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 android.Manifest;
30 import android.annotation.IntDef;
31 import android.annotation.NonNull;
32 import android.annotation.Nullable;
33 import android.app.ActivityManager;
34 import android.app.ActivityManagerInternal;
35 import android.app.AppGlobals;
36 import android.app.AppOpsManager;
37 import android.app.IUidObserver;
38 import android.app.NotificationManager;
39 import android.app.role.OnRoleHoldersChangedListener;
40 import android.app.role.RoleManager;
41 import android.bluetooth.BluetoothAdapter;
42 import android.bluetooth.BluetoothDevice;
43 import android.bluetooth.BluetoothHeadset;
44 import android.bluetooth.BluetoothProfile;
45 import android.content.BroadcastReceiver;
46 import android.content.ComponentName;
47 import android.content.ContentResolver;
48 import android.content.Context;
49 import android.content.Intent;
50 import android.content.IntentFilter;
51 import android.content.pm.ApplicationInfo;
52 import android.content.pm.PackageInfo;
53 import android.content.pm.PackageManager;
54 import android.content.pm.ResolveInfo;
55 import android.content.pm.UserInfo;
56 import android.content.res.Configuration;
57 import android.database.ContentObserver;
58 import android.hardware.hdmi.HdmiAudioSystemClient;
59 import android.hardware.hdmi.HdmiControlManager;
60 import android.hardware.hdmi.HdmiPlaybackClient;
61 import android.hardware.hdmi.HdmiTvClient;
62 import android.hardware.input.InputManager;
63 import android.hardware.usb.UsbManager;
64 import android.hidl.manager.V1_0.IServiceManager;
65 import android.media.AudioAttributes;
66 import android.media.AudioFocusInfo;
67 import android.media.AudioFocusRequest;
68 import android.media.AudioFormat;
69 import android.media.AudioManager;
70 import android.media.AudioManagerInternal;
71 import android.media.AudioPlaybackConfiguration;
72 import android.media.AudioRecordingConfiguration;
73 import android.media.AudioRoutesInfo;
74 import android.media.AudioSystem;
75 import android.media.IAudioFocusDispatcher;
76 import android.media.IAudioRoutesObserver;
77 import android.media.IAudioServerStateDispatcher;
78 import android.media.IAudioService;
79 import android.media.IPlaybackConfigDispatcher;
80 import android.media.IRecordingConfigDispatcher;
81 import android.media.IRingtonePlayer;
82 import android.media.IVolumeController;
83 import android.media.MediaExtractor;
84 import android.media.MediaFormat;
85 import android.media.PlayerBase;
86 import android.media.VolumePolicy;
87 import android.media.audiofx.AudioEffect;
88 import android.media.audiopolicy.AudioMix;
89 import android.media.audiopolicy.AudioPolicy;
90 import android.media.audiopolicy.AudioPolicyConfig;
91 import android.media.audiopolicy.AudioProductStrategy;
92 import android.media.audiopolicy.AudioVolumeGroup;
93 import android.media.audiopolicy.IAudioPolicyCallback;
94 import android.media.projection.IMediaProjection;
95 import android.media.projection.IMediaProjectionCallback;
96 import android.media.projection.IMediaProjectionManager;
97 import android.net.Uri;
98 import android.os.Binder;
99 import android.os.Build;
100 import android.os.Bundle;
101 import android.os.Handler;
102 import android.os.IBinder;
103 import android.os.Looper;
104 import android.os.Message;
105 import android.os.PowerManager;
106 import android.os.RemoteException;
107 import android.os.ServiceManager;
108 import android.os.SystemClock;
109 import android.os.SystemProperties;
110 import android.os.UserHandle;
111 import android.os.UserManager;
112 import android.os.UserManagerInternal;
113 import android.os.UserManagerInternal.UserRestrictionsListener;
114 import android.os.VibrationEffect;
115 import android.os.Vibrator;
116 import android.provider.Settings;
117 import android.provider.Settings.System;
118 import android.service.notification.ZenModeConfig;
119 import android.telecom.TelecomManager;
120 import android.text.TextUtils;
121 import android.util.AndroidRuntimeException;
122 import android.util.IntArray;
123 import android.util.Log;
124 import android.util.MathUtils;
125 import android.util.PrintWriterPrinter;
126 import android.util.Slog;
127 import android.util.SparseArray;
128 import android.util.SparseIntArray;
129 import android.view.KeyEvent;
130 import android.view.accessibility.AccessibilityManager;
131 import android.widget.Toast;
132 
133 import com.android.internal.annotations.GuardedBy;
134 import com.android.internal.annotations.VisibleForTesting;
135 import com.android.internal.util.DumpUtils;
136 import com.android.internal.util.Preconditions;
137 import com.android.server.EventLogTags;
138 import com.android.server.LocalServices;
139 import com.android.server.SystemService;
140 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
141 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
142 import com.android.server.pm.UserManagerService;
143 import com.android.server.wm.ActivityTaskManagerInternal;
144 
145 import java.io.FileDescriptor;
146 import java.io.IOException;
147 import java.io.PrintWriter;
148 import java.lang.annotation.Retention;
149 import java.lang.annotation.RetentionPolicy;
150 import java.util.ArrayList;
151 import java.util.Arrays;
152 import java.util.Collection;
153 import java.util.HashMap;
154 import java.util.HashSet;
155 import java.util.Iterator;
156 import java.util.List;
157 import java.util.NoSuchElementException;
158 import java.util.Objects;
159 import java.util.Set;
160 import java.util.concurrent.Executor;
161 import java.util.concurrent.atomic.AtomicBoolean;
162 
163 /**
164  * The implementation of the audio service for volume, audio focus, device management...
165  * <p>
166  * This implementation focuses on delivering a responsive UI. Most methods are
167  * asynchronous to external calls. For example, the task of setting a volume
168  * will update our internal state, but in a separate thread will set the system
169  * volume and later persist to the database. Similarly, setting the ringer mode
170  * will update the state and broadcast a change and in a separate thread later
171  * persist the ringer mode.
172  *
173  * @hide
174  */
175 public class AudioService extends IAudioService.Stub
176         implements AccessibilityManager.TouchExplorationStateChangeListener,
177             AccessibilityManager.AccessibilityServicesStateChangeListener {
178 
179     private static final String TAG = "AS.AudioService";
180 
181     /** Debug audio mode */
182     protected static final boolean DEBUG_MODE = false;
183 
184     /** Debug audio policy feature */
185     protected static final boolean DEBUG_AP = false;
186 
187     /** Debug volumes */
188     protected static final boolean DEBUG_VOL = false;
189 
190     /** debug calls to devices APIs */
191     protected static final boolean DEBUG_DEVICES = false;
192 
193     /** How long to delay before persisting a change in volume/ringer mode. */
194     private static final int PERSIST_DELAY = 500;
195 
196     /** How long to delay after a volume down event before unmuting a stream */
197     private static final int UNMUTE_STREAM_DELAY = 350;
198 
199     /**
200      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
201      * to give a chance to applications to pause.
202      */
203     @VisibleForTesting
204     public static final int BECOMING_NOISY_DELAY_MS = 1000;
205 
206     /**
207      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
208      */
209     private static final int FLAG_ADJUST_VOLUME = 1;
210 
211     private final Context mContext;
212     private final ContentResolver mContentResolver;
213     private final AppOpsManager mAppOps;
214 
215     // the platform type affects volume and silent mode behavior
216     private final int mPlatformType;
217 
218     // indicates whether the system maps all streams to a single stream.
219     private final boolean mIsSingleVolume;
220 
isPlatformVoice()221     private boolean isPlatformVoice() {
222         return mPlatformType == AudioSystem.PLATFORM_VOICE;
223     }
224 
isPlatformTelevision()225     /*package*/ boolean isPlatformTelevision() {
226         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
227     }
228 
isPlatformAutomotive()229     /*package*/ boolean isPlatformAutomotive() {
230         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
231     }
232 
233     /** The controller for the volume UI. */
234     private final VolumeController mVolumeController = new VolumeController();
235 
236     // sendMsg() flags
237     /** If the msg is already queued, replace it with this one. */
238     private static final int SENDMSG_REPLACE = 0;
239     /** If the msg is already queued, ignore this one and leave the old. */
240     private static final int SENDMSG_NOOP = 1;
241     /** If the msg is already queued, queue this one and leave the old. */
242     private static final int SENDMSG_QUEUE = 2;
243 
244     // AudioHandler messages
245     private static final int MSG_SET_DEVICE_VOLUME = 0;
246     private static final int MSG_PERSIST_VOLUME = 1;
247     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
248     private static final int MSG_PERSIST_RINGER_MODE = 3;
249     private static final int MSG_AUDIO_SERVER_DIED = 4;
250     private static final int MSG_PLAY_SOUND_EFFECT = 5;
251     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
252     private static final int MSG_SET_FORCE_USE = 8;
253     private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
254     private static final int MSG_SET_ALL_VOLUMES = 10;
255     private static final int MSG_CHECK_MUSIC_ACTIVE = 11;
256     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 12;
257     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 13;
258     private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 14;
259     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
260     private static final int MSG_SYSTEM_READY = 16;
261     private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 17;
262     private static final int MSG_UNMUTE_STREAM = 18;
263     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
264     private static final int MSG_INDICATE_SYSTEM_READY = 20;
265     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
266     private static final int MSG_NOTIFY_VOL_EVENT = 22;
267     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
268     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
269     private static final int MSG_UPDATE_RINGER_MODE = 25;
270     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
271     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
272     private static final int MSG_HDMI_VOLUME_CHECK = 28;
273     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
274     // start of messages handled under wakelock
275     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
276     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
277     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
278     // end of messages handled under wakelock
279 
280     // retry delay in case of failure to indicate system ready to AudioFlinger
281     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
282 
283     /** @see AudioSystemThread */
284     private AudioSystemThread mAudioSystemThread;
285     /** @see AudioHandler */
286     private AudioHandler mAudioHandler;
287     /** @see VolumeStreamState */
288     private VolumeStreamState[] mStreamStates;
289 
getVssVolumeForDevice(int stream, int device)290     /*package*/ int getVssVolumeForDevice(int stream, int device) {
291         return mStreamStates[stream].getIndex(device);
292     }
293 
294     private SettingsObserver mSettingsObserver;
295 
296     private int mMode = AudioSystem.MODE_NORMAL;
297     // protects mRingerMode
298     private final Object mSettingsLock = new Object();
299 
300    /** Maximum volume index values for audio streams */
301     protected static int[] MAX_STREAM_VOLUME = new int[] {
302         5,  // STREAM_VOICE_CALL
303         7,  // STREAM_SYSTEM
304         7,  // STREAM_RING
305         15, // STREAM_MUSIC
306         7,  // STREAM_ALARM
307         7,  // STREAM_NOTIFICATION
308         15, // STREAM_BLUETOOTH_SCO
309         7,  // STREAM_SYSTEM_ENFORCED
310         15, // STREAM_DTMF
311         15, // STREAM_TTS
312         15  // STREAM_ACCESSIBILITY
313     };
314 
315     /** Minimum volume index values for audio streams */
316     protected static int[] MIN_STREAM_VOLUME = new int[] {
317         1,  // STREAM_VOICE_CALL
318         0,  // STREAM_SYSTEM
319         0,  // STREAM_RING
320         0,  // STREAM_MUSIC
321         1,  // STREAM_ALARM
322         0,  // STREAM_NOTIFICATION
323         0,  // STREAM_BLUETOOTH_SCO
324         0,  // STREAM_SYSTEM_ENFORCED
325         0,  // STREAM_DTMF
326         0,  // STREAM_TTS
327         1   // STREAM_ACCESSIBILITY
328     };
329 
330     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
331      * of another stream: This avoids multiplying the volume settings for hidden
332      * stream types that follow other stream behavior for volume settings
333      * NOTE: do not create loops in aliases!
334      * Some streams alias to different streams according to device category (phone or tablet) or
335      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
336      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
337      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
338      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
339     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
340         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
341         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
342         AudioSystem.STREAM_RING,            // STREAM_RING
343         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
344         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
345         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
346         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
347         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
348         AudioSystem.STREAM_RING,            // STREAM_DTMF
349         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
350         AudioSystem.STREAM_MUSIC            // STREAM_ACCESSIBILITY
351     };
352     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
353         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
354         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
355         AudioSystem.STREAM_MUSIC,       // STREAM_RING
356         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
357         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
358         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
359         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
360         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
361         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
362         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
363         AudioSystem.STREAM_MUSIC        // STREAM_ACCESSIBILITY
364     };
365     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
366         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
367         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
368         AudioSystem.STREAM_RING,            // STREAM_RING
369         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
370         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
371         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
372         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
373         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
374         AudioSystem.STREAM_RING,            // STREAM_DTMF
375         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
376         AudioSystem.STREAM_MUSIC            // STREAM_ACCESSIBILITY
377     };
378     protected static int[] mStreamVolumeAlias;
379 
380     /**
381      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
382      * after mapping through mStreamVolumeAlias.
383      */
384     private static final int[] STREAM_VOLUME_OPS = new int[] {
385         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
386         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
387         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
388         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
389         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
390         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
391         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
392         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
393         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
394         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
395         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
396     };
397 
398     private final boolean mUseFixedVolume;
399 
400     /**
401     * Default stream type used for volume control in the absence of playback
402     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
403     *    stream type is controlled.
404     */
405     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
406 
407     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
408         public void onError(int error) {
409             switch (error) {
410                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
411                     mRecordMonitor.onAudioServerDied();
412 
413                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
414                             SENDMSG_NOOP, 0, 0, null, 0);
415                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
416                             SENDMSG_QUEUE, 0, 0, null, 0);
417                     break;
418                 default:
419                     break;
420             }
421         }
422     };
423 
424     /**
425      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
426      * {@link AudioManager#RINGER_MODE_SILENT}, or
427      * {@link AudioManager#RINGER_MODE_VIBRATE}.
428      */
429     @GuardedBy("mSettingsLock")
430     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
431     @GuardedBy("mSettingsLock")
432     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
433 
434     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
435     private int mRingerModeAffectedStreams = 0;
436 
437     private int mZenModeAffectedStreams = 0;
438 
439     // Streams currently muted by ringer mode and dnd
440     private int mRingerAndZenModeMutedStreams;
441 
442     /** Streams that can be muted. Do not resolve to aliases when checking.
443      * @see System#MUTE_STREAMS_AFFECTED */
444     private int mMuteAffectedStreams;
445 
446     @NonNull
447     private SoundEffectsHelper mSfxHelper;
448 
449     /**
450      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
451      * mVibrateSetting is just maintained during deprecation period but vibration policy is
452      * now only controlled by mHasVibrator and mRingerMode
453      */
454     private int mVibrateSetting;
455 
456     // Is there a vibrator
457     private final boolean mHasVibrator;
458     // Used to play vibrations
459     private Vibrator mVibrator;
460     private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
461             .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
462             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
463             .build();
464 
465     // Broadcast receiver for device connections intent broadcasts
466     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
467 
468     private IMediaProjectionManager mProjectionService; // to validate projection token
469 
470     /** Interface for UserManagerService. */
471     private final UserManagerInternal mUserManagerInternal;
472     private final ActivityManagerInternal mActivityManagerInternal;
473 
474     private final UserRestrictionsListener mUserRestrictionsListener =
475             new AudioServiceUserRestrictionsListener();
476 
477     // List of binder death handlers for setMode() client processes.
478     // The last process to have called setMode() is at the top of the list.
479     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
480     //TODO candidate to be moved to separate class that handles synchronization
481     @GuardedBy("mDeviceBroker.mSetModeLock")
482     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
483             new ArrayList<SetModeDeathHandler>();
484 
485     // true if boot sequence has been completed
486     private boolean mSystemReady;
487     // true if Intent.ACTION_USER_SWITCHED has ever been received
488     private boolean mUserSwitchedReceived;
489     // previous volume adjustment direction received by checkForRingerModeChange()
490     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
491     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
492     // is controlled by Vol keys.
493     private int mVolumeControlStream = -1;
494     // interpretation of whether the volume stream has been selected by the user by clicking on a
495     // volume slider to change which volume is controlled by the volume keys. Is false
496     // when mVolumeControlStream is -1.
497     private boolean mUserSelectedVolumeControlStream = false;
498     private final Object mForceControlStreamLock = new Object();
499     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
500     // server process so in theory it is not necessary to monitor the client death.
501     // However it is good to be ready for future evolutions.
502     private ForceControlStreamClient mForceControlStreamClient = null;
503     // Used to play ringtones outside system_server
504     private volatile IRingtonePlayer mRingtonePlayer;
505 
506     // Devices for which the volume is fixed (volume is either max or muted)
507     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
508             AudioSystem.DEVICE_OUT_HDMI,
509             AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
510             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
511             AudioSystem.DEVICE_OUT_HDMI_ARC,
512             AudioSystem.DEVICE_OUT_SPDIF,
513             AudioSystem.DEVICE_OUT_AUX_LINE));
514     // Devices for which the volume is always max, no volume panel
515     Set<Integer> mFullVolumeDevices = new HashSet<>();
516     // Devices for the which use the "absolute volume" concept (framework sends audio signal
517     // full scale, and volume control separately) and can be used for multiple use cases reflected
518     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
519     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
520             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
521 
522     private final boolean mMonitorRotation;
523 
524     private boolean mDockAudioMediaEnabled = true;
525 
526     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
527 
528     // Used when safe volume warning message display is requested by setStreamVolume(). In this
529     // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand
530     // and used later when/if disableSafeMediaVolume() is called.
531     private StreamVolumeCommand mPendingVolumeCommand;
532 
533     private PowerManager.WakeLock mAudioEventWakeLock;
534 
535     private final MediaFocusControl mMediaFocusControl;
536 
537     // Pre-scale for Bluetooth Absolute Volume
538     private float[] mPrescaleAbsoluteVolume = new float[] {
539         0.5f,    // Pre-scale for index 1
540         0.7f,    // Pre-scale for index 2
541         0.85f,   // Pre-scale for index 3
542     };
543 
544     private NotificationManager mNm;
545     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
546     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
547     private long mLoweredFromNormalToVibrateTime;
548 
549     // Array of Uids of valid accessibility services to check if caller is one of them
550     private int[] mAccessibilityServiceUids;
551     private final Object mAccessibilityServiceUidsLock = new Object();
552 
553     private int mEncodedSurroundMode;
554     private String mEnabledSurroundFormats;
555     private boolean mSurroundModeChanged;
556 
557     private boolean mMicMuteFromSwitch;
558     private boolean mMicMuteFromApi;
559     private boolean mMicMuteFromRestrictions;
560 
561     @GuardedBy("mSettingsLock")
562     private int mAssistantUid;
563 
564     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)565     public static String makeAlsaAddressString(int card, int device) {
566         return "card=" + card + ";device=" + device + ";";
567     }
568 
569     public static final class Lifecycle extends SystemService {
570         private AudioService mService;
571 
Lifecycle(Context context)572         public Lifecycle(Context context) {
573             super(context);
574             mService = new AudioService(context);
575         }
576 
577         @Override
onStart()578         public void onStart() {
579             publishBinderService(Context.AUDIO_SERVICE, mService);
580         }
581 
582         @Override
onBootPhase(int phase)583         public void onBootPhase(int phase) {
584             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
585                 mService.systemReady();
586             }
587         }
588     }
589 
590     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
591         @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
592         }
593 
594         @Override public void onUidGone(int uid, boolean disabled) {
595             // Once the uid is no longer running, no need to keep trying to disable its audio.
596             disableAudioForUid(false, uid);
597         }
598 
599         @Override public void onUidActive(int uid) throws RemoteException {
600         }
601 
602         @Override public void onUidIdle(int uid, boolean disabled) {
603         }
604 
605         @Override public void onUidCachedChanged(int uid, boolean cached) {
606             disableAudioForUid(cached, uid);
607         }
608 
609         private void disableAudioForUid(boolean disable, int uid) {
610             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
611                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
612                     null /* obj */,  0 /* delay */);
613         }
614     };
615 
616     ///////////////////////////////////////////////////////////////////////////
617     // Construction
618     ///////////////////////////////////////////////////////////////////////////
619 
620     /** @hide */
AudioService(Context context)621     public AudioService(Context context) {
622         mContext = context;
623         mContentResolver = context.getContentResolver();
624         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
625 
626         mPlatformType = AudioSystem.getPlatformType(context);
627 
628         mIsSingleVolume = AudioSystem.isSingleVolume(context);
629 
630         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
631         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
632 
633         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
634         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
635 
636         mSfxHelper = new SoundEffectsHelper(mContext);
637 
638         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
639         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
640 
641         // Initialize volume
642         // Priority 1 - Android Property
643         // Priority 2 - Audio Policy Service
644         // Priority 3 - Default Value
645         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
646             int numStreamTypes = AudioSystem.getNumStreamTypes();
647 
648             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
649                 AudioAttributes attr =
650                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
651                                 streamType);
652                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
653                 if (maxVolume != -1) {
654                     MAX_STREAM_VOLUME[streamType] = maxVolume;
655                 }
656                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
657                 if (minVolume != -1) {
658                     MIN_STREAM_VOLUME[streamType] = minVolume;
659                 }
660             }
661         }
662 
663         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
664         if (maxCallVolume != -1) {
665             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
666         }
667 
668         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
669         if (defaultCallVolume != -1 &&
670                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
671                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
672             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
673         } else {
674             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
675                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
676         }
677 
678         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
679         if (maxMusicVolume != -1) {
680             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
681         }
682 
683         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
684         if (defaultMusicVolume != -1 &&
685                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
686                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
687             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
688         } else {
689             if (isPlatformTelevision()) {
690                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
691                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
692             } else {
693                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
694                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
695             }
696         }
697 
698         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
699         if (maxAlarmVolume != -1) {
700             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
701         }
702 
703         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
704         if (defaultAlarmVolume != -1 &&
705                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
706             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
707         } else {
708             // Default is 6 out of 7 (default maximum), so scale accordingly.
709             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
710                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
711         }
712 
713         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
714         if (maxSystemVolume != -1) {
715             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
716         }
717 
718         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
719         if (defaultSystemVolume != -1 &&
720                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
721             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
722         } else {
723             // Default is to use maximum.
724             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
725                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
726         }
727 
728         createAudioSystemThread();
729 
730         AudioSystem.setErrorCallback(mAudioSystemCallback);
731 
732         updateAudioHalPids();
733 
734         boolean cameraSoundForced = readCameraSoundForced();
735         mCameraSoundForced = new Boolean(cameraSoundForced);
736         sendMsg(mAudioHandler,
737                 MSG_SET_FORCE_USE,
738                 SENDMSG_QUEUE,
739                 AudioSystem.FOR_SYSTEM,
740                 cameraSoundForced ?
741                         AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
742                 new String("AudioService ctor"),
743                 0);
744 
745         mSafeMediaVolumeState = Settings.Global.getInt(mContentResolver,
746                                             Settings.Global.AUDIO_SAFE_VOLUME_STATE,
747                                             SAFE_MEDIA_VOLUME_NOT_CONFIGURED);
748         // The default safe volume index read here will be replaced by the actual value when
749         // the mcc is read by onConfigureSafeVolume()
750         mSafeMediaVolumeIndex = mContext.getResources().getInteger(
751                 com.android.internal.R.integer.config_safe_media_volume_index) * 10;
752 
753         mUseFixedVolume = mContext.getResources().getBoolean(
754                 com.android.internal.R.bool.config_useFixedVolume);
755 
756         mDeviceBroker = new AudioDeviceBroker(mContext, this);
757 
758         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
759         // array initialized by updateStreamVolumeAlias()
760         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
761         readPersistedSettings();
762         readUserRestrictions();
763         mSettingsObserver = new SettingsObserver();
764         createStreamStates();
765 
766         // must be called after createStreamStates() as it uses MUSIC volume as default if no
767         // persistent data
768         initVolumeGroupStates();
769 
770         // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
771         // relies on audio policy having correct ranges for volume indexes.
772         mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
773 
774         mPlaybackMonitor =
775                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
776 
777         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
778 
779         mRecordMonitor = new RecordingActivityMonitor(mContext);
780 
781         readAndSetLowRamDevice();
782 
783         // Call setRingerModeInt() to apply correct mute
784         // state on streams affected by ringer mode.
785         mRingerAndZenModeMutedStreams = 0;
786         setRingerModeInt(getRingerModeInternal(), false);
787 
788         // Register for device connection intent broadcasts.
789         IntentFilter intentFilter =
790                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
791         intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
792         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
793         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
794         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
795         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
796         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
797         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
798         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
799         intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
800         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
801 
802         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
803         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
804         if (mMonitorRotation) {
805             RotationHelper.init(mContext, mAudioHandler);
806         }
807 
808         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
809         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
810 
811         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
812 
813         LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
814 
815         mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
816 
817         mRecordMonitor.initMonitor();
818 
819         final float[] preScale = new float[3];
820         preScale[0] = mContext.getResources().getFraction(
821                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
822                 1, 1);
823         preScale[1] = mContext.getResources().getFraction(
824                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
825                 1, 1);
826         preScale[2] = mContext.getResources().getFraction(
827                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
828                 1, 1);
829         for (int i = 0; i < preScale.length; i++) {
830             if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
831                 mPrescaleAbsoluteVolume[i] = preScale[i];
832             }
833         }
834     }
835 
systemReady()836     public void systemReady() {
837         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
838                 0, 0, null, 0);
839         if (false) {
840             // This is turned off for now, because it is racy and thus causes apps to break.
841             // Currently banning a uid means that if an app tries to start playing an audio
842             // stream, that will be preventing, and unbanning it will not allow that stream
843             // to resume.  However these changes in uid state are racy with what the app is doing,
844             // so that after taking a process out of the cached state we can't guarantee that
845             // we will unban the uid before the app actually tries to start playing audio.
846             // (To do that, the activity manager would need to wait until it knows for sure
847             // that the ban has been removed, before telling the app to do whatever it is
848             // supposed to do that caused it to go out of the cached state.)
849             try {
850                 ActivityManager.getService().registerUidObserver(mUidObserver,
851                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
852                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
853             } catch (RemoteException e) {
854                 // ignored; both services live in system_server
855             }
856         }
857     }
858 
onSystemReady()859     public void onSystemReady() {
860         mSystemReady = true;
861         scheduleLoadSoundEffects();
862 
863         mDeviceBroker.onSystemReady();
864 
865         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
866             synchronized (mHdmiClientLock) {
867                 mHdmiCecSink = false;
868                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
869                 if (mHdmiManager != null) {
870                     mHdmiManager.addHdmiControlStatusChangeListener(
871                             mHdmiControlStatusChangeListenerCallback);
872                 }
873                 mHdmiTvClient = mHdmiManager.getTvClient();
874                 if (mHdmiTvClient != null) {
875                     mFixedVolumeDevices.removeAll(
876                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
877                 }
878                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
879                 if (mHdmiPlaybackClient != null) {
880                     // not a television: HDMI output will be always at max
881                     mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_HDMI);
882                     mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_HDMI);
883                 }
884                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
885             }
886         }
887 
888         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
889 
890         sendMsg(mAudioHandler,
891                 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,
892                 SENDMSG_REPLACE,
893                 0,
894                 0,
895                 TAG,
896                 SystemProperties.getBoolean("audio.safemedia.bypass", false) ?
897                         0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
898 
899         initA11yMonitoring();
900 
901         mRoleObserver = new RoleObserver();
902         mRoleObserver.register();
903 
904         onIndicateSystemReady();
905 
906         setMicMuteFromSwitchInput();
907     }
908 
909     RoleObserver mRoleObserver;
910 
911     class RoleObserver implements OnRoleHoldersChangedListener {
912         private RoleManager mRm;
913         private final Executor mExecutor;
914 
RoleObserver()915         RoleObserver() {
916             mExecutor = mContext.getMainExecutor();
917         }
918 
register()919         public void register() {
920             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
921             if (mRm != null) {
922                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
923                 updateAssistantUId(true);
924             }
925         }
926 
927         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)928         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
929             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
930                 updateAssistantUId(false);
931             }
932         }
933 
getAssistantRoleHolder()934         public String getAssistantRoleHolder() {
935             String assitantPackage = "";
936             if (mRm != null) {
937                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
938                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
939             }
940             return assitantPackage;
941         }
942     }
943 
onIndicateSystemReady()944     void onIndicateSystemReady() {
945         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
946             return;
947         }
948         sendMsg(mAudioHandler,
949                 MSG_INDICATE_SYSTEM_READY,
950                 SENDMSG_REPLACE,
951                 0,
952                 0,
953                 null,
954                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
955     }
956 
onAudioServerDied()957     public void onAudioServerDied() {
958         if (!mSystemReady ||
959                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
960             Log.e(TAG, "Audioserver died.");
961             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
962                     null, 500);
963             return;
964         }
965         Log.e(TAG, "Audioserver started.");
966 
967         updateAudioHalPids();
968 
969         // indicate to audio HAL that we start the reconfiguration phase after a media
970         // server crash
971         // Note that we only execute this when the media server
972         // process restarts after a crash, not the first time it is started.
973         AudioSystem.setParameters("restarting=true");
974 
975         readAndSetLowRamDevice();
976 
977         // Restore device connection states, BT state
978         mDeviceBroker.onAudioServerDied();
979 
980         // Restore call state
981         if (AudioSystem.setPhoneState(mMode) ==  AudioSystem.AUDIO_STATUS_OK) {
982             mModeLogger.log(new AudioEventLogger.StringEvent(
983                 "onAudioServerDied causes setPhoneState(" + AudioSystem.modeToString(mMode) + ")"));
984         }
985 
986         final int forSys;
987         synchronized (mSettingsLock) {
988             forSys = mCameraSoundForced ?
989                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
990         }
991 
992         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
993 
994         // Restore stream volumes
995         int numStreamTypes = AudioSystem.getNumStreamTypes();
996         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
997             VolumeStreamState streamState = mStreamStates[streamType];
998             AudioSystem.initStreamVolume(
999                 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
1000 
1001             streamState.applyAllVolumes();
1002         }
1003 
1004         // Restore audio volume groups
1005         restoreVolumeGroups();
1006 
1007         // Restore mono mode
1008         updateMasterMono(mContentResolver);
1009 
1010         // Restore audio balance
1011         updateMasterBalance(mContentResolver);
1012 
1013         // Restore ringer mode
1014         setRingerModeInt(getRingerModeInternal(), false);
1015 
1016         // Reset device rotation (if monitored for this device)
1017         if (mMonitorRotation) {
1018             RotationHelper.updateOrientation();
1019         }
1020 
1021         synchronized (mSettingsLock) {
1022             final int forDock = mDockAudioMediaEnabled ?
1023                     AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE;
1024             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
1025             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
1026             sendEnabledSurroundFormats(mContentResolver, true);
1027             updateAssistantUId(true);
1028             updateRttEanbled(mContentResolver);
1029         }
1030         synchronized (mAccessibilityServiceUidsLock) {
1031             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
1032         }
1033         synchronized (mHdmiClientLock) {
1034             if (mHdmiManager != null && mHdmiTvClient != null) {
1035                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
1036             }
1037         }
1038 
1039         synchronized (mAudioPolicies) {
1040             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
1041                 final int status = policy.connectMixes();
1042                 if (status != AudioSystem.SUCCESS) {
1043                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
1044                     Log.e(TAG, "onAudioServerDied: error "
1045                             + AudioSystem.audioSystemErrorToString(status)
1046                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
1047                     policy.release();
1048                 }
1049             }
1050         }
1051 
1052         // Restore capture policies
1053         synchronized (mPlaybackMonitor) {
1054             HashMap<Integer, Integer> allowedCapturePolicies =
1055                     mPlaybackMonitor.getAllAllowedCapturePolicies();
1056             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
1057                 int result = AudioSystem.setAllowedCapturePolicy(
1058                         entry.getKey(),
1059                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
1060                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1061                     Log.e(TAG, "Failed to restore capture policy, uid: "
1062                             + entry.getKey() + ", capture policy: " + entry.getValue()
1063                             + ", result: " + result);
1064                     // When restoring capture policy failed, set the capture policy as
1065                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
1066                     // capture policy in PlaybackActivityMonitor.
1067                     mPlaybackMonitor.setAllowedCapturePolicy(
1068                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
1069                 }
1070             }
1071         }
1072 
1073         onIndicateSystemReady();
1074         // indicate the end of reconfiguration phase to audio HAL
1075         AudioSystem.setParameters("restarting=false");
1076 
1077         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
1078                 SENDMSG_QUEUE, 1, 0, null, 0);
1079 
1080         setMicMuteFromSwitchInput();
1081     }
1082 
onDispatchAudioServerStateChange(boolean state)1083     private void onDispatchAudioServerStateChange(boolean state) {
1084         synchronized (mAudioServerStateListeners) {
1085             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
1086                 try {
1087                     asdp.callback().dispatchAudioServerStateChange(state);
1088                 } catch (RemoteException e) {
1089                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
1090                 }
1091             }
1092         }
1093     }
1094 
createAudioSystemThread()1095     private void createAudioSystemThread() {
1096         mAudioSystemThread = new AudioSystemThread();
1097         mAudioSystemThread.start();
1098         waitForAudioHandlerCreation();
1099     }
1100 
1101     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()1102     private void waitForAudioHandlerCreation() {
1103         synchronized(this) {
1104             while (mAudioHandler == null) {
1105                 try {
1106                     // Wait for mAudioHandler to be set by the other thread
1107                     wait();
1108                 } catch (InterruptedException e) {
1109                     Log.e(TAG, "Interrupted while waiting on volume handler.");
1110                 }
1111             }
1112         }
1113     }
1114 
1115     /**
1116      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
1117      * platform configuration file.
1118      */
1119     @NonNull
getAudioProductStrategies()1120     public List<AudioProductStrategy> getAudioProductStrategies() {
1121         return AudioProductStrategy.getAudioProductStrategies();
1122     }
1123 
1124     /**
1125      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
1126      * platform configuration file.
1127      */
1128     @NonNull
getAudioVolumeGroups()1129     public List<AudioVolumeGroup> getAudioVolumeGroups() {
1130         return AudioVolumeGroup.getAudioVolumeGroups();
1131     }
1132 
checkAllAliasStreamVolumes()1133     private void checkAllAliasStreamVolumes() {
1134         synchronized (mSettingsLock) {
1135             synchronized (VolumeStreamState.class) {
1136                 int numStreamTypes = AudioSystem.getNumStreamTypes();
1137                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1138                     mStreamStates[streamType]
1139                             .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
1140                     // apply stream volume
1141                     if (!mStreamStates[streamType].mIsMuted) {
1142                         mStreamStates[streamType].applyAllVolumes();
1143                     }
1144                 }
1145             }
1146         }
1147     }
1148 
1149 
1150     /**
1151      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
1152      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1153     /*package*/ void postCheckVolumeCecOnHdmiConnection(
1154             @AudioService.ConnectionState  int state, String caller) {
1155         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
1156                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
1157     }
1158 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1159     private void onCheckVolumeCecOnHdmiConnection(
1160             @AudioService.ConnectionState int state, String caller) {
1161         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
1162             // DEVICE_OUT_HDMI is now connected
1163             if (mSafeMediaVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)) {
1164                 sendMsg(mAudioHandler,
1165                         MSG_CHECK_MUSIC_ACTIVE,
1166                         SENDMSG_REPLACE,
1167                         0,
1168                         0,
1169                         caller,
1170                         MUSIC_ACTIVE_POLL_PERIOD_MS);
1171             }
1172 
1173             if (isPlatformTelevision()) {
1174                 checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI, caller);
1175                 synchronized (mHdmiClientLock) {
1176                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
1177                         updateHdmiCecSinkLocked(mHdmiCecSink | false);
1178                     }
1179                 }
1180             }
1181             sendEnabledSurroundFormats(mContentResolver, true);
1182         } else {
1183             // DEVICE_OUT_HDMI disconnected
1184             if (isPlatformTelevision()) {
1185                 synchronized (mHdmiClientLock) {
1186                     if (mHdmiManager != null) {
1187                         updateHdmiCecSinkLocked(mHdmiCecSink | false);
1188                     }
1189                 }
1190             }
1191         }
1192     }
1193 
checkAddAllFixedVolumeDevices(int device, String caller)1194     private void checkAddAllFixedVolumeDevices(int device, String caller) {
1195         final int numStreamTypes = AudioSystem.getNumStreamTypes();
1196         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1197             if (!mStreamStates[streamType].hasIndexForDevice(device)) {
1198                 // set the default value, if device is affected by a full/fix/abs volume rule, it
1199                 // will taken into account in checkFixedVolumeDevices()
1200                 mStreamStates[streamType].setIndex(
1201                         mStreamStates[mStreamVolumeAlias[streamType]]
1202                                 .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
1203                         device, caller);
1204             }
1205             mStreamStates[streamType].checkFixedVolumeDevices();
1206         }
1207     }
1208 
checkAllFixedVolumeDevices()1209     private void checkAllFixedVolumeDevices()
1210     {
1211         int numStreamTypes = AudioSystem.getNumStreamTypes();
1212         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1213             mStreamStates[streamType].checkFixedVolumeDevices();
1214         }
1215     }
1216 
checkAllFixedVolumeDevices(int streamType)1217     private void checkAllFixedVolumeDevices(int streamType) {
1218         mStreamStates[streamType].checkFixedVolumeDevices();
1219     }
1220 
checkMuteAffectedStreams()1221     private void checkMuteAffectedStreams() {
1222         // any stream with a min level > 0 is not muteable by definition
1223         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
1224         // that has the the MODIFY_PHONE_STATE permission.
1225         for (int i = 0; i < mStreamStates.length; i++) {
1226             final VolumeStreamState vss = mStreamStates[i];
1227             if (vss.mIndexMin > 0 &&
1228                 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL &&
1229                 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
1230                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
1231             }
1232         }
1233     }
1234 
createStreamStates()1235     private void createStreamStates() {
1236         int numStreamTypes = AudioSystem.getNumStreamTypes();
1237         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
1238 
1239         for (int i = 0; i < numStreamTypes; i++) {
1240             streams[i] =
1241                     new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);
1242         }
1243 
1244         checkAllFixedVolumeDevices();
1245         checkAllAliasStreamVolumes();
1246         checkMuteAffectedStreams();
1247         updateDefaultVolumes();
1248     }
1249 
1250     // Update default indexes from aliased streams. Must be called after mStreamStates is created
updateDefaultVolumes()1251     private void updateDefaultVolumes() {
1252         for (int stream = 0; stream < mStreamStates.length; stream++) {
1253             if (stream != mStreamVolumeAlias[stream]) {
1254                 AudioSystem.DEFAULT_STREAM_VOLUME[stream] = (rescaleIndex(
1255                         AudioSystem.DEFAULT_STREAM_VOLUME[mStreamVolumeAlias[stream]] * 10,
1256                         mStreamVolumeAlias[stream],
1257                         stream) + 5) / 10;
1258             }
1259         }
1260     }
1261 
dumpStreamStates(PrintWriter pw)1262     private void dumpStreamStates(PrintWriter pw) {
1263         pw.println("\nStream volumes (device: index)");
1264         int numStreamTypes = AudioSystem.getNumStreamTypes();
1265         for (int i = 0; i < numStreamTypes; i++) {
1266             pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":");
1267             mStreamStates[i].dump(pw);
1268             pw.println("");
1269         }
1270         pw.print("\n- mute affected streams = 0x");
1271         pw.println(Integer.toHexString(mMuteAffectedStreams));
1272     }
1273 
updateStreamVolumeAlias(boolean updateVolumes, String caller)1274     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
1275         int dtmfStreamAlias;
1276         final int a11yStreamAlias = sIndependentA11yVolume ?
1277                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
1278 
1279         if (mIsSingleVolume) {
1280             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
1281             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
1282         } else {
1283             switch (mPlatformType) {
1284                 case AudioSystem.PLATFORM_VOICE:
1285                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE;
1286                     dtmfStreamAlias = AudioSystem.STREAM_RING;
1287                     break;
1288                 default:
1289                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT;
1290                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
1291             }
1292         }
1293 
1294         if (mIsSingleVolume) {
1295             mRingerModeAffectedStreams = 0;
1296         } else {
1297             if (isInCommunication()) {
1298                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
1299                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
1300             } else {
1301                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
1302             }
1303         }
1304 
1305         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
1306         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
1307 
1308         if (updateVolumes && mStreamStates != null) {
1309             updateDefaultVolumes();
1310 
1311             synchronized (mSettingsLock) {
1312                 synchronized (VolumeStreamState.class) {
1313                     mStreamStates[AudioSystem.STREAM_DTMF]
1314                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
1315                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName =
1316                             System.VOLUME_SETTINGS_INT[a11yStreamAlias];
1317                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
1318                             mStreamStates[a11yStreamAlias], caller);
1319                 }
1320             }
1321             if (sIndependentA11yVolume) {
1322                 // restore the a11y values from the settings
1323                 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
1324             }
1325 
1326             // apply stream mute states according to new value of mRingerModeAffectedStreams
1327             setRingerModeInt(getRingerModeInternal(), false);
1328             sendMsg(mAudioHandler,
1329                     MSG_SET_ALL_VOLUMES,
1330                     SENDMSG_QUEUE,
1331                     0,
1332                     0,
1333                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
1334             sendMsg(mAudioHandler,
1335                     MSG_SET_ALL_VOLUMES,
1336                     SENDMSG_QUEUE,
1337                     0,
1338                     0,
1339                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
1340         }
1341     }
1342 
readDockAudioSettings(ContentResolver cr)1343     private void readDockAudioSettings(ContentResolver cr)
1344     {
1345         mDockAudioMediaEnabled = Settings.Global.getInt(
1346                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
1347 
1348         sendMsg(mAudioHandler,
1349                 MSG_SET_FORCE_USE,
1350                 SENDMSG_QUEUE,
1351                 AudioSystem.FOR_DOCK,
1352                 mDockAudioMediaEnabled ?
1353                         AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE,
1354                 new String("readDockAudioSettings"),
1355                 0);
1356     }
1357 
1358 
updateMasterMono(ContentResolver cr)1359     private void updateMasterMono(ContentResolver cr)
1360     {
1361         final boolean masterMono = System.getIntForUser(
1362                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
1363         if (DEBUG_VOL) {
1364             Log.d(TAG, String.format("Master mono %b", masterMono));
1365         }
1366         AudioSystem.setMasterMono(masterMono);
1367     }
1368 
updateMasterBalance(ContentResolver cr)1369     private void updateMasterBalance(ContentResolver cr) {
1370         final float masterBalance = System.getFloatForUser(
1371                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
1372         if (DEBUG_VOL) {
1373             Log.d(TAG, String.format("Master balance %f", masterBalance));
1374         }
1375         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
1376             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
1377         }
1378     }
1379 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)1380     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
1381     {
1382         final int encodedSurroundMode = Settings.Global.getInt(
1383                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
1384                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
1385         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
1386     }
1387 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)1388     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
1389     {
1390         // initialize to guaranteed bad value
1391         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
1392         switch (encodedSurroundMode) {
1393             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
1394                 forceSetting = AudioSystem.FORCE_NONE;
1395                 break;
1396             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
1397                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
1398                 break;
1399             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
1400                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
1401                 break;
1402             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
1403                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
1404                 break;
1405             default:
1406                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
1407                         + encodedSurroundMode);
1408                 break;
1409         }
1410         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
1411             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
1412                     eventSource);
1413         }
1414     }
1415 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)1416     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
1417         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
1418             // Manually enable surround formats only when the setting is in manual mode.
1419             return;
1420         }
1421         String enabledSurroundFormats = Settings.Global.getString(
1422                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
1423         if (enabledSurroundFormats == null) {
1424             // Never allow enabledSurroundFormats as a null, which could happen when
1425             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
1426             enabledSurroundFormats = "";
1427         }
1428         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
1429             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
1430             // is true or enabled surround formats changed.
1431             return;
1432         }
1433 
1434         mEnabledSurroundFormats = enabledSurroundFormats;
1435         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
1436         ArrayList<Integer> formats = new ArrayList<>();
1437         for (String format : surroundFormats) {
1438             try {
1439                 int audioFormat = Integer.valueOf(format);
1440                 boolean isSurroundFormat = false;
1441                 for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
1442                     if (sf == audioFormat) {
1443                         isSurroundFormat = true;
1444                         break;
1445                     }
1446                 }
1447                 if (isSurroundFormat && !formats.contains(audioFormat)) {
1448                     formats.add(audioFormat);
1449                 }
1450             } catch (Exception e) {
1451                 Log.e(TAG, "Invalid enabled surround format:" + format);
1452             }
1453         }
1454         // Set filtered surround formats to settings DB in case
1455         // there are invalid surround formats in original settings.
1456         Settings.Global.putString(mContext.getContentResolver(),
1457                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
1458                 TextUtils.join(",", formats));
1459         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
1460     }
1461 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)1462     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
1463         // Set surround format enabled accordingly.
1464         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
1465             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
1466             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
1467             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
1468         }
1469     }
1470 
1471     @GuardedBy("mSettingsLock")
updateAssistantUId(boolean forceUpdate)1472     private void updateAssistantUId(boolean forceUpdate) {
1473         int assistantUid = 0;
1474 
1475         // Consider assistants in the following order of priority:
1476         // 1) apk in assistant role
1477         // 2) voice interaction service
1478         // 3) assistant service
1479 
1480         String packageName = "";
1481         if (mRoleObserver != null) {
1482             packageName = mRoleObserver.getAssistantRoleHolder();
1483         }
1484         if (TextUtils.isEmpty(packageName)) {
1485             String assistantName = Settings.Secure.getStringForUser(
1486                             mContentResolver,
1487                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
1488             if (TextUtils.isEmpty(assistantName)) {
1489                 assistantName = Settings.Secure.getStringForUser(
1490                         mContentResolver,
1491                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
1492             }
1493             if (!TextUtils.isEmpty(assistantName)) {
1494                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
1495                 if (componentName == null) {
1496                     Slog.w(TAG, "Invalid service name for "
1497                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
1498                     return;
1499                 }
1500                 packageName = componentName.getPackageName();
1501             }
1502         }
1503         if (!TextUtils.isEmpty(packageName)) {
1504             PackageManager pm = mContext.getPackageManager();
1505             ActivityManager am =
1506                           (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
1507 
1508             if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
1509                     == PackageManager.PERMISSION_GRANTED) {
1510                 try {
1511                     assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser());
1512                 } catch (PackageManager.NameNotFoundException e) {
1513                     Log.e(TAG,
1514                             "updateAssistantUId() could not find UID for package: " + packageName);
1515                 }
1516             }
1517         }
1518 
1519         if (assistantUid != mAssistantUid || forceUpdate) {
1520             AudioSystem.setAssistantUid(assistantUid);
1521             mAssistantUid = assistantUid;
1522         }
1523     }
1524 
updateRttEanbled(ContentResolver cr)1525     private void updateRttEanbled(ContentResolver cr) {
1526         final boolean rttEnabled = Settings.Secure.getIntForUser(cr,
1527                     Settings.Secure.RTT_CALLING_MODE, 0, UserHandle.USER_CURRENT) != 0;
1528         AudioSystem.setRttEnabled(rttEnabled);
1529     }
1530 
readPersistedSettings()1531     private void readPersistedSettings() {
1532         final ContentResolver cr = mContentResolver;
1533 
1534         int ringerModeFromSettings =
1535                 Settings.Global.getInt(
1536                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
1537         int ringerMode = ringerModeFromSettings;
1538         // sanity check in case the settings are restored from a device with incompatible
1539         // ringer modes
1540         if (!isValidRingerMode(ringerMode)) {
1541             ringerMode = AudioManager.RINGER_MODE_NORMAL;
1542         }
1543         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
1544             ringerMode = AudioManager.RINGER_MODE_SILENT;
1545         }
1546         if (ringerMode != ringerModeFromSettings) {
1547             Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode);
1548         }
1549         if (mUseFixedVolume || mIsSingleVolume) {
1550             ringerMode = AudioManager.RINGER_MODE_NORMAL;
1551         }
1552         synchronized(mSettingsLock) {
1553             mRingerMode = ringerMode;
1554             if (mRingerModeExternal == -1) {
1555                 mRingerModeExternal = mRingerMode;
1556             }
1557 
1558             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
1559             // are still needed while setVibrateSetting() and getVibrateSetting() are being
1560             // deprecated.
1561             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
1562                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
1563                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
1564                                                             : AudioManager.VIBRATE_SETTING_OFF);
1565             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
1566                                             AudioManager.VIBRATE_TYPE_RINGER,
1567                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
1568                                                             : AudioManager.VIBRATE_SETTING_OFF);
1569 
1570             updateRingerAndZenModeAffectedStreams();
1571             readDockAudioSettings(cr);
1572             sendEncodedSurroundMode(cr, "readPersistedSettings");
1573             sendEnabledSurroundFormats(cr, true);
1574             updateAssistantUId(true);
1575             updateRttEanbled(cr);
1576         }
1577 
1578         mMuteAffectedStreams = System.getIntForUser(cr,
1579                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
1580                 UserHandle.USER_CURRENT);
1581 
1582         updateMasterMono(cr);
1583 
1584         updateMasterBalance(cr);
1585 
1586         // Each stream will read its own persisted settings
1587 
1588         // Broadcast the sticky intents
1589         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
1590         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
1591 
1592         // Broadcast vibrate settings
1593         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
1594         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
1595 
1596         // Load settings for the volume controller
1597         mVolumeController.loadSettings(cr);
1598     }
1599 
readUserRestrictions()1600     private void readUserRestrictions() {
1601         final int currentUser = getCurrentUserId();
1602 
1603         // Check the current user restriction.
1604         boolean masterMute =
1605                 mUserManagerInternal.getUserRestriction(currentUser,
1606                         UserManager.DISALLOW_UNMUTE_DEVICE)
1607                         || mUserManagerInternal.getUserRestriction(currentUser,
1608                         UserManager.DISALLOW_ADJUST_VOLUME);
1609         if (mUseFixedVolume) {
1610             masterMute = false;
1611             AudioSystem.setMasterVolume(1.0f);
1612         }
1613         if (DEBUG_VOL) {
1614             Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
1615         }
1616         setSystemAudioMute(masterMute);
1617         AudioSystem.setMasterMute(masterMute);
1618         broadcastMasterMuteStatus(masterMute);
1619 
1620         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
1621                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1622         if (DEBUG_VOL) {
1623             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
1624                     currentUser));
1625         }
1626         setMicrophoneMuteNoCallerCheck(currentUser);
1627     }
1628 
getIndexRange(int streamType)1629     private int getIndexRange(int streamType) {
1630         return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
1631     }
1632 
rescaleIndex(int index, int srcStream, int dstStream)1633     private int rescaleIndex(int index, int srcStream, int dstStream) {
1634         int srcRange = getIndexRange(srcStream);
1635         int dstRange = getIndexRange(dstStream);
1636         if (srcRange == 0) {
1637             Log.e(TAG, "rescaleIndex : index range should not be zero");
1638             return mStreamStates[dstStream].getMinIndex();
1639         }
1640 
1641         return mStreamStates[dstStream].getMinIndex()
1642                 + ((index - mStreamStates[srcStream].getMinIndex()) * dstRange + srcRange / 2)
1643                 / srcRange;
1644     }
1645 
rescaleStep(int step, int srcStream, int dstStream)1646     private int rescaleStep(int step, int srcStream, int dstStream) {
1647         int srcRange = getIndexRange(srcStream);
1648         int dstRange = getIndexRange(dstStream);
1649         if (srcRange == 0) {
1650             Log.e(TAG, "rescaleStep : index range should not be zero");
1651             return 0;
1652         }
1653 
1654         return ((step * dstRange + srcRange / 2) / srcRange);
1655     }
1656 
1657     ///////////////////////////////////////////////////////////////////////////
1658     // IPC methods
1659     ///////////////////////////////////////////////////////////////////////////
1660     /** @see AudioManager#adjustVolume(int, int) */
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller)1661     public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
1662             String callingPackage, String caller) {
1663         final IAudioPolicyCallback extVolCtlr;
1664         synchronized (mExtVolumeControllerLock) {
1665             extVolCtlr = mExtVolumeController;
1666         }
1667         if (extVolCtlr != null) {
1668             sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
1669                     direction, 0 /*ignored*/,
1670                     extVolCtlr, 0 /*delay*/);
1671         } else {
1672             adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
1673                     caller, Binder.getCallingUid());
1674         }
1675     }
1676 
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid)1677     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
1678             String callingPackage, String caller, int uid) {
1679         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
1680                 + ", flags=" + flags + ", caller=" + caller
1681                 + ", volControlStream=" + mVolumeControlStream
1682                 + ", userSelect=" + mUserSelectedVolumeControlStream);
1683         if (direction != AudioManager.ADJUST_SAME) {
1684             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
1685                     direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
1686                     .append("/").append(caller).append(" uid:").append(uid).toString()));
1687         }
1688         final int streamType;
1689         synchronized (mForceControlStreamLock) {
1690             // Request lock in case mVolumeControlStream is changed by other thread.
1691             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
1692                 streamType = mVolumeControlStream;
1693             } else {
1694                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
1695                 final boolean activeForReal;
1696                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
1697                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
1698                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
1699                 } else {
1700                     activeForReal = AudioSystem.isStreamActive(maybeActiveStreamType, 0);
1701                 }
1702                 if (activeForReal || mVolumeControlStream == -1) {
1703                     streamType = maybeActiveStreamType;
1704                 } else {
1705                     streamType = mVolumeControlStream;
1706                 }
1707             }
1708         }
1709 
1710         final boolean isMute = isMuteAdjust(direction);
1711 
1712         ensureValidStreamType(streamType);
1713         final int resolvedStream = mStreamVolumeAlias[streamType];
1714 
1715         // Play sounds on STREAM_RING only.
1716         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
1717                 resolvedStream != AudioSystem.STREAM_RING) {
1718             flags &= ~AudioManager.FLAG_PLAY_SOUND;
1719         }
1720 
1721         // For notifications/ring, show the ui before making any adjustments
1722         // Don't suppress mute/unmute requests
1723         // Don't suppress adjustments for single volume device
1724         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
1725                 && !mIsSingleVolume) {
1726             direction = 0;
1727             flags &= ~AudioManager.FLAG_PLAY_SOUND;
1728             flags &= ~AudioManager.FLAG_VIBRATE;
1729             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
1730         }
1731 
1732         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
1733     }
1734 
1735     /** @see AudioManager#adjustStreamVolume(int, int, int) */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)1736     public void adjustStreamVolume(int streamType, int direction, int flags,
1737             String callingPackage) {
1738         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
1739             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
1740                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
1741             return;
1742         }
1743         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
1744                 direction/*val1*/, flags/*val2*/, callingPackage));
1745         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
1746                 Binder.getCallingUid());
1747     }
1748 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid)1749     protected void adjustStreamVolume(int streamType, int direction, int flags,
1750             String callingPackage, String caller, int uid) {
1751         if (mUseFixedVolume) {
1752             return;
1753         }
1754         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
1755                 + ", flags=" + flags + ", caller=" + caller);
1756 
1757         ensureValidDirection(direction);
1758         ensureValidStreamType(streamType);
1759 
1760         boolean isMuteAdjust = isMuteAdjust(direction);
1761 
1762         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
1763             return;
1764         }
1765 
1766         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
1767         // that the calling app have the MODIFY_PHONE_STATE permission.
1768         if (isMuteAdjust &&
1769             (streamType == AudioSystem.STREAM_VOICE_CALL ||
1770                 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) &&
1771             mContext.checkCallingOrSelfPermission(
1772                 android.Manifest.permission.MODIFY_PHONE_STATE)
1773                     != PackageManager.PERMISSION_GRANTED) {
1774             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
1775                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
1776             return;
1777         }
1778 
1779         // use stream type alias here so that streams with same alias have the same behavior,
1780         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
1781         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
1782         int streamTypeAlias = mStreamVolumeAlias[streamType];
1783 
1784         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
1785 
1786         final int device = getDeviceForStream(streamTypeAlias);
1787 
1788         int aliasIndex = streamState.getIndex(device);
1789         boolean adjustVolume = true;
1790         int step;
1791 
1792         // skip a2dp absolute volume control request when the device
1793         // is not an a2dp device
1794         if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
1795                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
1796             return;
1797         }
1798 
1799         // If we are being called by the system (e.g. hardware keys) check for current user
1800         // so we handle user restrictions correctly.
1801         if (uid == android.os.Process.SYSTEM_UID) {
1802             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
1803         }
1804         if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
1805                 != AppOpsManager.MODE_ALLOWED) {
1806             return;
1807         }
1808 
1809         // reset any pending volume command
1810         synchronized (mSafeMediaVolumeStateLock) {
1811             mPendingVolumeCommand = null;
1812         }
1813 
1814         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
1815         if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
1816                 mFixedVolumeDevices.contains(device)) {
1817             flags |= AudioManager.FLAG_FIXED_VOLUME;
1818 
1819             // Always toggle between max safe volume and 0 for fixed volume devices where safe
1820             // volume is enforced, and max and 0 for the others.
1821             // This is simulated by stepping by the full allowed volume range
1822             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
1823                     mSafeMediaVolumeDevices.contains(device)) {
1824                 step = safeMediaVolumeIndex(device);
1825             } else {
1826                 step = streamState.getMaxIndex();
1827             }
1828             if (aliasIndex != 0) {
1829                 aliasIndex = step;
1830             }
1831         } else {
1832             // convert one UI step (+/-1) into a number of internal units on the stream alias
1833             step = rescaleStep(10, streamType, streamTypeAlias);
1834         }
1835 
1836         // If either the client forces allowing ringer modes for this adjustment,
1837         // or the stream type is one that is affected by ringer modes
1838         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
1839                 (streamTypeAlias == getUiSoundsStreamType())) {
1840             int ringerMode = getRingerModeInternal();
1841             // do not vibrate if already in vibrate mode
1842             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
1843                 flags &= ~AudioManager.FLAG_VIBRATE;
1844             }
1845             // Check if the ringer mode handles this adjustment. If it does we don't
1846             // need to adjust the volume further.
1847             final int result = checkForRingerModeChange(aliasIndex, direction, step,
1848                     streamState.mIsMuted, callingPackage, flags);
1849             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
1850             // If suppressing a volume adjustment in silent mode, display the UI hint
1851             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
1852                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
1853             }
1854             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
1855             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
1856                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
1857             }
1858         }
1859 
1860         // If the ringer mode or zen is muting the stream, do not change stream unless
1861         // it'll cause us to exit dnd
1862         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
1863             adjustVolume = false;
1864         }
1865         int oldIndex = mStreamStates[streamType].getIndex(device);
1866 
1867         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
1868             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
1869 
1870             if (isMuteAdjust) {
1871                 boolean state;
1872                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
1873                     state = !streamState.mIsMuted;
1874                 } else {
1875                     state = direction == AudioManager.ADJUST_MUTE;
1876                 }
1877                 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
1878                     setSystemAudioMute(state);
1879                 }
1880                 for (int stream = 0; stream < mStreamStates.length; stream++) {
1881                     if (streamTypeAlias == mStreamVolumeAlias[stream]) {
1882                         if (!(readCameraSoundForced()
1883                                     && (mStreamStates[stream].getStreamType()
1884                                         == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
1885                             mStreamStates[stream].mute(state);
1886                         }
1887                     }
1888                 }
1889             } else if ((direction == AudioManager.ADJUST_RAISE) &&
1890                     !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
1891                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
1892                 mVolumeController.postDisplaySafeVolumeWarning(flags);
1893             } else if (!mFullVolumeDevices.contains(device)
1894                     && (streamState.adjustIndex(direction * step, device, caller)
1895                             || streamState.mIsMuted)) {
1896                 // Post message to set system volume (it in turn will post a
1897                 // message to persist).
1898                 if (streamState.mIsMuted) {
1899                     // Unmute the stream if it was previously muted
1900                     if (direction == AudioManager.ADJUST_RAISE) {
1901                         // unmute immediately for volume up
1902                         streamState.mute(false);
1903                     } else if (direction == AudioManager.ADJUST_LOWER) {
1904                         if (mIsSingleVolume) {
1905                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
1906                                     streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
1907                         }
1908                     }
1909                 }
1910                 sendMsg(mAudioHandler,
1911                         MSG_SET_DEVICE_VOLUME,
1912                         SENDMSG_QUEUE,
1913                         device,
1914                         0,
1915                         streamState,
1916                         0);
1917             }
1918 
1919             int newIndex = mStreamStates[streamType].getIndex(device);
1920 
1921             // Check if volume update should be send to AVRCP
1922             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
1923                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
1924                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
1925                 if (DEBUG_VOL) {
1926                     Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
1927                             + newIndex + "stream=" + streamType);
1928                 }
1929                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
1930             }
1931 
1932             // Check if volume update should be send to Hearing Aid
1933             if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
1934                 // only modify the hearing aid attenuation when the stream to modify matches
1935                 // the one expected by the hearing aid
1936                 if (streamType == getHearingAidStreamType()) {
1937                     if (DEBUG_VOL) {
1938                         Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
1939                                 + newIndex + " stream=" + streamType);
1940                     }
1941                     mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
1942                 }
1943             }
1944 
1945             // Check if volume update should be sent to Hdmi system audio.
1946             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
1947                 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
1948             }
1949             synchronized (mHdmiClientLock) {
1950                 if (mHdmiManager != null) {
1951                     // mHdmiCecSink true => mHdmiPlaybackClient != null
1952                     if (mHdmiCecSink
1953                             && streamTypeAlias == AudioSystem.STREAM_MUSIC
1954                             // vol change on a full volume device
1955                             && mFullVolumeDevices.contains(device)) {
1956                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
1957                         switch (direction) {
1958                             case AudioManager.ADJUST_RAISE:
1959                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
1960                                 break;
1961                             case AudioManager.ADJUST_LOWER:
1962                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
1963                                 break;
1964                             case AudioManager.ADJUST_TOGGLE_MUTE:
1965                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
1966                                 break;
1967                             default:
1968                                 break;
1969                         }
1970                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
1971                             final long ident = Binder.clearCallingIdentity();
1972                             try {
1973                                 mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
1974                                 mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
1975                             } finally {
1976                                 Binder.restoreCallingIdentity(ident);
1977                             }
1978                         }
1979                     }
1980 
1981                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
1982                             && (oldIndex != newIndex || isMuteAdjust)) {
1983                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
1984                     }
1985                 }
1986             }
1987         }
1988         int index = mStreamStates[streamType].getIndex(device);
1989         sendVolumeUpdate(streamType, oldIndex, index, flags, device);
1990     }
1991 
1992     // Called after a delay when volume down is pressed while muted
onUnmuteStream(int stream, int flags)1993     private void onUnmuteStream(int stream, int flags) {
1994         boolean wasMuted;
1995         synchronized (VolumeStreamState.class) {
1996             final VolumeStreamState streamState = mStreamStates[stream];
1997             wasMuted = streamState.mute(false); // if unmuting causes a change, it was muted
1998 
1999             final int device = getDeviceForStream(stream);
2000             final int index = streamState.getIndex(device);
2001             sendVolumeUpdate(stream, index, index, flags, device);
2002         }
2003         if (stream == AudioSystem.STREAM_MUSIC && wasMuted) {
2004             synchronized (mHdmiClientLock) {
2005                 maybeSendSystemAudioStatusCommand(true);
2006             }
2007         }
2008     }
2009 
2010     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)2011     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
2012         if (mHdmiAudioSystemClient == null
2013                 || !mHdmiSystemAudioSupported) {
2014             return;
2015         }
2016 
2017         final long identity = Binder.clearCallingIdentity();
2018         mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
2019                 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
2020                 getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
2021                 isStreamMute(AudioSystem.STREAM_MUSIC));
2022         Binder.restoreCallingIdentity(identity);
2023     }
2024 
setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags)2025     private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) {
2026         // Sets the audio volume of AVR when we are in system audio mode. The new volume info
2027         // is tranformed to HDMI-CEC commands and passed through CEC bus.
2028         synchronized (mHdmiClientLock) {
2029             if (mHdmiManager == null
2030                     || mHdmiTvClient == null
2031                     || oldVolume == newVolume
2032                     || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0
2033                     || !mHdmiSystemAudioSupported) {
2034                 return;
2035             }
2036             final long token = Binder.clearCallingIdentity();
2037             try {
2038                 mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume);
2039             } finally {
2040                 Binder.restoreCallingIdentity(token);
2041             }
2042         }
2043     }
2044 
2045     // StreamVolumeCommand contains the information needed to defer the process of
2046     // setStreamVolume() in case the user has to acknowledge the safe volume warning message.
2047     class StreamVolumeCommand {
2048         public final int mStreamType;
2049         public final int mIndex;
2050         public final int mFlags;
2051         public final int mDevice;
2052 
StreamVolumeCommand(int streamType, int index, int flags, int device)2053         StreamVolumeCommand(int streamType, int index, int flags, int device) {
2054             mStreamType = streamType;
2055             mIndex = index;
2056             mFlags = flags;
2057             mDevice = device;
2058         }
2059 
2060         @Override
toString()2061         public String toString() {
2062             return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
2063                     .append(mIndex).append(",flags=").append(mFlags).append(",device=")
2064                     .append(mDevice).append('}').toString();
2065         }
2066     };
2067 
getNewRingerMode(int stream, int index, int flags)2068     private int getNewRingerMode(int stream, int index, int flags) {
2069         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
2070         if (mIsSingleVolume) {
2071             return getRingerModeExternal();
2072         }
2073 
2074         // setting volume on ui sounds stream type also controls silent mode
2075         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
2076                 (stream == getUiSoundsStreamType())) {
2077             int newRingerMode;
2078             if (index == 0) {
2079                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
2080                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
2081                                 : AudioManager.RINGER_MODE_NORMAL;
2082             } else {
2083                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
2084             }
2085             return newRingerMode;
2086         }
2087         return getRingerModeExternal();
2088     }
2089 
isAndroidNPlus(String caller)2090     private boolean isAndroidNPlus(String caller) {
2091         try {
2092             final ApplicationInfo applicationInfo =
2093                     mContext.getPackageManager().getApplicationInfoAsUser(
2094                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
2095             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
2096                 return true;
2097             }
2098             return false;
2099         } catch (PackageManager.NameNotFoundException e) {
2100             return true;
2101         }
2102     }
2103 
wouldToggleZenMode(int newMode)2104     private boolean wouldToggleZenMode(int newMode) {
2105         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
2106                 && newMode != AudioManager.RINGER_MODE_SILENT) {
2107             return true;
2108         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
2109                 && newMode == AudioManager.RINGER_MODE_SILENT) {
2110             return true;
2111         }
2112         return false;
2113     }
2114 
onSetStreamVolume(int streamType, int index, int flags, int device, String caller)2115     private void onSetStreamVolume(int streamType, int index, int flags, int device,
2116             String caller) {
2117         final int stream = mStreamVolumeAlias[streamType];
2118         setStreamVolumeInt(stream, index, device, false, caller);
2119         // setting volume on ui sounds stream type also controls silent mode
2120         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
2121                 (stream == getUiSoundsStreamType())) {
2122             setRingerMode(getNewRingerMode(stream, index, flags),
2123                     TAG + ".onSetStreamVolume", false /*external*/);
2124         }
2125         // setting non-zero volume for a muted stream unmutes the stream and vice versa,
2126         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
2127         if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
2128             mStreamStates[stream].mute(index == 0);
2129         }
2130     }
2131 
enforceModifyAudioRoutingPermission()2132     private void enforceModifyAudioRoutingPermission() {
2133         if (mContext.checkCallingPermission(
2134                     android.Manifest.permission.MODIFY_AUDIO_ROUTING)
2135                 != PackageManager.PERMISSION_GRANTED) {
2136             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
2137         }
2138     }
2139 
2140     /** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
setVolumeIndexForAttributes(@onNull AudioAttributes attr, int index, int flags, String callingPackage)2141     public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
2142                                             String callingPackage) {
2143         enforceModifyAudioRoutingPermission();
2144         Preconditions.checkNotNull(attr, "attr must not be null");
2145         final int volumeGroup = getVolumeGroupIdForAttributes(attr);
2146         if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
2147             Log.e(TAG, ": no volume group found for attributes " + attr.toString());
2148             return;
2149         }
2150         final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
2151 
2152         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
2153                 index/*val1*/, flags/*val2*/, callingPackage));
2154 
2155         vgs.setVolumeIndex(index, flags);
2156 
2157         // For legacy reason, propagate to all streams associated to this volume group
2158         for (final int groupedStream : vgs.getLegacyStreamTypes()) {
2159             try {
2160                 ensureValidStreamType(groupedStream);
2161             } catch (IllegalArgumentException e) {
2162                 Log.d(TAG, "volume group " + volumeGroup + " has internal streams (" + groupedStream
2163                         + "), do not change associated stream volume");
2164                 continue;
2165             }
2166             setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage,
2167                             Binder.getCallingUid());
2168         }
2169     }
2170 
2171     @Nullable
getAudioVolumeGroupById(int volumeGroupId)2172     private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
2173         for (final AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
2174             if (avg.getId() == volumeGroupId) {
2175                 return avg;
2176             }
2177         }
2178 
2179         Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
2180         return null;
2181     }
2182 
2183     /** @see AudioManager#getVolumeIndexForAttributes(attr) */
getVolumeIndexForAttributes(@onNull AudioAttributes attr)2184     public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
2185         enforceModifyAudioRoutingPermission();
2186         Preconditions.checkNotNull(attr, "attr must not be null");
2187         final int volumeGroup = getVolumeGroupIdForAttributes(attr);
2188         if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
2189             throw new IllegalArgumentException("No volume group for attributes " + attr);
2190         }
2191         final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
2192         return vgs.getVolumeIndex();
2193     }
2194 
2195     /** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
getMaxVolumeIndexForAttributes(@onNull AudioAttributes attr)2196     public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
2197         enforceModifyAudioRoutingPermission();
2198         Preconditions.checkNotNull(attr, "attr must not be null");
2199         return AudioSystem.getMaxVolumeIndexForAttributes(attr);
2200     }
2201 
2202     /** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
getMinVolumeIndexForAttributes(@onNull AudioAttributes attr)2203     public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
2204         enforceModifyAudioRoutingPermission();
2205         Preconditions.checkNotNull(attr, "attr must not be null");
2206         return AudioSystem.getMinVolumeIndexForAttributes(attr);
2207     }
2208 
2209     /** @see AudioManager#setStreamVolume(int, int, int) */
setStreamVolume(int streamType, int index, int flags, String callingPackage)2210     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
2211         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
2212             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
2213                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
2214             return;
2215         }
2216         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
2217                 && (mContext.checkCallingOrSelfPermission(
2218                     android.Manifest.permission.MODIFY_PHONE_STATE)
2219                     != PackageManager.PERMISSION_GRANTED)) {
2220             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
2221                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
2222             return;
2223         }
2224         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
2225                 index/*val1*/, flags/*val2*/, callingPackage));
2226         setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
2227                 Binder.getCallingUid());
2228     }
2229 
canChangeAccessibilityVolume()2230     private boolean canChangeAccessibilityVolume() {
2231         synchronized (mAccessibilityServiceUidsLock) {
2232             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
2233                     android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
2234                 return true;
2235             }
2236             if (mAccessibilityServiceUids != null) {
2237                 int callingUid = Binder.getCallingUid();
2238                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
2239                     if (mAccessibilityServiceUids[i] == callingUid) {
2240                         return true;
2241                     }
2242                 }
2243             }
2244             return false;
2245         }
2246     }
2247 
getHearingAidStreamType()2248     /*package*/ int getHearingAidStreamType() {
2249         return getHearingAidStreamType(mMode);
2250     }
2251 
getHearingAidStreamType(int mode)2252     private int getHearingAidStreamType(int mode) {
2253         switch (mode) {
2254             case AudioSystem.MODE_IN_COMMUNICATION:
2255             case AudioSystem.MODE_IN_CALL:
2256                 return AudioSystem.STREAM_VOICE_CALL;
2257             case AudioSystem.MODE_NORMAL:
2258             default:
2259                 // other conditions will influence the stream type choice, read on...
2260                 break;
2261         }
2262         if (mVoiceActive.get()) {
2263             return AudioSystem.STREAM_VOICE_CALL;
2264         }
2265         return AudioSystem.STREAM_MUSIC;
2266     }
2267 
2268     private AtomicBoolean mVoiceActive = new AtomicBoolean(false);
2269 
2270     private final IPlaybackConfigDispatcher mVoiceActivityMonitor =
2271             new IPlaybackConfigDispatcher.Stub() {
2272         @Override
2273         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
2274                                                  boolean flush) {
2275             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
2276                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
2277                     configs /*obj*/, 0 /*delay*/);
2278         }
2279     };
2280 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)2281     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
2282         boolean voiceActive = false;
2283         for (AudioPlaybackConfiguration config : configs) {
2284             final int usage = config.getAudioAttributes().getUsage();
2285             if ((usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
2286                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
2287                     && config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
2288                 voiceActive = true;
2289                 break;
2290             }
2291         }
2292         if (mVoiceActive.getAndSet(voiceActive) != voiceActive) {
2293             updateHearingAidVolumeOnVoiceActivityUpdate();
2294         }
2295     }
2296 
updateHearingAidVolumeOnVoiceActivityUpdate()2297     private void updateHearingAidVolumeOnVoiceActivityUpdate() {
2298         final int streamType = getHearingAidStreamType();
2299         final int index = getStreamVolume(streamType);
2300         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
2301                 mVoiceActive.get(), streamType, index));
2302         mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
2303 
2304     }
2305 
2306     /**
2307      * Manage an audio mode change for audio devices that use an "absolute volume" model,
2308      * i.e. the framework sends the full scale signal, and the actual volume for the use case
2309      * is communicated separately.
2310      */
updateAbsVolumeMultiModeDevices(int oldMode, int newMode)2311     void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
2312         if (oldMode == newMode) {
2313             return;
2314         }
2315         switch (newMode) {
2316             case AudioSystem.MODE_IN_COMMUNICATION:
2317             case AudioSystem.MODE_IN_CALL:
2318             case AudioSystem.MODE_NORMAL:
2319                 break;
2320             case AudioSystem.MODE_RINGTONE:
2321                 // not changing anything for ringtone
2322                 return;
2323             case AudioSystem.MODE_CURRENT:
2324             case AudioSystem.MODE_INVALID:
2325             default:
2326                 // don't know what to do in this case, better bail
2327                 return;
2328         }
2329 
2330         int streamType = getHearingAidStreamType(newMode);
2331 
2332         final Set<Integer> deviceTypes = AudioSystem.generateAudioDeviceTypesSet(
2333                 AudioSystem.getDevicesForStream(streamType));
2334         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
2335                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
2336         if (absVolumeMultiModeCaseDevices.isEmpty()) {
2337             return;
2338         }
2339 
2340         // handling of specific interfaces goes here:
2341         if (AudioSystem.isSingleAudioDeviceType(
2342                 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
2343             final int index = getStreamVolume(streamType);
2344             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
2345                     newMode, streamType, index));
2346             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
2347         }
2348     }
2349 
setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid)2350     private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
2351             String caller, int uid) {
2352         if (DEBUG_VOL) {
2353             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
2354                     + ", calling=" + callingPackage + ")");
2355         }
2356         if (mUseFixedVolume) {
2357             return;
2358         }
2359 
2360         ensureValidStreamType(streamType);
2361         int streamTypeAlias = mStreamVolumeAlias[streamType];
2362         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
2363 
2364         final int device = getDeviceForStream(streamType);
2365         int oldIndex;
2366 
2367         // skip a2dp absolute volume control request when the device
2368         // is not an a2dp device
2369         if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
2370                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
2371             return;
2372         }
2373         // If we are being called by the system (e.g. hardware keys) check for current user
2374         // so we handle user restrictions correctly.
2375         if (uid == android.os.Process.SYSTEM_UID) {
2376             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
2377         }
2378         if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
2379                 != AppOpsManager.MODE_ALLOWED) {
2380             return;
2381         }
2382 
2383         if (isAndroidNPlus(callingPackage)
2384                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
2385                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
2386             throw new SecurityException("Not allowed to change Do Not Disturb state");
2387         }
2388 
2389         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
2390             return;
2391         }
2392 
2393         synchronized (mSafeMediaVolumeStateLock) {
2394             // reset any pending volume command
2395             mPendingVolumeCommand = null;
2396 
2397             oldIndex = streamState.getIndex(device);
2398 
2399             index = rescaleIndex(index * 10, streamType, streamTypeAlias);
2400 
2401             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
2402                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
2403                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
2404                 if (DEBUG_VOL) {
2405                     Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
2406                             + "stream=" + streamType);
2407                 }
2408                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
2409             }
2410 
2411             if (device == AudioSystem.DEVICE_OUT_HEARING_AID
2412                     && streamType == getHearingAidStreamType()) {
2413                 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
2414                         + " stream=" + streamType);
2415                 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
2416             }
2417 
2418             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
2419                 setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags);
2420             }
2421 
2422             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
2423             if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
2424                     mFixedVolumeDevices.contains(device)) {
2425                 flags |= AudioManager.FLAG_FIXED_VOLUME;
2426 
2427                 // volume is either 0 or max allowed for fixed volume devices
2428                 if (index != 0) {
2429                     if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
2430                             mSafeMediaVolumeDevices.contains(device)) {
2431                         index = safeMediaVolumeIndex(device);
2432                     } else {
2433                         index = streamState.getMaxIndex();
2434                     }
2435                 }
2436             }
2437 
2438             if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
2439                 mVolumeController.postDisplaySafeVolumeWarning(flags);
2440                 mPendingVolumeCommand = new StreamVolumeCommand(
2441                                                     streamType, index, flags, device);
2442             } else {
2443                 onSetStreamVolume(streamType, index, flags, device, caller);
2444                 index = mStreamStates[streamType].getIndex(device);
2445             }
2446         }
2447         synchronized (mHdmiClientLock) {
2448             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
2449                     && (oldIndex != index)) {
2450                 maybeSendSystemAudioStatusCommand(false);
2451             }
2452         }
2453         sendVolumeUpdate(streamType, oldIndex, index, flags, device);
2454     }
2455 
2456 
2457 
getVolumeGroupIdForAttributes(@onNull AudioAttributes attributes)2458     private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
2459         Preconditions.checkNotNull(attributes, "attributes must not be null");
2460         int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
2461         if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
2462             return volumeGroupId;
2463         }
2464         // The default volume group is the one hosted by default product strategy, i.e.
2465         // supporting Default Attributes
2466         return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
2467     }
2468 
getVolumeGroupIdForAttributesInt(@onNull AudioAttributes attributes)2469     private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
2470         Preconditions.checkNotNull(attributes, "attributes must not be null");
2471         for (final AudioProductStrategy productStrategy :
2472                 AudioProductStrategy.getAudioProductStrategies()) {
2473             int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
2474             if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
2475                 return volumeGroupId;
2476             }
2477         }
2478         return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
2479     }
2480 
2481 
2482     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)2483     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
2484         switch (mNm.getZenMode()) {
2485             case Settings.Global.ZEN_MODE_OFF:
2486                 return true;
2487             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
2488             case Settings.Global.ZEN_MODE_ALARMS:
2489             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
2490                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
2491                         || streamTypeAlias == getUiSoundsStreamType()
2492                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
2493         }
2494 
2495         return true;
2496     }
2497 
2498     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)2499     public void forceVolumeControlStream(int streamType, IBinder cb) {
2500         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2501                 != PackageManager.PERMISSION_GRANTED) {
2502             return;
2503         }
2504         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
2505         synchronized(mForceControlStreamLock) {
2506             if (mVolumeControlStream != -1 && streamType != -1) {
2507                 mUserSelectedVolumeControlStream = true;
2508             }
2509             mVolumeControlStream = streamType;
2510             if (mVolumeControlStream == -1) {
2511                 if (mForceControlStreamClient != null) {
2512                     mForceControlStreamClient.release();
2513                     mForceControlStreamClient = null;
2514                 }
2515                 mUserSelectedVolumeControlStream = false;
2516             } else {
2517                 if (null == mForceControlStreamClient) {
2518                     mForceControlStreamClient = new ForceControlStreamClient(cb);
2519                 } else {
2520                     if (mForceControlStreamClient.getBinder() == cb) {
2521                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
2522                     } else {
2523                         mForceControlStreamClient.release();
2524                         mForceControlStreamClient = new ForceControlStreamClient(cb);
2525                     }
2526                 }
2527             }
2528         }
2529     }
2530 
2531     private class ForceControlStreamClient implements IBinder.DeathRecipient {
2532         private IBinder mCb; // To be notified of client's death
2533 
ForceControlStreamClient(IBinder cb)2534         ForceControlStreamClient(IBinder cb) {
2535             if (cb != null) {
2536                 try {
2537                     cb.linkToDeath(this, 0);
2538                 } catch (RemoteException e) {
2539                     // Client has died!
2540                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
2541                     cb = null;
2542                 }
2543             }
2544             mCb = cb;
2545         }
2546 
binderDied()2547         public void binderDied() {
2548             synchronized(mForceControlStreamLock) {
2549                 Log.w(TAG, "SCO client died");
2550                 if (mForceControlStreamClient != this) {
2551                     Log.w(TAG, "unregistered control stream client died");
2552                 } else {
2553                     mForceControlStreamClient = null;
2554                     mVolumeControlStream = -1;
2555                     mUserSelectedVolumeControlStream = false;
2556                 }
2557             }
2558         }
2559 
release()2560         public void release() {
2561             if (mCb != null) {
2562                 mCb.unlinkToDeath(this, 0);
2563                 mCb = null;
2564             }
2565         }
2566 
getBinder()2567         public IBinder getBinder() {
2568             return mCb;
2569         }
2570     }
2571 
sendBroadcastToAll(Intent intent)2572     private void sendBroadcastToAll(Intent intent) {
2573         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2574         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2575         final long ident = Binder.clearCallingIdentity();
2576         try {
2577             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
2578         } finally {
2579             Binder.restoreCallingIdentity(ident);
2580         }
2581     }
2582 
sendStickyBroadcastToAll(Intent intent)2583     private void sendStickyBroadcastToAll(Intent intent) {
2584         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
2585         final long ident = Binder.clearCallingIdentity();
2586         try {
2587             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
2588         } finally {
2589             Binder.restoreCallingIdentity(ident);
2590         }
2591     }
2592 
getCurrentUserId()2593     private int getCurrentUserId() {
2594         final long ident = Binder.clearCallingIdentity();
2595         try {
2596             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
2597             return currentUser.id;
2598         } catch (RemoteException e) {
2599             // Activity manager not running, nothing we can do assume user 0.
2600         } finally {
2601             Binder.restoreCallingIdentity(ident);
2602         }
2603         return UserHandle.USER_SYSTEM;
2604     }
2605 
2606     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)2607     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
2608     {
2609         streamType = mStreamVolumeAlias[streamType];
2610 
2611         if (streamType == AudioSystem.STREAM_MUSIC) {
2612             flags = updateFlagsForTvPlatform(flags);
2613             if (mFullVolumeDevices.contains(device)) {
2614                 flags &= ~AudioManager.FLAG_SHOW_UI;
2615             }
2616         }
2617         mVolumeController.postVolumeChanged(streamType, flags);
2618     }
2619 
2620     // If Hdmi-CEC system audio mode is on and we are a TV panel, never show volume bar.
updateFlagsForTvPlatform(int flags)2621     private int updateFlagsForTvPlatform(int flags) {
2622         synchronized (mHdmiClientLock) {
2623             if (mHdmiTvClient != null && mHdmiSystemAudioSupported) {
2624                 flags &= ~AudioManager.FLAG_SHOW_UI;
2625             }
2626         }
2627         return flags;
2628     }
2629 
2630     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)2631     private void sendMasterMuteUpdate(boolean muted, int flags) {
2632         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
2633         broadcastMasterMuteStatus(muted);
2634     }
2635 
broadcastMasterMuteStatus(boolean muted)2636     private void broadcastMasterMuteStatus(boolean muted) {
2637         Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
2638         intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
2639         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
2640                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
2641         sendStickyBroadcastToAll(intent);
2642     }
2643 
2644     /**
2645      * Sets the stream state's index, and posts a message to set system volume.
2646      * This will not call out to the UI. Assumes a valid stream type.
2647      *
2648      * @param streamType Type of the stream
2649      * @param index Desired volume index of the stream
2650      * @param device the device whose volume must be changed
2651      * @param force If true, set the volume even if the desired volume is same
2652      * as the current volume.
2653      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller)2654     private void setStreamVolumeInt(int streamType,
2655                                     int index,
2656                                     int device,
2657                                     boolean force,
2658                                     String caller) {
2659         if (mFullVolumeDevices.contains(device)) {
2660             return;
2661         }
2662         VolumeStreamState streamState = mStreamStates[streamType];
2663 
2664         if (streamState.setIndex(index, device, caller) || force) {
2665             // Post message to set system volume (it in turn will post a message
2666             // to persist).
2667             sendMsg(mAudioHandler,
2668                     MSG_SET_DEVICE_VOLUME,
2669                     SENDMSG_QUEUE,
2670                     device,
2671                     0,
2672                     streamState,
2673                     0);
2674         }
2675     }
2676 
setSystemAudioMute(boolean state)2677     private void setSystemAudioMute(boolean state) {
2678         synchronized (mHdmiClientLock) {
2679             if (mHdmiManager == null || mHdmiTvClient == null || !mHdmiSystemAudioSupported) return;
2680             final long token = Binder.clearCallingIdentity();
2681             try {
2682                 mHdmiTvClient.setSystemAudioMute(state);
2683             } finally {
2684                 Binder.restoreCallingIdentity(token);
2685             }
2686         }
2687     }
2688 
2689     /** get stream mute state. */
isStreamMute(int streamType)2690     public boolean isStreamMute(int streamType) {
2691         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
2692             streamType = getActiveStreamType(streamType);
2693         }
2694         synchronized (VolumeStreamState.class) {
2695             ensureValidStreamType(streamType);
2696             return mStreamStates[streamType].mIsMuted;
2697         }
2698     }
2699 
2700     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
2701         private IBinder mICallback; // To be notified of client's death
2702 
RmtSbmxFullVolDeathHandler(IBinder cb)2703         RmtSbmxFullVolDeathHandler(IBinder cb) {
2704             mICallback = cb;
2705             try {
2706                 cb.linkToDeath(this, 0/*flags*/);
2707             } catch (RemoteException e) {
2708                 Log.e(TAG, "can't link to death", e);
2709             }
2710         }
2711 
isHandlerFor(IBinder cb)2712         boolean isHandlerFor(IBinder cb) {
2713             return mICallback.equals(cb);
2714         }
2715 
forget()2716         void forget() {
2717             try {
2718                 mICallback.unlinkToDeath(this, 0/*flags*/);
2719             } catch (NoSuchElementException e) {
2720                 Log.e(TAG, "error unlinking to death", e);
2721             }
2722         }
2723 
binderDied()2724         public void binderDied() {
2725             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
2726             forceRemoteSubmixFullVolume(false, mICallback);
2727         }
2728     }
2729 
2730     /**
2731      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
2732      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)2733     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
2734         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
2735         while (it.hasNext()) {
2736             final RmtSbmxFullVolDeathHandler handler = it.next();
2737             if (handler.isHandlerFor(cb)) {
2738                 handler.forget();
2739                 mRmtSbmxFullVolDeathHandlers.remove(handler);
2740                 return true;
2741             }
2742         }
2743         return false;
2744     }
2745 
2746     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)2747     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
2748         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
2749         while (it.hasNext()) {
2750             if (it.next().isHandlerFor(cb)) {
2751                 return true;
2752             }
2753         }
2754         return false;
2755     }
2756 
2757     private int mRmtSbmxFullVolRefCount = 0;
2758     private ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
2759             new ArrayList<RmtSbmxFullVolDeathHandler>();
2760 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)2761     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
2762         if (cb == null) {
2763             return;
2764         }
2765         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
2766                         android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) {
2767             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
2768             return;
2769         }
2770         synchronized(mRmtSbmxFullVolDeathHandlers) {
2771             boolean applyRequired = false;
2772             if (startForcing) {
2773                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
2774                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
2775                     if (mRmtSbmxFullVolRefCount == 0) {
2776                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
2777                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
2778                         applyRequired = true;
2779                     }
2780                     mRmtSbmxFullVolRefCount++;
2781                 }
2782             } else {
2783                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
2784                     mRmtSbmxFullVolRefCount--;
2785                     if (mRmtSbmxFullVolRefCount == 0) {
2786                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
2787                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
2788                         applyRequired = true;
2789                     }
2790                 }
2791             }
2792             if (applyRequired) {
2793                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
2794                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
2795                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
2796             }
2797         }
2798     }
2799 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId)2800     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
2801             int userId) {
2802         // If we are being called by the system check for user we are going to change
2803         // so we handle user restrictions correctly.
2804         if (uid == android.os.Process.SYSTEM_UID) {
2805             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
2806         }
2807         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
2808         if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage)
2809                 != AppOpsManager.MODE_ALLOWED) {
2810             return;
2811         }
2812         if (userId != UserHandle.getCallingUserId() &&
2813                 mContext.checkCallingOrSelfPermission(
2814                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
2815                 != PackageManager.PERMISSION_GRANTED) {
2816             return;
2817         }
2818         setMasterMuteInternalNoCallerCheck(mute, flags, userId);
2819     }
2820 
setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)2821     private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
2822         if (DEBUG_VOL) {
2823             Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
2824         }
2825         if (!isPlatformAutomotive() && mUseFixedVolume) {
2826             // If using fixed volume, we don't mute.
2827             // TODO: remove the isPlatformAutomotive check here.
2828             // The isPlatformAutomotive check is added for safety but may not be necessary.
2829             return;
2830         }
2831         // For automotive,
2832         // - the car service is always running as system user
2833         // - foreground users are non-system users
2834         // Car service is in charge of dispatching the key event include master mute to Android.
2835         // Therefore, the getCurrentUser() is always different to the foreground user.
2836         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
2837                 || (getCurrentUserId() == userId)) {
2838             if (mute != AudioSystem.getMasterMute()) {
2839                 setSystemAudioMute(mute);
2840                 AudioSystem.setMasterMute(mute);
2841                 sendMasterMuteUpdate(mute, flags);
2842             }
2843         }
2844     }
2845 
2846     /** get master mute state. */
isMasterMute()2847     public boolean isMasterMute() {
2848         return AudioSystem.getMasterMute();
2849     }
2850 
setMasterMute(boolean mute, int flags, String callingPackage, int userId)2851     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) {
2852         enforceModifyAudioRoutingPermission();
2853         setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(),
2854                 userId);
2855     }
2856 
2857     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)2858     public int getStreamVolume(int streamType) {
2859         ensureValidStreamType(streamType);
2860         int device = getDeviceForStream(streamType);
2861         synchronized (VolumeStreamState.class) {
2862             int index = mStreamStates[streamType].getIndex(device);
2863 
2864             // by convention getStreamVolume() returns 0 when a stream is muted.
2865             if (mStreamStates[streamType].mIsMuted) {
2866                 index = 0;
2867             }
2868             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
2869                     mFixedVolumeDevices.contains(device)) {
2870                 index = mStreamStates[streamType].getMaxIndex();
2871             }
2872             return (index + 5) / 10;
2873         }
2874     }
2875 
2876     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)2877     public int getStreamMaxVolume(int streamType) {
2878         ensureValidStreamType(streamType);
2879         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
2880     }
2881 
2882     /** @see AudioManager#getStreamMinVolumeInt(int) */
getStreamMinVolume(int streamType)2883     public int getStreamMinVolume(int streamType) {
2884         ensureValidStreamType(streamType);
2885         return (mStreamStates[streamType].getMinIndex() + 5) / 10;
2886     }
2887 
2888     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)2889     public int getLastAudibleStreamVolume(int streamType) {
2890         ensureValidStreamType(streamType);
2891         int device = getDeviceForStream(streamType);
2892         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
2893     }
2894 
2895     /** @see AudioManager#getUiSoundsStreamType()  */
getUiSoundsStreamType()2896     public int getUiSoundsStreamType() {
2897         return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
2898     }
2899 
2900     /** @see AudioManager#setMicrophoneMute(boolean) */
2901     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId)2902     public void setMicrophoneMute(boolean on, String callingPackage, int userId) {
2903         // If we are being called by the system check for user we are going to change
2904         // so we handle user restrictions correctly.
2905         int uid = Binder.getCallingUid();
2906         if (uid == android.os.Process.SYSTEM_UID) {
2907             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
2908         }
2909         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
2910         if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage)
2911                 != AppOpsManager.MODE_ALLOWED) {
2912             return;
2913         }
2914         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
2915             return;
2916         }
2917         if (userId != UserHandle.getCallingUserId() &&
2918                 mContext.checkCallingOrSelfPermission(
2919                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
2920                 != PackageManager.PERMISSION_GRANTED) {
2921             return;
2922         }
2923         mMicMuteFromApi = on;
2924         setMicrophoneMuteNoCallerCheck(userId);
2925     }
2926 
2927     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)2928     public void setMicrophoneMuteFromSwitch(boolean on) {
2929         int userId = Binder.getCallingUid();
2930         if (userId != android.os.Process.SYSTEM_UID) {
2931             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
2932             return;
2933         }
2934         mMicMuteFromSwitch = on;
2935         setMicrophoneMuteNoCallerCheck(userId);
2936     }
2937 
setMicMuteFromSwitchInput()2938     private void setMicMuteFromSwitchInput() {
2939         InputManager im = mContext.getSystemService(InputManager.class);
2940         final int isMicMuted = im.isMicMuted();
2941         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
2942             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
2943         }
2944     }
2945 
isMicrophoneMuted()2946     public boolean isMicrophoneMuted() {
2947         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi;
2948     }
2949 
setMicrophoneMuteNoCallerCheck(int userId)2950     private void setMicrophoneMuteNoCallerCheck(int userId) {
2951         final boolean muted = isMicrophoneMuted();
2952         if (DEBUG_VOL) {
2953             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
2954         }
2955         // only mute for the current user
2956         if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
2957             final boolean currentMute = AudioSystem.isMicrophoneMuted();
2958             final long identity = Binder.clearCallingIdentity();
2959             AudioSystem.muteMicrophone(muted);
2960             Binder.restoreCallingIdentity(identity);
2961             if (muted != currentMute) {
2962                 mContext.sendBroadcastAsUser(
2963                         new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)
2964                                 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
2965             }
2966         }
2967     }
2968 
2969     @Override
getRingerModeExternal()2970     public int getRingerModeExternal() {
2971         synchronized(mSettingsLock) {
2972             return mRingerModeExternal;
2973         }
2974     }
2975 
2976     @Override
getRingerModeInternal()2977     public int getRingerModeInternal() {
2978         synchronized(mSettingsLock) {
2979             return mRingerMode;
2980         }
2981     }
2982 
ensureValidRingerMode(int ringerMode)2983     private void ensureValidRingerMode(int ringerMode) {
2984         if (!isValidRingerMode(ringerMode)) {
2985             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
2986         }
2987     }
2988 
2989     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)2990     public boolean isValidRingerMode(int ringerMode) {
2991         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
2992     }
2993 
setRingerModeExternal(int ringerMode, String caller)2994     public void setRingerModeExternal(int ringerMode, String caller) {
2995         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
2996                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
2997             throw new SecurityException("Not allowed to change Do Not Disturb state");
2998         }
2999 
3000         setRingerMode(ringerMode, caller, true /*external*/);
3001     }
3002 
setRingerModeInternal(int ringerMode, String caller)3003     public void setRingerModeInternal(int ringerMode, String caller) {
3004         enforceVolumeController("setRingerModeInternal");
3005         setRingerMode(ringerMode, caller, false /*external*/);
3006     }
3007 
silenceRingerModeInternal(String reason)3008     public void silenceRingerModeInternal(String reason) {
3009         VibrationEffect effect = null;
3010         int ringerMode = AudioManager.RINGER_MODE_SILENT;
3011         int toastText = 0;
3012 
3013         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
3014         if (mContext.getResources()
3015                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
3016             silenceRingerSetting = Settings.Secure.getIntForUser(mContentResolver,
3017                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
3018                     UserHandle.USER_CURRENT);
3019         }
3020 
3021         switch(silenceRingerSetting) {
3022             case VOLUME_HUSH_MUTE:
3023                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
3024                 ringerMode = AudioManager.RINGER_MODE_SILENT;
3025                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
3026                 break;
3027             case VOLUME_HUSH_VIBRATE:
3028                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
3029                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
3030                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
3031                 break;
3032         }
3033         maybeVibrate(effect, reason);
3034         setRingerModeInternal(ringerMode, reason);
3035         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
3036     }
3037 
maybeVibrate(VibrationEffect effect, String reason)3038     private boolean maybeVibrate(VibrationEffect effect, String reason) {
3039         if (!mHasVibrator) {
3040             return false;
3041         }
3042         final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(),
3043                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0;
3044         if (hapticsDisabled) {
3045             return false;
3046         }
3047 
3048         if (effect == null) {
3049             return false;
3050         }
3051         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
3052                 reason, VIBRATION_ATTRIBUTES);
3053         return true;
3054     }
3055 
setRingerMode(int ringerMode, String caller, boolean external)3056     private void setRingerMode(int ringerMode, String caller, boolean external) {
3057         if (mUseFixedVolume || mIsSingleVolume) {
3058             return;
3059         }
3060         if (caller == null || caller.length() == 0) {
3061             throw new IllegalArgumentException("Bad caller: " + caller);
3062         }
3063         ensureValidRingerMode(ringerMode);
3064         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
3065             ringerMode = AudioManager.RINGER_MODE_SILENT;
3066         }
3067         final long identity = Binder.clearCallingIdentity();
3068         try {
3069             synchronized (mSettingsLock) {
3070                 final int ringerModeInternal = getRingerModeInternal();
3071                 final int ringerModeExternal = getRingerModeExternal();
3072                 if (external) {
3073                     setRingerModeExt(ringerMode);
3074                     if (mRingerModeDelegate != null) {
3075                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
3076                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
3077                     }
3078                     if (ringerMode != ringerModeInternal) {
3079                         setRingerModeInt(ringerMode, true /*persist*/);
3080                     }
3081                 } else /*internal*/ {
3082                     if (ringerMode != ringerModeInternal) {
3083                         setRingerModeInt(ringerMode, true /*persist*/);
3084                     }
3085                     if (mRingerModeDelegate != null) {
3086                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
3087                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
3088                     }
3089                     setRingerModeExt(ringerMode);
3090                 }
3091             }
3092         } finally {
3093             Binder.restoreCallingIdentity(identity);
3094         }
3095     }
3096 
setRingerModeExt(int ringerMode)3097     private void setRingerModeExt(int ringerMode) {
3098         synchronized(mSettingsLock) {
3099             if (ringerMode == mRingerModeExternal) return;
3100             mRingerModeExternal = ringerMode;
3101         }
3102         // Send sticky broadcast
3103         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
3104     }
3105 
3106     @GuardedBy("mSettingsLock")
muteRingerModeStreams()3107     private void muteRingerModeStreams() {
3108         // Mute stream if not previously muted by ringer mode and (ringer mode
3109         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
3110         // Unmute stream if previously muted by ringer/zen mode and ringer mode
3111         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
3112         int numStreamTypes = AudioSystem.getNumStreamTypes();
3113 
3114         if (mNm == null) {
3115             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
3116         }
3117 
3118         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
3119         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
3120                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
3121         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
3122                 && isBluetoothScoOn();
3123         // Ask audio policy engine to force use Bluetooth SCO channel if needed
3124         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
3125                 + "/" + Binder.getCallingPid();
3126         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
3127                 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0);
3128 
3129         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
3130             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
3131             final boolean muteAllowedBySco =
3132                     !(shouldRingSco && streamType == AudioSystem.STREAM_RING);
3133             final boolean shouldZenMute = shouldZenMuteStream(streamType);
3134             final boolean shouldMute = shouldZenMute || (ringerModeMute
3135                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
3136             if (isMuted == shouldMute) continue;
3137             if (!shouldMute) {
3138                 // unmute
3139                 // ring and notifications volume should never be 0 when not silenced
3140                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
3141                     synchronized (VolumeStreamState.class) {
3142                         final VolumeStreamState vss = mStreamStates[streamType];
3143                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
3144                             int device = vss.mIndexMap.keyAt(i);
3145                             int value = vss.mIndexMap.valueAt(i);
3146                             if (value == 0) {
3147                                 vss.setIndex(10, device, TAG);
3148                             }
3149                         }
3150                         // Persist volume for stream ring when it is changed here
3151                       final int device = getDeviceForStream(streamType);
3152                       sendMsg(mAudioHandler,
3153                               MSG_PERSIST_VOLUME,
3154                               SENDMSG_QUEUE,
3155                               device,
3156                               0,
3157                               mStreamStates[streamType],
3158                               PERSIST_DELAY);
3159                     }
3160                 }
3161                 mStreamStates[streamType].mute(false);
3162                 mRingerAndZenModeMutedStreams &= ~(1 << streamType);
3163             } else {
3164                 // mute
3165                 mStreamStates[streamType].mute(true);
3166                 mRingerAndZenModeMutedStreams |= (1 << streamType);
3167             }
3168         }
3169     }
3170 
isAlarm(int streamType)3171     private boolean isAlarm(int streamType) {
3172         return streamType == AudioSystem.STREAM_ALARM;
3173     }
3174 
isNotificationOrRinger(int streamType)3175     private boolean isNotificationOrRinger(int streamType) {
3176         return streamType == AudioSystem.STREAM_NOTIFICATION
3177                 || streamType == AudioSystem.STREAM_RING;
3178     }
3179 
isMedia(int streamType)3180     private boolean isMedia(int streamType) {
3181         return streamType == AudioSystem.STREAM_MUSIC;
3182     }
3183 
3184 
isSystem(int streamType)3185     private boolean isSystem(int streamType) {
3186         return streamType == AudioSystem.STREAM_SYSTEM;
3187     }
3188 
setRingerModeInt(int ringerMode, boolean persist)3189     private void setRingerModeInt(int ringerMode, boolean persist) {
3190         final boolean change;
3191         synchronized(mSettingsLock) {
3192             change = mRingerMode != ringerMode;
3193             mRingerMode = ringerMode;
3194             muteRingerModeStreams();
3195         }
3196 
3197         // Post a persist ringer mode msg
3198         if (persist) {
3199             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
3200                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
3201         }
3202         if (change) {
3203             // Send sticky broadcast
3204             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
3205         }
3206     }
3207 
postUpdateRingerModeServiceInt()3208     /*package*/ void postUpdateRingerModeServiceInt() {
3209         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
3210     }
3211 
onUpdateRingerModeServiceInt()3212     private void onUpdateRingerModeServiceInt() {
3213         setRingerModeInt(getRingerModeInternal(), false);
3214     }
3215 
3216     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)3217     public boolean shouldVibrate(int vibrateType) {
3218         if (!mHasVibrator) return false;
3219 
3220         switch (getVibrateSetting(vibrateType)) {
3221 
3222             case AudioManager.VIBRATE_SETTING_ON:
3223                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
3224 
3225             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
3226                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
3227 
3228             case AudioManager.VIBRATE_SETTING_OFF:
3229                 // return false, even for incoming calls
3230                 return false;
3231 
3232             default:
3233                 return false;
3234         }
3235     }
3236 
3237     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)3238     public int getVibrateSetting(int vibrateType) {
3239         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
3240         return (mVibrateSetting >> (vibrateType * 2)) & 3;
3241     }
3242 
3243     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)3244     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
3245 
3246         if (!mHasVibrator) return;
3247 
3248         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
3249                 vibrateSetting);
3250 
3251         // Broadcast change
3252         broadcastVibrateSetting(vibrateType);
3253 
3254     }
3255 
3256     /**
3257      * Return the pid of the current audio mode owner
3258      * @return 0 if nobody owns the mode
3259      */
getModeOwnerPid()3260     /*package*/ int getModeOwnerPid() {
3261         int modeOwnerPid = 0;
3262         try {
3263             modeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
3264         } catch (Exception e) {
3265             // nothing to do, modeOwnerPid is not modified
3266         }
3267         return modeOwnerPid;
3268     }
3269 
3270     private class SetModeDeathHandler implements IBinder.DeathRecipient {
3271         private IBinder mCb; // To be notified of client's death
3272         private int mPid;
3273         private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client
3274 
SetModeDeathHandler(IBinder cb, int pid)3275         SetModeDeathHandler(IBinder cb, int pid) {
3276             mCb = cb;
3277             mPid = pid;
3278         }
3279 
binderDied()3280         public void binderDied() {
3281             int oldModeOwnerPid = 0;
3282             int newModeOwnerPid = 0;
3283             synchronized (mDeviceBroker.mSetModeLock) {
3284                 Log.w(TAG, "setMode() client died");
3285                 if (!mSetModeDeathHandlers.isEmpty()) {
3286                     oldModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
3287                 }
3288                 int index = mSetModeDeathHandlers.indexOf(this);
3289                 if (index < 0) {
3290                     Log.w(TAG, "unregistered setMode() client died");
3291                 } else {
3292                     newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG);
3293                 }
3294             }
3295             // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
3296             // SCO connections not started by the application changing the mode when pid changes
3297             if ((newModeOwnerPid != oldModeOwnerPid) && (newModeOwnerPid != 0)) {
3298                 mDeviceBroker.postDisconnectBluetoothSco(newModeOwnerPid);
3299             }
3300         }
3301 
getPid()3302         public int getPid() {
3303             return mPid;
3304         }
3305 
setMode(int mode)3306         public void setMode(int mode) {
3307             mMode = mode;
3308         }
3309 
getMode()3310         public int getMode() {
3311             return mMode;
3312         }
3313 
getBinder()3314         public IBinder getBinder() {
3315             return mCb;
3316         }
3317     }
3318 
3319     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)3320     public void setMode(int mode, IBinder cb, String callingPackage) {
3321         if (DEBUG_MODE) { Log.v(TAG, "setMode(mode=" + mode + ", callingPackage=" + callingPackage + ")"); }
3322         if (!checkAudioSettingsPermission("setMode()")) {
3323             return;
3324         }
3325 
3326         if ( (mode == AudioSystem.MODE_IN_CALL) &&
3327                 (mContext.checkCallingOrSelfPermission(
3328                         android.Manifest.permission.MODIFY_PHONE_STATE)
3329                             != PackageManager.PERMISSION_GRANTED)) {
3330             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid="
3331                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3332             return;
3333         }
3334 
3335         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
3336             return;
3337         }
3338 
3339         int oldModeOwnerPid = 0;
3340         int newModeOwnerPid = 0;
3341         synchronized (mDeviceBroker.mSetModeLock) {
3342             if (!mSetModeDeathHandlers.isEmpty()) {
3343                 oldModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
3344             }
3345             if (mode == AudioSystem.MODE_CURRENT) {
3346                 mode = mMode;
3347             }
3348             newModeOwnerPid = setModeInt(mode, cb, Binder.getCallingPid(), callingPackage);
3349         }
3350         // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
3351         // SCO connections not started by the application changing the mode when pid changes
3352         if ((newModeOwnerPid != oldModeOwnerPid) && (newModeOwnerPid != 0)) {
3353             mDeviceBroker.postDisconnectBluetoothSco(newModeOwnerPid);
3354         }
3355     }
3356 
3357     // setModeInt() returns a valid PID if the audio mode was successfully set to
3358     // any mode other than NORMAL.
3359     @GuardedBy("mDeviceBroker.mSetModeLock")
setModeInt(int mode, IBinder cb, int pid, String caller)3360     private int setModeInt(int mode, IBinder cb, int pid, String caller) {
3361         if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller="
3362                 + caller + ")"); }
3363         int newModeOwnerPid = 0;
3364         if (cb == null) {
3365             Log.e(TAG, "setModeInt() called with null binder");
3366             return newModeOwnerPid;
3367         }
3368 
3369         SetModeDeathHandler hdlr = null;
3370         Iterator iter = mSetModeDeathHandlers.iterator();
3371         while (iter.hasNext()) {
3372             SetModeDeathHandler h = (SetModeDeathHandler)iter.next();
3373             if (h.getPid() == pid) {
3374                 hdlr = h;
3375                 // Remove from client list so that it is re-inserted at top of list
3376                 iter.remove();
3377                 try {
3378                     hdlr.getBinder().unlinkToDeath(hdlr, 0);
3379                     if (cb != hdlr.getBinder()){
3380                         hdlr = null;
3381                     }
3382                 } catch (NoSuchElementException e) {
3383                     hdlr = null;
3384                     Log.w(TAG, "link does not exist ...");
3385                 }
3386                 break;
3387             }
3388         }
3389         final int oldMode = mMode;
3390         int status = AudioSystem.AUDIO_STATUS_OK;
3391         int actualMode;
3392         do {
3393             actualMode = mode;
3394             if (mode == AudioSystem.MODE_NORMAL) {
3395                 // get new mode from client at top the list if any
3396                 if (!mSetModeDeathHandlers.isEmpty()) {
3397                     hdlr = mSetModeDeathHandlers.get(0);
3398                     cb = hdlr.getBinder();
3399                     actualMode = hdlr.getMode();
3400                     if (DEBUG_MODE) {
3401                         Log.w(TAG, " using mode=" + mode + " instead due to death hdlr at pid="
3402                                 + hdlr.mPid);
3403                     }
3404                 }
3405             } else {
3406                 if (hdlr == null) {
3407                     hdlr = new SetModeDeathHandler(cb, pid);
3408                 }
3409                 // Register for client death notification
3410                 try {
3411                     cb.linkToDeath(hdlr, 0);
3412                 } catch (RemoteException e) {
3413                     // Client has died!
3414                     Log.w(TAG, "setMode() could not link to "+cb+" binder death");
3415                 }
3416 
3417                 // Last client to call setMode() is always at top of client list
3418                 // as required by SetModeDeathHandler.binderDied()
3419                 mSetModeDeathHandlers.add(0, hdlr);
3420                 hdlr.setMode(mode);
3421             }
3422 
3423             if (actualMode != mMode) {
3424                 final long identity = Binder.clearCallingIdentity();
3425                 status = AudioSystem.setPhoneState(actualMode);
3426                 Binder.restoreCallingIdentity(identity);
3427                 if (status == AudioSystem.AUDIO_STATUS_OK) {
3428                     if (DEBUG_MODE) { Log.v(TAG, " mode successfully set to " + actualMode); }
3429                     mMode = actualMode;
3430                 } else {
3431                     if (hdlr != null) {
3432                         mSetModeDeathHandlers.remove(hdlr);
3433                         cb.unlinkToDeath(hdlr, 0);
3434                     }
3435                     // force reading new top of mSetModeDeathHandlers stack
3436                     if (DEBUG_MODE) { Log.w(TAG, " mode set to MODE_NORMAL after phoneState pb"); }
3437                     mode = AudioSystem.MODE_NORMAL;
3438                 }
3439             } else {
3440                 status = AudioSystem.AUDIO_STATUS_OK;
3441             }
3442         } while (status != AudioSystem.AUDIO_STATUS_OK && !mSetModeDeathHandlers.isEmpty());
3443 
3444         if (status == AudioSystem.AUDIO_STATUS_OK) {
3445             if (actualMode != AudioSystem.MODE_NORMAL) {
3446                 if (mSetModeDeathHandlers.isEmpty()) {
3447                     Log.e(TAG, "setMode() different from MODE_NORMAL with empty mode client stack");
3448                 } else {
3449                     newModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
3450                 }
3451             }
3452             // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
3453             mModeLogger.log(
3454                     new PhoneStateEvent(caller, pid, mode, newModeOwnerPid, actualMode));
3455             int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
3456             int device = getDeviceForStream(streamType);
3457             int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
3458             setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller);
3459 
3460             updateStreamVolumeAlias(true /*updateVolumes*/, caller);
3461 
3462             // change of mode may require volume to be re-applied on some devices
3463             updateAbsVolumeMultiModeDevices(oldMode, actualMode);
3464         }
3465         return newModeOwnerPid;
3466     }
3467 
3468     /** @see AudioManager#getMode() */
getMode()3469     public int getMode() {
3470         return mMode;
3471     }
3472 
3473     //==========================================================================================
3474     // Sound Effects
3475     //==========================================================================================
3476     private static final class LoadSoundEffectReply
3477             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
3478         private static final int SOUND_EFFECTS_LOADING = 1;
3479         private static final int SOUND_EFFECTS_LOADED = 0;
3480         private static final int SOUND_EFFECTS_ERROR = -1;
3481         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
3482 
3483         private int mStatus = SOUND_EFFECTS_LOADING;
3484 
3485         @Override
run(boolean success)3486         public synchronized void run(boolean success) {
3487             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
3488             notify();
3489         }
3490 
waitForLoaded(int attempts)3491         public synchronized boolean waitForLoaded(int attempts) {
3492             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
3493                 try {
3494                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
3495                 } catch (InterruptedException e) {
3496                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
3497                 }
3498             }
3499             return mStatus == SOUND_EFFECTS_LOADED;
3500         }
3501     }
3502 
3503     /** @see AudioManager#playSoundEffect(int) */
playSoundEffect(int effectType)3504     public void playSoundEffect(int effectType) {
3505         playSoundEffectVolume(effectType, -1.0f);
3506     }
3507 
3508     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)3509     public void playSoundEffectVolume(int effectType, float volume) {
3510         // do not try to play the sound effect if the system stream is muted
3511         if (isStreamMutedByRingerOrZenMode(STREAM_SYSTEM)) {
3512             return;
3513         }
3514 
3515         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
3516             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
3517             return;
3518         }
3519 
3520         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
3521                 effectType, (int) (volume * 1000), null, 0);
3522     }
3523 
3524     /**
3525      * Loads samples into the soundpool.
3526      * This method must be called at first when sound effects are enabled
3527      */
loadSoundEffects()3528     public boolean loadSoundEffects() {
3529         LoadSoundEffectReply reply = new LoadSoundEffectReply();
3530         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
3531         return reply.waitForLoaded(3 /*attempts*/);
3532     }
3533 
3534     /**
3535      * Schedule loading samples into the soundpool.
3536      * This method can be overridden to schedule loading at a later time.
3537      */
scheduleLoadSoundEffects()3538     protected void scheduleLoadSoundEffects() {
3539         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
3540     }
3541 
3542     /**
3543      *  Unloads samples from the sound pool.
3544      *  This method can be called to free some memory when
3545      *  sound effects are disabled.
3546      */
unloadSoundEffects()3547     public void unloadSoundEffects() {
3548         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
3549     }
3550 
3551     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()3552     public void reloadAudioSettings() {
3553         readAudioSettings(false /*userSwitch*/);
3554     }
3555 
readAudioSettings(boolean userSwitch)3556     private void readAudioSettings(boolean userSwitch) {
3557         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
3558         readPersistedSettings();
3559         readUserRestrictions();
3560 
3561         // restore volume settings
3562         int numStreamTypes = AudioSystem.getNumStreamTypes();
3563         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
3564             VolumeStreamState streamState = mStreamStates[streamType];
3565 
3566             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
3567                 continue;
3568             }
3569 
3570             streamState.readSettings();
3571             synchronized (VolumeStreamState.class) {
3572                 // unmute stream that was muted but is not affect by mute anymore
3573                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
3574                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
3575                     streamState.mIsMuted = false;
3576                 }
3577             }
3578         }
3579 
3580         // apply new ringer mode before checking volume for alias streams so that streams
3581         // muted by ringer mode have the correct volume
3582         setRingerModeInt(getRingerModeInternal(), false);
3583 
3584         checkAllFixedVolumeDevices();
3585         checkAllAliasStreamVolumes();
3586         checkMuteAffectedStreams();
3587 
3588         synchronized (mSafeMediaVolumeStateLock) {
3589             mMusicActiveMs = MathUtils.constrain(Settings.Secure.getIntForUser(mContentResolver,
3590                     Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT),
3591                     0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX);
3592             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
3593                 enforceSafeMediaVolume(TAG);
3594             }
3595         }
3596 
3597         readVolumeGroupsSettings();
3598     }
3599 
3600     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(boolean on)3601     public void setSpeakerphoneOn(boolean on){
3602         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
3603             return;
3604         }
3605 
3606         if (mContext.checkCallingOrSelfPermission(
3607                 android.Manifest.permission.MODIFY_PHONE_STATE)
3608                 != PackageManager.PERMISSION_GRANTED) {
3609             synchronized (mSetModeDeathHandlers) {
3610                 for (SetModeDeathHandler h : mSetModeDeathHandlers) {
3611                     if (h.getMode() == AudioSystem.MODE_IN_CALL) {
3612                         Log.w(TAG, "getMode is call, Permission Denial: setSpeakerphoneOn from pid="
3613                                 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3614                         return;
3615                     }
3616                 }
3617             }
3618         }
3619 
3620         // for logging only
3621         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
3622                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
3623                 .append(Binder.getCallingPid()).toString();
3624         final boolean stateChanged = mDeviceBroker.setSpeakerphoneOn(on, eventSource);
3625         if (stateChanged) {
3626             final long ident = Binder.clearCallingIdentity();
3627             try {
3628                 mContext.sendBroadcastAsUser(
3629                         new Intent(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)
3630                                 .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
3631             } finally {
3632                 Binder.restoreCallingIdentity(ident);
3633             }
3634         }
3635     }
3636 
3637     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()3638     public boolean isSpeakerphoneOn() {
3639         return mDeviceBroker.isSpeakerphoneOn();
3640     }
3641 
3642     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)3643     public void setBluetoothScoOn(boolean on) {
3644         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
3645             return;
3646         }
3647 
3648         // Only enable calls from system components
3649         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
3650             mDeviceBroker.setBluetoothScoOnByApp(on);
3651             return;
3652         }
3653 
3654         // for logging only
3655         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
3656                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
3657                 .append(Binder.getCallingPid()).toString();
3658 
3659         mDeviceBroker.setBluetoothScoOn(on, eventSource);
3660     }
3661 
3662     /** @see AudioManager#isBluetoothScoOn()
3663      * Note that it doesn't report internal state, but state seen by apps (which may have
3664      * called setBluetoothScoOn() */
isBluetoothScoOn()3665     public boolean isBluetoothScoOn() {
3666         return mDeviceBroker.isBluetoothScoOnForApp();
3667     }
3668 
3669     // TODO investigate internal users due to deprecation of SDK API
3670     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)3671     public void setBluetoothA2dpOn(boolean on) {
3672         // for logging only
3673         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
3674                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
3675                 .append(Binder.getCallingPid()).toString();
3676         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
3677     }
3678 
3679     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()3680     public boolean isBluetoothA2dpOn() {
3681         return mDeviceBroker.isBluetoothA2dpOn();
3682     }
3683 
3684     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion)3685     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
3686         final int scoAudioMode =
3687                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
3688                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
3689         final String eventSource = new StringBuilder("startBluetoothSco()")
3690                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
3691                 .append(Binder.getCallingPid()).toString();
3692         startBluetoothScoInt(cb, scoAudioMode, eventSource);
3693     }
3694 
3695     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb)3696     public void startBluetoothScoVirtualCall(IBinder cb) {
3697         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
3698                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
3699                 .append(Binder.getCallingPid()).toString();
3700         startBluetoothScoInt(cb, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
3701     }
3702 
startBluetoothScoInt(IBinder cb, int scoAudioMode, @NonNull String eventSource)3703     void startBluetoothScoInt(IBinder cb, int scoAudioMode, @NonNull String eventSource) {
3704         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
3705                 !mSystemReady) {
3706             return;
3707         }
3708         synchronized (mDeviceBroker.mSetModeLock) {
3709             mDeviceBroker.startBluetoothScoForClient_Sync(cb, scoAudioMode, eventSource);
3710         }
3711     }
3712 
3713     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb)3714     public void stopBluetoothSco(IBinder cb){
3715         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
3716                 !mSystemReady) {
3717             return;
3718         }
3719         final String eventSource =  new StringBuilder("stopBluetoothSco()")
3720                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
3721                 .append(Binder.getCallingPid()).toString();
3722         synchronized (mDeviceBroker.mSetModeLock) {
3723             mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource);
3724         }
3725     }
3726 
3727 
getContentResolver()3728     /*package*/ ContentResolver getContentResolver() {
3729         return mContentResolver;
3730     }
3731 
onCheckMusicActive(String caller)3732     private void onCheckMusicActive(String caller) {
3733         synchronized (mSafeMediaVolumeStateLock) {
3734             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
3735                 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
3736 
3737                 if (mSafeMediaVolumeDevices.contains(device)) {
3738                     sendMsg(mAudioHandler,
3739                             MSG_CHECK_MUSIC_ACTIVE,
3740                             SENDMSG_REPLACE,
3741                             0,
3742                             0,
3743                             caller,
3744                             MUSIC_ACTIVE_POLL_PERIOD_MS);
3745                     int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
3746                     if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)
3747                             && (index > safeMediaVolumeIndex(device))) {
3748                         // Approximate cumulative active music time
3749                         mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS;
3750                         if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
3751                             setSafeMediaVolumeEnabled(true, caller);
3752                             mMusicActiveMs = 0;
3753                         }
3754                         saveMusicActiveMs();
3755                     }
3756                 }
3757             }
3758         }
3759     }
3760 
saveMusicActiveMs()3761     private void saveMusicActiveMs() {
3762         mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget();
3763     }
3764 
getSafeUsbMediaVolumeIndex()3765     private int getSafeUsbMediaVolumeIndex() {
3766         // determine UI volume index corresponding to the wanted safe gain in dBFS
3767         int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
3768         int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
3769 
3770         mSafeUsbMediaVolumeDbfs = mContext.getResources().getInteger(
3771                 com.android.internal.R.integer.config_safe_media_volume_usb_mB) / 100.0f;
3772 
3773         while (Math.abs(max - min) > 1) {
3774             int index = (max + min) / 2;
3775             float gainDB = AudioSystem.getStreamVolumeDB(
3776                     AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
3777             if (Float.isNaN(gainDB)) {
3778                 //keep last min in case of read error
3779                 break;
3780             } else if (gainDB == mSafeUsbMediaVolumeDbfs) {
3781                 min = index;
3782                 break;
3783             } else if (gainDB < mSafeUsbMediaVolumeDbfs) {
3784                 min = index;
3785             } else {
3786                 max = index;
3787             }
3788         }
3789         return min * 10;
3790     }
3791 
onConfigureSafeVolume(boolean force, String caller)3792     private void onConfigureSafeVolume(boolean force, String caller) {
3793         synchronized (mSafeMediaVolumeStateLock) {
3794             int mcc = mContext.getResources().getConfiguration().mcc;
3795             if ((mMcc != mcc) || ((mMcc == 0) && force)) {
3796                 mSafeMediaVolumeIndex = mContext.getResources().getInteger(
3797                         com.android.internal.R.integer.config_safe_media_volume_index) * 10;
3798 
3799                 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
3800 
3801                 boolean safeMediaVolumeEnabled =
3802                         SystemProperties.getBoolean("audio.safemedia.force", false)
3803                         || mContext.getResources().getBoolean(
3804                                 com.android.internal.R.bool.config_safe_media_volume_enabled);
3805 
3806                 boolean safeMediaVolumeBypass =
3807                         SystemProperties.getBoolean("audio.safemedia.bypass", false);
3808 
3809                 // The persisted state is either "disabled" or "active": this is the state applied
3810                 // next time we boot and cannot be "inactive"
3811                 int persistedState;
3812                 if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
3813                     persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
3814                     // The state can already be "inactive" here if the user has forced it before
3815                     // the 30 seconds timeout for forced configuration. In this case we don't reset
3816                     // it to "active".
3817                     if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
3818                         if (mMusicActiveMs == 0) {
3819                             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
3820                             enforceSafeMediaVolume(caller);
3821                         } else {
3822                             // We have existing playback time recorded, already confirmed.
3823                             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
3824                         }
3825                     }
3826                 } else {
3827                     persistedState = SAFE_MEDIA_VOLUME_DISABLED;
3828                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
3829                 }
3830                 mMcc = mcc;
3831                 sendMsg(mAudioHandler,
3832                         MSG_PERSIST_SAFE_VOLUME_STATE,
3833                         SENDMSG_QUEUE,
3834                         persistedState,
3835                         0,
3836                         null,
3837                         0);
3838             }
3839         }
3840     }
3841 
3842     ///////////////////////////////////////////////////////////////////////////
3843     // Internal methods
3844     ///////////////////////////////////////////////////////////////////////////
3845 
3846     /**
3847      * Checks if the adjustment should change ringer mode instead of just
3848      * adjusting volume. If so, this will set the proper ringer mode and volume
3849      * indices on the stream states.
3850      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)3851     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
3852             String caller, int flags) {
3853         int result = FLAG_ADJUST_VOLUME;
3854         if (isPlatformTelevision() || mIsSingleVolume) {
3855             return result;
3856         }
3857 
3858         int ringerMode = getRingerModeInternal();
3859 
3860         switch (ringerMode) {
3861         case RINGER_MODE_NORMAL:
3862             if (direction == AudioManager.ADJUST_LOWER) {
3863                 if (mHasVibrator) {
3864                     // "step" is the delta in internal index units corresponding to a
3865                     // change of 1 in UI index units.
3866                     // Because of rounding when rescaling from one stream index range to its alias
3867                     // index range, we cannot simply test oldIndex == step:
3868                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
3869                     if (step <= oldIndex && oldIndex < 2 * step) {
3870                         ringerMode = RINGER_MODE_VIBRATE;
3871                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
3872                     }
3873                 } else {
3874                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
3875                         ringerMode = RINGER_MODE_SILENT;
3876                     }
3877                 }
3878             } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE
3879                     || direction == AudioManager.ADJUST_MUTE)) {
3880                 if (mHasVibrator) {
3881                     ringerMode = RINGER_MODE_VIBRATE;
3882                 } else {
3883                     ringerMode = RINGER_MODE_SILENT;
3884                 }
3885                 // Setting the ringer mode will toggle mute
3886                 result &= ~FLAG_ADJUST_VOLUME;
3887             }
3888             break;
3889         case RINGER_MODE_VIBRATE:
3890             if (!mHasVibrator) {
3891                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
3892                         "but no vibrator is present");
3893                 break;
3894             }
3895             if ((direction == AudioManager.ADJUST_LOWER)) {
3896                 // This is the case we were muted with the volume turned up
3897                 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) {
3898                     ringerMode = RINGER_MODE_NORMAL;
3899                 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
3900                     if (mVolumePolicy.volumeDownToEnterSilent) {
3901                         final long diff = SystemClock.uptimeMillis()
3902                                 - mLoweredFromNormalToVibrateTime;
3903                         if (diff > mVolumePolicy.vibrateToSilentDebounce
3904                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
3905                             ringerMode = RINGER_MODE_SILENT;
3906                         }
3907                     } else {
3908                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
3909                     }
3910                 }
3911             } else if (direction == AudioManager.ADJUST_RAISE
3912                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
3913                     || direction == AudioManager.ADJUST_UNMUTE) {
3914                 ringerMode = RINGER_MODE_NORMAL;
3915             }
3916             result &= ~FLAG_ADJUST_VOLUME;
3917             break;
3918         case RINGER_MODE_SILENT:
3919             if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
3920                 // This is the case we were muted with the volume turned up
3921                 ringerMode = RINGER_MODE_NORMAL;
3922             } else if (direction == AudioManager.ADJUST_RAISE
3923                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
3924                     || direction == AudioManager.ADJUST_UNMUTE) {
3925                 if (!mVolumePolicy.volumeUpToExitSilent) {
3926                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
3927                 } else {
3928                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
3929                       ringerMode = RINGER_MODE_VIBRATE;
3930                   } else {
3931                       // If we don't have a vibrator or they were toggling mute
3932                       // go straight back to normal.
3933                       ringerMode = RINGER_MODE_NORMAL;
3934                   }
3935                 }
3936             }
3937             result &= ~FLAG_ADJUST_VOLUME;
3938             break;
3939         default:
3940             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
3941             break;
3942         }
3943 
3944         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
3945                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
3946                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
3947             throw new SecurityException("Not allowed to change Do Not Disturb state");
3948         }
3949 
3950         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
3951 
3952         mPrevVolDirection = direction;
3953 
3954         return result;
3955     }
3956 
3957     @Override
isStreamAffectedByRingerMode(int streamType)3958     public boolean isStreamAffectedByRingerMode(int streamType) {
3959         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
3960     }
3961 
shouldZenMuteStream(int streamType)3962     private boolean shouldZenMuteStream(int streamType) {
3963         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
3964             return false;
3965         }
3966 
3967         NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
3968         final boolean muteAlarms = (zenPolicy.priorityCategories
3969                 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0;
3970         final boolean muteMedia = (zenPolicy.priorityCategories
3971                 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0;
3972         final boolean muteSystem = (zenPolicy.priorityCategories
3973                 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0;
3974         final boolean muteNotificationAndRing = ZenModeConfig
3975                 .areAllPriorityOnlyNotificationZenSoundsMuted(zenPolicy);
3976         return muteAlarms && isAlarm(streamType)
3977                 || muteMedia && isMedia(streamType)
3978                 || muteSystem && isSystem(streamType)
3979                 || muteNotificationAndRing && isNotificationOrRinger(streamType);
3980     }
3981 
isStreamMutedByRingerOrZenMode(int streamType)3982     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
3983         return (mRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
3984     }
3985 
3986     /**
3987      * Notifications, ringer and system sounds are controlled by the ringer:
3988      * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can
3989      * also be muted by DND based on the DND mode:
3990      * DND total silence: media and alarms streams can be muted by DND
3991      * DND alarms only: no streams additionally controlled by DND
3992      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
3993      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
3994      * @return true if changed, else false
3995      */
updateZenModeAffectedStreams()3996     private boolean updateZenModeAffectedStreams() {
3997         int zenModeAffectedStreams = 0;
3998         if (mSystemReady && mNm.getZenMode() == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
3999             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
4000             if ((zenPolicy.priorityCategories
4001                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
4002                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
4003             }
4004 
4005             if ((zenPolicy.priorityCategories
4006                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
4007                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
4008             }
4009 
4010             if ((zenPolicy.priorityCategories
4011                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
4012                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
4013             }
4014 
4015             if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(zenPolicy)) {
4016                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
4017                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
4018             }
4019         }
4020 
4021         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
4022             mZenModeAffectedStreams = zenModeAffectedStreams;
4023             return true;
4024         }
4025 
4026         return false;
4027     }
4028 
4029     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()4030     private boolean updateRingerAndZenModeAffectedStreams() {
4031         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
4032         int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
4033                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
4034                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
4035                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
4036                  UserHandle.USER_CURRENT);
4037 
4038         if (mIsSingleVolume) {
4039             ringerModeAffectedStreams = 0;
4040         } else if (mRingerModeDelegate != null) {
4041             ringerModeAffectedStreams = mRingerModeDelegate
4042                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
4043         }
4044         if (mCameraSoundForced) {
4045             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
4046         } else {
4047             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
4048         }
4049         if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) {
4050             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
4051         } else {
4052             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
4053         }
4054 
4055         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
4056             Settings.System.putIntForUser(mContentResolver,
4057                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
4058                     ringerModeAffectedStreams,
4059                     UserHandle.USER_CURRENT);
4060             mRingerModeAffectedStreams = ringerModeAffectedStreams;
4061             return true;
4062         }
4063         return updatedZenModeAffectedStreams;
4064     }
4065 
4066     @Override
isStreamAffectedByMute(int streamType)4067     public boolean isStreamAffectedByMute(int streamType) {
4068         return (mMuteAffectedStreams & (1 << streamType)) != 0;
4069     }
4070 
ensureValidDirection(int direction)4071     private void ensureValidDirection(int direction) {
4072         switch (direction) {
4073             case AudioManager.ADJUST_LOWER:
4074             case AudioManager.ADJUST_RAISE:
4075             case AudioManager.ADJUST_SAME:
4076             case AudioManager.ADJUST_MUTE:
4077             case AudioManager.ADJUST_UNMUTE:
4078             case AudioManager.ADJUST_TOGGLE_MUTE:
4079                 break;
4080             default:
4081                 throw new IllegalArgumentException("Bad direction " + direction);
4082         }
4083     }
4084 
ensureValidStreamType(int streamType)4085     private void ensureValidStreamType(int streamType) {
4086         if (streamType < 0 || streamType >= mStreamStates.length) {
4087             throw new IllegalArgumentException("Bad stream type " + streamType);
4088         }
4089     }
4090 
isMuteAdjust(int adjust)4091     private boolean isMuteAdjust(int adjust) {
4092         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
4093                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
4094     }
4095 
4096     /** only public for mocking/spying, do not call outside of AudioService */
4097     @VisibleForTesting
isInCommunication()4098     public boolean isInCommunication() {
4099         boolean IsInCall = false;
4100 
4101         TelecomManager telecomManager =
4102                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
4103 
4104         final long ident = Binder.clearCallingIdentity();
4105         IsInCall = telecomManager.isInCall();
4106         Binder.restoreCallingIdentity(ident);
4107 
4108         return (IsInCall || getMode() == AudioManager.MODE_IN_COMMUNICATION ||
4109                 getMode() == AudioManager.MODE_IN_CALL);
4110     }
4111 
4112     /**
4113      * For code clarity for getActiveStreamType(int)
4114      * @param delay_ms max time since last stream activity to consider
4115      * @return true if stream is active in streams handled by AudioFlinger now or
4116      *     in the last "delay_ms" ms.
4117      */
wasStreamActiveRecently(int stream, int delay_ms)4118     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
4119         return AudioSystem.isStreamActive(stream, delay_ms)
4120                 || AudioSystem.isStreamActiveRemotely(stream, delay_ms);
4121     }
4122 
getActiveStreamType(int suggestedStreamType)4123     private int getActiveStreamType(int suggestedStreamType) {
4124         if (mIsSingleVolume
4125                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
4126             return AudioSystem.STREAM_MUSIC;
4127         }
4128 
4129         switch (mPlatformType) {
4130         case AudioSystem.PLATFORM_VOICE:
4131             if (isInCommunication()) {
4132                 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
4133                         == AudioSystem.FORCE_BT_SCO) {
4134                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
4135                     return AudioSystem.STREAM_BLUETOOTH_SCO;
4136                 } else {
4137                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
4138                     return AudioSystem.STREAM_VOICE_CALL;
4139                 }
4140             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
4141                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
4142                     if (DEBUG_VOL)
4143                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
4144                     return AudioSystem.STREAM_RING;
4145                 } else if (wasStreamActiveRecently(
4146                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
4147                     if (DEBUG_VOL)
4148                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
4149                     return AudioSystem.STREAM_NOTIFICATION;
4150                 } else {
4151                     if (DEBUG_VOL) {
4152                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
4153                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
4154                     }
4155                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
4156                 }
4157             } else if (
4158                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
4159                 if (DEBUG_VOL)
4160                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
4161                 return AudioSystem.STREAM_NOTIFICATION;
4162             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
4163                 if (DEBUG_VOL)
4164                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
4165                 return AudioSystem.STREAM_RING;
4166             }
4167         default:
4168             if (isInCommunication()) {
4169                 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
4170                         == AudioSystem.FORCE_BT_SCO) {
4171                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
4172                     return AudioSystem.STREAM_BLUETOOTH_SCO;
4173                 } else {
4174                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
4175                     return AudioSystem.STREAM_VOICE_CALL;
4176                 }
4177             } else if (AudioSystem.isStreamActive(
4178                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
4179                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
4180                 return AudioSystem.STREAM_NOTIFICATION;
4181             } else if (AudioSystem.isStreamActive(
4182                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
4183                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
4184                 return AudioSystem.STREAM_RING;
4185             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
4186                 if (AudioSystem.isStreamActive(
4187                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
4188                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
4189                     return AudioSystem.STREAM_NOTIFICATION;
4190                 } else if (AudioSystem.isStreamActive(
4191                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
4192                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
4193                     return AudioSystem.STREAM_RING;
4194                 } else {
4195                     if (DEBUG_VOL) {
4196                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
4197                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
4198                     }
4199                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
4200                 }
4201             }
4202             break;
4203         }
4204         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
4205                 + suggestedStreamType);
4206         return suggestedStreamType;
4207     }
4208 
broadcastRingerMode(String action, int ringerMode)4209     private void broadcastRingerMode(String action, int ringerMode) {
4210         // Send sticky broadcast
4211         Intent broadcast = new Intent(action);
4212         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
4213         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
4214                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
4215         sendStickyBroadcastToAll(broadcast);
4216     }
4217 
broadcastVibrateSetting(int vibrateType)4218     private void broadcastVibrateSetting(int vibrateType) {
4219         // Send broadcast
4220         if (mActivityManagerInternal.isSystemReady()) {
4221             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
4222             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
4223             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
4224             sendBroadcastToAll(broadcast);
4225         }
4226     }
4227 
4228     // Message helper methods
4229     /**
4230      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
4231      * Note that the wake lock needs to be released after the message has been handled.
4232      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)4233     private void queueMsgUnderWakeLock(Handler handler, int msg,
4234             int arg1, int arg2, Object obj, int delay) {
4235         final long ident = Binder.clearCallingIdentity();
4236         // Always acquire the wake lock as AudioService because it is released by the
4237         // message handler.
4238         mAudioEventWakeLock.acquire();
4239         Binder.restoreCallingIdentity(ident);
4240         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
4241     }
4242 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)4243     private static void sendMsg(Handler handler, int msg,
4244             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
4245         if (existingMsgPolicy == SENDMSG_REPLACE) {
4246             handler.removeMessages(msg);
4247         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
4248             return;
4249         }
4250 
4251         final long time = SystemClock.uptimeMillis() + delay;
4252         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
4253     }
4254 
checkAudioSettingsPermission(String method)4255     boolean checkAudioSettingsPermission(String method) {
4256         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS)
4257                 == PackageManager.PERMISSION_GRANTED) {
4258             return true;
4259         }
4260         String msg = "Audio Settings Permission Denial: " + method + " from pid="
4261                 + Binder.getCallingPid()
4262                 + ", uid=" + Binder.getCallingUid();
4263         Log.w(TAG, msg);
4264         return false;
4265     }
4266 
4267     /** only public for mocking/spying, do not call outside of AudioService */
4268     @VisibleForTesting
getDeviceForStream(int stream)4269     public int getDeviceForStream(int stream) {
4270         int device = getDevicesForStream(stream);
4271         if ((device & (device - 1)) != 0) {
4272             // Multiple device selection is either:
4273             //  - speaker + one other device: give priority to speaker in this case.
4274             //  - one A2DP device + another device: happens with duplicated output. In this case
4275             // retain the device on the A2DP output as the other must not correspond to an active
4276             // selection if not the speaker.
4277             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
4278             // FIXME: Haven't applied audio device type refactor to this API
4279             //  as it is going to be deprecated.
4280             if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) {
4281                 device = AudioSystem.DEVICE_OUT_SPEAKER;
4282             } else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) {
4283                 device = AudioSystem.DEVICE_OUT_HDMI_ARC;
4284             } else if ((device & AudioSystem.DEVICE_OUT_SPDIF) != 0) {
4285                 device = AudioSystem.DEVICE_OUT_SPDIF;
4286             } else if ((device & AudioSystem.DEVICE_OUT_AUX_LINE) != 0) {
4287                 device = AudioSystem.DEVICE_OUT_AUX_LINE;
4288             } else {
4289                 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_A2DP_SET) {
4290                     if ((deviceType & device) == deviceType) {
4291                         return deviceType;
4292                     }
4293                 }
4294             }
4295         }
4296         return device;
4297     }
4298 
getDevicesForStream(int stream)4299     private int getDevicesForStream(int stream) {
4300         return getDevicesForStream(stream, true /*checkOthers*/);
4301     }
4302 
getDevicesForStream(int stream, boolean checkOthers)4303     private int getDevicesForStream(int stream, boolean checkOthers) {
4304         ensureValidStreamType(stream);
4305         synchronized (VolumeStreamState.class) {
4306             return mStreamStates[stream].observeDevicesForStream_syncVSS(checkOthers);
4307         }
4308     }
4309 
observeDevicesForStreams(int skipStream)4310     private void observeDevicesForStreams(int skipStream) {
4311         synchronized (VolumeStreamState.class) {
4312             for (int stream = 0; stream < mStreamStates.length; stream++) {
4313                 if (stream != skipStream) {
4314                     mStreamStates[stream].observeDevicesForStream_syncVSS(false /*checkOthers*/);
4315                 }
4316             }
4317         }
4318     }
4319 
4320     /** only public for mocking/spying, do not call outside of AudioService */
4321     @VisibleForTesting
postObserveDevicesForAllStreams()4322     public void postObserveDevicesForAllStreams() {
4323         sendMsg(mAudioHandler,
4324                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
4325                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/, null /*obj*/,
4326                 0 /*delay*/);
4327     }
4328 
onObserveDevicesForAllStreams()4329     private void onObserveDevicesForAllStreams() {
4330         observeDevicesForStreams(-1);
4331     }
4332 
4333     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
4334     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
4335     /**
4336      * The states that can be used with AudioService.setWiredDeviceConnectionState()
4337      * Attention: those values differ from those in BluetoothProfile, follow annotations to
4338      * distinguish between @ConnectionState and @BtProfileConnectionState
4339      */
4340     @IntDef({
4341             CONNECTION_STATE_DISCONNECTED,
4342             CONNECTION_STATE_CONNECTED,
4343     })
4344     @Retention(RetentionPolicy.SOURCE)
4345     public @interface ConnectionState {}
4346 
4347     /**
4348      * see AudioManager.setWiredDeviceConnectionState()
4349      */
setWiredDeviceConnectionState(int type, @ConnectionState int state, String address, String name, String caller)4350     public void setWiredDeviceConnectionState(int type,
4351             @ConnectionState int state, String address, String name,
4352             String caller) {
4353         enforceModifyAudioRoutingPermission();
4354         if (state != CONNECTION_STATE_CONNECTED
4355                 && state != CONNECTION_STATE_DISCONNECTED) {
4356             throw new IllegalArgumentException("Invalid state " + state);
4357         }
4358         mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
4359     }
4360 
4361     /**
4362      * @hide
4363      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
4364      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
4365      */
4366     @IntDef({
4367             BluetoothProfile.STATE_DISCONNECTED,
4368             BluetoothProfile.STATE_CONNECTED,
4369     })
4370     @Retention(RetentionPolicy.SOURCE)
4371     public @interface BtProfileConnectionState {}
4372 
4373     /**
4374      * See AudioManager.setBluetoothHearingAidDeviceConnectionState()
4375      */
setBluetoothHearingAidDeviceConnectionState( @onNull BluetoothDevice device, @BtProfileConnectionState int state, boolean suppressNoisyIntent, int musicDevice)4376     public void setBluetoothHearingAidDeviceConnectionState(
4377             @NonNull BluetoothDevice device, @BtProfileConnectionState int state,
4378             boolean suppressNoisyIntent, int musicDevice)
4379     {
4380         if (device == null) {
4381             throw new IllegalArgumentException("Illegal null device");
4382         }
4383         if (state != BluetoothProfile.STATE_CONNECTED
4384                 && state != BluetoothProfile.STATE_DISCONNECTED) {
4385             throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
4386                     + " (dis)connection, got " + state);
4387         }
4388         if (state == BluetoothProfile.STATE_CONNECTED) {
4389             mPlaybackMonitor.registerPlaybackCallback(mVoiceActivityMonitor, true);
4390         } else {
4391             mPlaybackMonitor.unregisterPlaybackCallback(mVoiceActivityMonitor);
4392         }
4393         mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
4394                 device, state, suppressNoisyIntent, musicDevice, "AudioService");
4395     }
4396 
4397     /**
4398      * See AudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
4399      */
setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( @onNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)4400     public void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
4401             @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
4402             int profile, boolean suppressNoisyIntent, int a2dpVolume) {
4403         if (device == null) {
4404             throw new IllegalArgumentException("Illegal null device");
4405         }
4406         if (state != BluetoothProfile.STATE_CONNECTED
4407                 && state != BluetoothProfile.STATE_DISCONNECTED) {
4408             throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
4409                     + " (dis)connection, got " + state);
4410         }
4411         mDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(device, state,
4412                 profile, suppressNoisyIntent, a2dpVolume);
4413     }
4414 
4415     /**
4416      * See AudioManager.handleBluetoothA2dpDeviceConfigChange()
4417      * @param device
4418      */
handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)4419     public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)
4420     {
4421         if (device == null) {
4422             throw new IllegalArgumentException("Illegal null device");
4423         }
4424         mDeviceBroker.postBluetoothA2dpDeviceConfigChange(device);
4425     }
4426 
4427     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
4428     static {
4429         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
4430         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
4431         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
4432         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
4433         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
4434         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
4435         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI);
4436     }
4437 
4438     /** only public for mocking/spying, do not call outside of AudioService */
4439     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)4440     public void postAccessoryPlugMediaUnmute(int newDevice) {
4441         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
4442                 newDevice, 0, null, 0);
4443     }
4444 
onAccessoryPlugMediaUnmute(int newDevice)4445     private void onAccessoryPlugMediaUnmute(int newDevice) {
4446         if (DEBUG_VOL) {
4447             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
4448                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
4449         }
4450 
4451         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
4452                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
4453                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
4454                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
4455                 && (newDevice & AudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC)) != 0) {
4456             if (DEBUG_VOL) {
4457                 Log.i(TAG, String.format(" onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
4458                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
4459             }
4460             mStreamStates[AudioSystem.STREAM_MUSIC].mute(false);
4461         }
4462     }
4463 
4464     /**
4465      * See AudioManager.hasHapticChannels(Uri).
4466      */
hasHapticChannels(Uri uri)4467     public boolean hasHapticChannels(Uri uri) {
4468         MediaExtractor extractor = new MediaExtractor();
4469         try {
4470             extractor.setDataSource(mContext, uri, null);
4471             for (int i = 0; i < extractor.getTrackCount(); i++) {
4472                 MediaFormat format = extractor.getTrackFormat(i);
4473                 if (format.containsKey(MediaFormat.KEY_HAPTIC_CHANNEL_COUNT)
4474                         && format.getInteger(MediaFormat.KEY_HAPTIC_CHANNEL_COUNT) > 0) {
4475                     return true;
4476                 }
4477             }
4478         } catch (IOException e) {
4479             Log.e(TAG, "hasHapticChannels failure:" + e);
4480         }
4481         return false;
4482     }
4483 
4484     ///////////////////////////////////////////////////////////////////////////
4485     // Inner classes
4486     ///////////////////////////////////////////////////////////////////////////
4487     /**
4488      * Key is the AudioManager VolumeGroupId
4489      * Value is the VolumeGroupState
4490      */
4491     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
4492 
initVolumeGroupStates()4493     private void initVolumeGroupStates() {
4494         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
4495             try {
4496                 // if no valid attributes, this volume group is not controllable, throw exception
4497                 ensureValidAttributes(avg);
4498             } catch (IllegalArgumentException e) {
4499                 // Volume Groups without attributes are not controllable through set/get volume
4500                 // using attributes. Do not append them.
4501                 if (DEBUG_VOL) {
4502                     Log.v(TAG, "volume group " + avg.name() + " for internal policy needs");
4503                 }
4504                 continue;
4505             }
4506             sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
4507         }
4508         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
4509             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
4510             vgs.applyAllVolumes();
4511         }
4512     }
4513 
ensureValidAttributes(AudioVolumeGroup avg)4514     private void ensureValidAttributes(AudioVolumeGroup avg) {
4515         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
4516                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.sDefaultAttributes));
4517         if (!hasAtLeastOneValidAudioAttributes) {
4518             throw new IllegalArgumentException("Volume Group " + avg.name()
4519                     + " has no valid audio attributes");
4520         }
4521     }
4522 
readVolumeGroupsSettings()4523     private void readVolumeGroupsSettings() {
4524         if (DEBUG_VOL) {
4525             Log.v(TAG, "readVolumeGroupsSettings.");
4526         }
4527         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
4528             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
4529             vgs.readSettings();
4530             vgs.applyAllVolumes();
4531         }
4532     }
4533 
4534     // Called upon crash of AudioServer
restoreVolumeGroups()4535     private void restoreVolumeGroups() {
4536         if (DEBUG_VOL) {
4537             Log.v(TAG, "restoreVolumeGroups");
4538         }
4539         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
4540             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
4541             vgs.applyAllVolumes();
4542         }
4543     }
4544 
dumpVolumeGroups(PrintWriter pw)4545     private void dumpVolumeGroups(PrintWriter pw) {
4546         pw.println("\nVolume Groups (device: index)");
4547         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
4548             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
4549             vgs.dump(pw);
4550             pw.println("");
4551         }
4552     }
4553 
4554     // NOTE: Locking order for synchronized objects related to volume management:
4555     //  1     mSettingsLock
4556     //  2       VolumeGroupState.class
4557     private class VolumeGroupState {
4558         private final AudioVolumeGroup mAudioVolumeGroup;
4559         private final SparseIntArray mIndexMap = new SparseIntArray(8);
4560         private int mIndexMin;
4561         private int mIndexMax;
4562         private int mLegacyStreamType = AudioSystem.STREAM_DEFAULT;
4563         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
4564         private AudioAttributes mAudioAttributes = AudioProductStrategy.sDefaultAttributes;
4565 
4566         // No API in AudioSystem to get a device from strategy or from attributes.
4567         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()4568         private int getDeviceForVolume() {
4569             return getDeviceForStream(mPublicStreamType);
4570         }
4571 
VolumeGroupState(AudioVolumeGroup avg)4572         private VolumeGroupState(AudioVolumeGroup avg) {
4573             mAudioVolumeGroup = avg;
4574             if (DEBUG_VOL) {
4575                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
4576             }
4577             for (final AudioAttributes aa : avg.getAudioAttributes()) {
4578                 if (!aa.equals(AudioProductStrategy.sDefaultAttributes)) {
4579                     mAudioAttributes = aa;
4580                     break;
4581                 }
4582             }
4583             final int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
4584             if (streamTypes.length != 0) {
4585                 // Uses already initialized MIN / MAX if a stream type is attached to group
4586                 mLegacyStreamType = streamTypes[0];
4587                 for (final int streamType : streamTypes) {
4588                     if (streamType != AudioSystem.STREAM_DEFAULT
4589                             && streamType < AudioSystem.getNumStreamTypes()) {
4590                         mPublicStreamType = streamType;
4591                         break;
4592                     }
4593                 }
4594                 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
4595                 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
4596             } else if (!avg.getAudioAttributes().isEmpty()) {
4597                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
4598                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
4599             } else {
4600                 Log.e(TAG, "volume group: " + mAudioVolumeGroup.name()
4601                         + " has neither valid attributes nor valid stream types assigned");
4602                 return;
4603             }
4604             // Load volume indexes from data base
4605             readSettings();
4606         }
4607 
getLegacyStreamTypes()4608         public @NonNull int[] getLegacyStreamTypes() {
4609             return mAudioVolumeGroup.getLegacyStreamTypes();
4610         }
4611 
name()4612         public String name() {
4613             return mAudioVolumeGroup.name();
4614         }
4615 
getVolumeIndex()4616         public int getVolumeIndex() {
4617             return getIndex(getDeviceForVolume());
4618         }
4619 
setVolumeIndex(int index, int flags)4620         public void setVolumeIndex(int index, int flags) {
4621             if (mUseFixedVolume) {
4622                 return;
4623             }
4624             setVolumeIndex(index, getDeviceForVolume(), flags);
4625         }
4626 
setVolumeIndex(int index, int device, int flags)4627         private void setVolumeIndex(int index, int device, int flags) {
4628             // Set the volume index
4629             setVolumeIndexInt(index, device, flags);
4630 
4631             // Update local cache
4632             mIndexMap.put(device, index);
4633 
4634             // update data base - post a persist volume group msg
4635             sendMsg(mAudioHandler,
4636                     MSG_PERSIST_VOLUME_GROUP,
4637                     SENDMSG_QUEUE,
4638                     device,
4639                     0,
4640                     this,
4641                     PERSIST_DELAY);
4642         }
4643 
setVolumeIndexInt(int index, int device, int flags)4644         private void setVolumeIndexInt(int index, int device, int flags) {
4645             // Set the volume index
4646             AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
4647         }
4648 
getIndex(int device)4649         public int getIndex(int device) {
4650             synchronized (VolumeGroupState.class) {
4651                 int index = mIndexMap.get(device, -1);
4652                 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
4653                 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
4654             }
4655         }
4656 
hasIndexForDevice(int device)4657         public boolean hasIndexForDevice(int device) {
4658             synchronized (VolumeGroupState.class) {
4659                 return (mIndexMap.get(device, -1) != -1);
4660             }
4661         }
4662 
getMaxIndex()4663         public int getMaxIndex() {
4664             return mIndexMax;
4665         }
4666 
getMinIndex()4667         public int getMinIndex() {
4668             return mIndexMin;
4669         }
4670 
isValidLegacyStreamType()4671         private boolean isValidLegacyStreamType() {
4672             return (mLegacyStreamType != AudioSystem.STREAM_DEFAULT)
4673                     && (mLegacyStreamType < mStreamStates.length);
4674         }
4675 
applyAllVolumes()4676         public void applyAllVolumes() {
4677             synchronized (VolumeGroupState.class) {
4678                 int deviceForStream = AudioSystem.DEVICE_NONE;
4679                 int volumeIndexForStream = 0;
4680                 if (isValidLegacyStreamType()) {
4681                     // Prevent to apply settings twice when group is associated to public stream
4682                     deviceForStream = getDeviceForStream(mLegacyStreamType);
4683                     volumeIndexForStream = getStreamVolume(mLegacyStreamType);
4684                 }
4685                 // apply device specific volumes first
4686                 int index;
4687                 for (int i = 0; i < mIndexMap.size(); i++) {
4688                     final int device = mIndexMap.keyAt(i);
4689                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
4690                         index = mIndexMap.valueAt(i);
4691                         if (device == deviceForStream && volumeIndexForStream == index) {
4692                             continue;
4693                         }
4694                         if (DEBUG_VOL) {
4695                             Log.v(TAG, "applyAllVolumes: restore index " + index + " for group "
4696                                     + mAudioVolumeGroup.name() + " and device "
4697                                     + AudioSystem.getOutputDeviceName(device));
4698                         }
4699                         setVolumeIndexInt(index, device, 0 /*flags*/);
4700                     }
4701                 }
4702                 // apply default volume last: by convention , default device volume will be used
4703                 index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
4704                 if (DEBUG_VOL) {
4705                     Log.v(TAG, "applyAllVolumes: restore default device index " + index
4706                             + " for group " + mAudioVolumeGroup.name());
4707                 }
4708                 if (isValidLegacyStreamType()) {
4709                     int defaultStreamIndex = (mStreamStates[mLegacyStreamType]
4710                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10;
4711                     if (defaultStreamIndex == index) {
4712                         return;
4713                     }
4714                 }
4715                 setVolumeIndexInt(index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
4716             }
4717         }
4718 
persistVolumeGroup(int device)4719         private void persistVolumeGroup(int device) {
4720             if (mUseFixedVolume) {
4721                 return;
4722             }
4723             if (DEBUG_VOL) {
4724                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
4725                         + mAudioVolumeGroup.name()
4726                         + ", device " + AudioSystem.getOutputDeviceName(device)
4727                         + " and User=" + ActivityManager.getCurrentUser());
4728             }
4729             boolean success = Settings.System.putIntForUser(mContentResolver,
4730                     getSettingNameForDevice(device),
4731                     getIndex(device),
4732                     UserHandle.USER_CURRENT);
4733             if (!success) {
4734                 Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
4735             }
4736         }
4737 
readSettings()4738         public void readSettings() {
4739             synchronized (VolumeGroupState.class) {
4740                 // First clear previously loaded (previous user?) settings
4741                 mIndexMap.clear();
4742                 // force maximum volume on all streams if fixed volume property is set
4743                 if (mUseFixedVolume) {
4744                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
4745                     return;
4746                 }
4747                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
4748                     // retrieve current volume for device
4749                     // if no volume stored for current volume group and device, use default volume
4750                     // if default device, continue otherwise
4751                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
4752                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
4753                     int index;
4754                     String name = getSettingNameForDevice(device);
4755                     index = Settings.System.getIntForUser(
4756                             mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
4757                     if (index == -1) {
4758                         if (DEBUG_VOL) {
4759                             Log.e(TAG, "readSettings: No index stored for group "
4760                                     + mAudioVolumeGroup.name() + ", device " + name
4761                                     + ", User=" + ActivityManager.getCurrentUser());
4762                         }
4763                         continue;
4764                     }
4765                     if (DEBUG_VOL) {
4766                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
4767                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
4768                                  + ", User=" + ActivityManager.getCurrentUser());
4769                     }
4770                     mIndexMap.put(device, getValidIndex(index));
4771                 }
4772             }
4773         }
4774 
getValidIndex(int index)4775         private int getValidIndex(int index) {
4776             if (index < mIndexMin) {
4777                 return mIndexMin;
4778             } else if (mUseFixedVolume || index > mIndexMax) {
4779                 return mIndexMax;
4780             }
4781             return index;
4782         }
4783 
getSettingNameForDevice(int device)4784         public @NonNull String getSettingNameForDevice(int device) {
4785             final String suffix = AudioSystem.getOutputDeviceName(device);
4786             if (suffix.isEmpty()) {
4787                 return mAudioVolumeGroup.name();
4788             }
4789             return mAudioVolumeGroup.name() + "_" + AudioSystem.getOutputDeviceName(device);
4790         }
4791 
dump(PrintWriter pw)4792         private void dump(PrintWriter pw) {
4793             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
4794             pw.print("   Min: ");
4795             pw.println(mIndexMin);
4796             pw.print("   Max: ");
4797             pw.println(mIndexMax);
4798             pw.print("   Current: ");
4799             for (int i = 0; i < mIndexMap.size(); i++) {
4800                 if (i > 0) {
4801                     pw.print(", ");
4802                 }
4803                 final int device = mIndexMap.keyAt(i);
4804                 pw.print(Integer.toHexString(device));
4805                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
4806                         : AudioSystem.getOutputDeviceName(device);
4807                 if (!deviceName.isEmpty()) {
4808                     pw.print(" (");
4809                     pw.print(deviceName);
4810                     pw.print(")");
4811                 }
4812                 pw.print(": ");
4813                 pw.print(mIndexMap.valueAt(i));
4814             }
4815             pw.println();
4816             pw.print("   Devices: ");
4817             int n = 0;
4818             final int devices = getDeviceForVolume();
4819             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
4820                 if ((devices & device) == device) {
4821                     if (n++ > 0) {
4822                         pw.print(", ");
4823                     }
4824                     pw.print(AudioSystem.getOutputDeviceName(device));
4825                 }
4826             }
4827         }
4828     }
4829 
4830 
4831     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
4832     //  1 mScoclient OR mSafeMediaVolumeState
4833     //  2   mSetModeLock
4834     //  3     mSettingsLock
4835     //  4       VolumeStreamState.class
4836     private class VolumeStreamState {
4837         private final int mStreamType;
4838         private int mIndexMin;
4839         private int mIndexMax;
4840 
4841         private boolean mIsMuted;
4842         private String mVolumeIndexSettingName;
4843         private int mObservedDevices;
4844 
4845         private final SparseIntArray mIndexMap = new SparseIntArray(8);
4846         private final Intent mVolumeChanged;
4847         private final Intent mStreamDevicesChanged;
4848 
VolumeStreamState(String settingName, int streamType)4849         private VolumeStreamState(String settingName, int streamType) {
4850 
4851             mVolumeIndexSettingName = settingName;
4852 
4853             mStreamType = streamType;
4854             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
4855             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
4856             AudioSystem.initStreamVolume(streamType, mIndexMin / 10, mIndexMax / 10);
4857 
4858             readSettings();
4859             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
4860             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
4861             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
4862             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
4863         }
4864 
observeDevicesForStream_syncVSS(boolean checkOthers)4865         public int observeDevicesForStream_syncVSS(boolean checkOthers) {
4866             final int devices = AudioSystem.getDevicesForStream(mStreamType);
4867             if (devices == mObservedDevices) {
4868                 return devices;
4869             }
4870             final int prevDevices = mObservedDevices;
4871             mObservedDevices = devices;
4872             if (checkOthers) {
4873                 // one stream's devices have changed, check the others
4874                 observeDevicesForStreams(mStreamType);
4875             }
4876             // log base stream changes to the event log
4877             if (mStreamVolumeAlias[mStreamType] == mStreamType) {
4878                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
4879             }
4880             sendBroadcastToAll(mStreamDevicesChanged
4881                     .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, prevDevices)
4882                     .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, devices));
4883             return devices;
4884         }
4885 
getSettingNameForDevice(int device)4886         public @Nullable String getSettingNameForDevice(int device) {
4887             if (!hasValidSettingsName()) {
4888                 return null;
4889             }
4890             final String suffix = AudioSystem.getOutputDeviceName(device);
4891             if (suffix.isEmpty()) {
4892                 return mVolumeIndexSettingName;
4893             }
4894             return mVolumeIndexSettingName + "_" + suffix;
4895         }
4896 
hasValidSettingsName()4897         private boolean hasValidSettingsName() {
4898             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
4899         }
4900 
readSettings()4901         public void readSettings() {
4902             synchronized (mSettingsLock) {
4903                 synchronized (VolumeStreamState.class) {
4904                     // force maximum volume on all streams if fixed volume property is set
4905                     if (mUseFixedVolume) {
4906                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
4907                         return;
4908                     }
4909                     // do not read system stream volume from settings: this stream is always aliased
4910                     // to another stream type and its volume is never persisted. Values in settings can
4911                     // only be stale values
4912                     if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
4913                             (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
4914                         int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
4915                         if (mCameraSoundForced) {
4916                             index = mIndexMax;
4917                         }
4918                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
4919                         return;
4920                     }
4921                 }
4922             }
4923             synchronized (VolumeStreamState.class) {
4924                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
4925 
4926                     // retrieve current volume for device
4927                     // if no volume stored for current stream and device, use default volume if default
4928                     // device, continue otherwise
4929                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
4930                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
4931                     int index;
4932                     if (!hasValidSettingsName()) {
4933                         index = defaultIndex;
4934                     } else {
4935                         String name = getSettingNameForDevice(device);
4936                         index = Settings.System.getIntForUser(
4937                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
4938                     }
4939                     if (index == -1) {
4940                         continue;
4941                     }
4942 
4943                     mIndexMap.put(device, getValidIndex(10 * index));
4944                 }
4945             }
4946         }
4947 
getAbsoluteVolumeIndex(int index)4948         private int getAbsoluteVolumeIndex(int index) {
4949             /* Special handling for Bluetooth Absolute Volume scenario
4950              * If we send full audio gain, some accessories are too loud even at its lowest
4951              * volume. We are not able to enumerate all such accessories, so here is the
4952              * workaround from phone side.
4953              * Pre-scale volume at lowest volume steps 1 2 and 3.
4954              * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
4955              */
4956             if (index == 0) {
4957                 // 0% for volume 0
4958                 index = 0;
4959             } else if (index > 0 && index <= 3) {
4960                 // Pre-scale for volume steps 1 2 and 3
4961                 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
4962             } else {
4963                 // otherwise, full gain
4964                 index = (mIndexMax + 5) / 10;
4965             }
4966             return index;
4967         }
4968 
setStreamVolumeIndex(int index, int device)4969         private void setStreamVolumeIndex(int index, int device) {
4970             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
4971             // This allows RX path muting by the audio HAL only when explicitly muted but not when
4972             // index is just set to 0 to repect BT requirements
4973             if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 && !mIsMuted) {
4974                 index = 1;
4975             }
4976             AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
4977         }
4978 
4979         // must be called while synchronized VolumeStreamState.class
applyDeviceVolume_syncVSS(int device, boolean isAvrcpAbsVolSupported)4980         /*package*/ void applyDeviceVolume_syncVSS(int device, boolean isAvrcpAbsVolSupported) {
4981             int index;
4982             if (mIsMuted) {
4983                 index = 0;
4984             } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4985                     && isAvrcpAbsVolSupported) {
4986                 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
4987             } else if (mFullVolumeDevices.contains(device)) {
4988                 index = (mIndexMax + 5)/10;
4989             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
4990                 index = (mIndexMax + 5)/10;
4991             } else {
4992                 index = (getIndex(device) + 5)/10;
4993             }
4994             setStreamVolumeIndex(index, device);
4995         }
4996 
applyAllVolumes()4997         public void applyAllVolumes() {
4998             final boolean isAvrcpAbsVolSupported = mDeviceBroker.isAvrcpAbsoluteVolumeSupported();
4999             synchronized (VolumeStreamState.class) {
5000                 // apply device specific volumes first
5001                 int index;
5002                 for (int i = 0; i < mIndexMap.size(); i++) {
5003                     final int device = mIndexMap.keyAt(i);
5004                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
5005                         if (mIsMuted) {
5006                             index = 0;
5007                         } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
5008                                 && isAvrcpAbsVolSupported) {
5009                             index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
5010                         } else if (mFullVolumeDevices.contains(device)) {
5011                             index = (mIndexMax + 5)/10;
5012                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
5013                             index = (mIndexMax + 5)/10;
5014                         } else {
5015                             index = (mIndexMap.valueAt(i) + 5)/10;
5016                         }
5017                         setStreamVolumeIndex(index, device);
5018                     }
5019                 }
5020                 // apply default volume last: by convention , default device volume will be used
5021                 // by audio policy manager if no explicit volume is present for a given device type
5022                 if (mIsMuted) {
5023                     index = 0;
5024                 } else {
5025                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
5026                 }
5027                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
5028             }
5029         }
5030 
adjustIndex(int deltaIndex, int device, String caller)5031         public boolean adjustIndex(int deltaIndex, int device, String caller) {
5032             return setIndex(getIndex(device) + deltaIndex, device, caller);
5033         }
5034 
setIndex(int index, int device, String caller)5035         public boolean setIndex(int index, int device, String caller) {
5036             boolean changed;
5037             int oldIndex;
5038             synchronized (mSettingsLock) {
5039                 synchronized (VolumeStreamState.class) {
5040                     oldIndex = getIndex(device);
5041                     index = getValidIndex(index);
5042                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
5043                         index = mIndexMax;
5044                     }
5045                     mIndexMap.put(device, index);
5046 
5047                     changed = oldIndex != index;
5048                     // Apply change to all streams using this one as alias if:
5049                     // - the index actually changed OR
5050                     // - there is no volume index stored for this device on alias stream.
5051                     // If changing volume of current device, also change volume of current
5052                     // device on aliased stream
5053                     final boolean isCurrentDevice = (device == getDeviceForStream(mStreamType));
5054                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
5055                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5056                         final VolumeStreamState aliasStreamState = mStreamStates[streamType];
5057                         if (streamType != mStreamType &&
5058                                 mStreamVolumeAlias[streamType] == mStreamType &&
5059                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
5060                             final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
5061                             aliasStreamState.setIndex(scaledIndex, device, caller);
5062                             if (isCurrentDevice) {
5063                                 aliasStreamState.setIndex(scaledIndex,
5064                                         getDeviceForStream(streamType), caller);
5065                             }
5066                         }
5067                     }
5068                     // Mirror changes in SPEAKER ringtone volume on SCO when
5069                     if (changed && mStreamType == AudioSystem.STREAM_RING
5070                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
5071                         for (int i = 0; i < mIndexMap.size(); i++) {
5072                             int otherDevice = mIndexMap.keyAt(i);
5073                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
5074                                 mIndexMap.put(otherDevice, index);
5075                             }
5076                         }
5077                     }
5078                 }
5079             }
5080             if (changed) {
5081                 oldIndex = (oldIndex + 5) / 10;
5082                 index = (index + 5) / 10;
5083                 // log base stream changes to the event log
5084                 if (mStreamVolumeAlias[mStreamType] == mStreamType) {
5085                     if (caller == null) {
5086                         Log.w(TAG, "No caller for volume_changed event", new Throwable());
5087                     }
5088                     EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
5089                             caller);
5090                 }
5091                 // fire changed intents for all streams
5092                 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
5093                 mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
5094                 mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
5095                         mStreamVolumeAlias[mStreamType]);
5096                 sendBroadcastToAll(mVolumeChanged);
5097             }
5098             return changed;
5099         }
5100 
getIndex(int device)5101         public int getIndex(int device) {
5102             synchronized (VolumeStreamState.class) {
5103                 int index = mIndexMap.get(device, -1);
5104                 if (index == -1) {
5105                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
5106                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
5107                 }
5108                 return index;
5109             }
5110         }
5111 
hasIndexForDevice(int device)5112         public boolean hasIndexForDevice(int device) {
5113             synchronized (VolumeStreamState.class) {
5114                 return (mIndexMap.get(device, -1) != -1);
5115             }
5116         }
5117 
getMaxIndex()5118         public int getMaxIndex() {
5119             return mIndexMax;
5120         }
5121 
getMinIndex()5122         public int getMinIndex() {
5123             return mIndexMin;
5124         }
5125 
5126         /**
5127          * Copies all device/index pairs from the given VolumeStreamState after initializing
5128          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
5129          * has the same stream type as this instance.
5130          * @param srcStream
5131          * @param caller
5132          */
5133         // must be sync'd on mSettingsLock before VolumeStreamState.class
5134         @GuardedBy("VolumeStreamState.class")
setAllIndexes(VolumeStreamState srcStream, String caller)5135         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
5136             if (mStreamType == srcStream.mStreamType) {
5137                 return;
5138             }
5139             int srcStreamType = srcStream.getStreamType();
5140             // apply default device volume from source stream to all devices first in case
5141             // some devices are present in this stream state but not in source stream state
5142             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
5143             index = rescaleIndex(index, srcStreamType, mStreamType);
5144             for (int i = 0; i < mIndexMap.size(); i++) {
5145                 mIndexMap.put(mIndexMap.keyAt(i), index);
5146             }
5147             // Now apply actual volume for devices in source stream state
5148             SparseIntArray srcMap = srcStream.mIndexMap;
5149             for (int i = 0; i < srcMap.size(); i++) {
5150                 int device = srcMap.keyAt(i);
5151                 index = srcMap.valueAt(i);
5152                 index = rescaleIndex(index, srcStreamType, mStreamType);
5153 
5154                 setIndex(index, device, caller);
5155             }
5156         }
5157 
5158         // must be sync'd on mSettingsLock before VolumeStreamState.class
5159         @GuardedBy("VolumeStreamState.class")
setAllIndexesToMax()5160         public void setAllIndexesToMax() {
5161             for (int i = 0; i < mIndexMap.size(); i++) {
5162                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
5163             }
5164         }
5165 
5166         /**
5167          * Mute/unmute the stream
5168          * @param state the new mute state
5169          * @return true if the mute state was changed
5170          */
mute(boolean state)5171         public boolean mute(boolean state) {
5172             boolean changed = false;
5173             synchronized (VolumeStreamState.class) {
5174                 if (state != mIsMuted) {
5175                     changed = true;
5176                     mIsMuted = state;
5177 
5178                     // Set the new mute volume. This propagates the values to
5179                     // the audio system, otherwise the volume won't be changed
5180                     // at the lower level.
5181                     sendMsg(mAudioHandler,
5182                             MSG_SET_ALL_VOLUMES,
5183                             SENDMSG_QUEUE,
5184                             0,
5185                             0,
5186                             this, 0);
5187                 }
5188             }
5189             if (changed) {
5190                 // Stream mute changed, fire the intent.
5191                 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
5192                 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
5193                 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
5194                 sendBroadcastToAll(intent);
5195             }
5196             return changed;
5197         }
5198 
getStreamType()5199         public int getStreamType() {
5200             return mStreamType;
5201         }
5202 
checkFixedVolumeDevices()5203         public void checkFixedVolumeDevices() {
5204             final boolean isAvrcpAbsVolSupported = mDeviceBroker.isAvrcpAbsoluteVolumeSupported();
5205             synchronized (VolumeStreamState.class) {
5206                 // ignore settings for fixed volume devices: volume should always be at max or 0
5207                 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) {
5208                     for (int i = 0; i < mIndexMap.size(); i++) {
5209                         int device = mIndexMap.keyAt(i);
5210                         int index = mIndexMap.valueAt(i);
5211                         if (mFullVolumeDevices.contains(device)
5212                                 || (mFixedVolumeDevices.contains(device) && index != 0)) {
5213                             mIndexMap.put(device, mIndexMax);
5214                         }
5215                         applyDeviceVolume_syncVSS(device, isAvrcpAbsVolSupported);
5216                     }
5217                 }
5218             }
5219         }
5220 
getValidIndex(int index)5221         private int getValidIndex(int index) {
5222             if (index < mIndexMin) {
5223                 return mIndexMin;
5224             } else if (mUseFixedVolume || index > mIndexMax) {
5225                 return mIndexMax;
5226             }
5227 
5228             return index;
5229         }
5230 
dump(PrintWriter pw)5231         private void dump(PrintWriter pw) {
5232             pw.print("   Muted: ");
5233             pw.println(mIsMuted);
5234             pw.print("   Min: ");
5235             pw.println((mIndexMin + 5) / 10);
5236             pw.print("   Max: ");
5237             pw.println((mIndexMax + 5) / 10);
5238             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
5239             pw.print("   Current: ");
5240             for (int i = 0; i < mIndexMap.size(); i++) {
5241                 if (i > 0) {
5242                     pw.print(", ");
5243                 }
5244                 final int device = mIndexMap.keyAt(i);
5245                 pw.print(Integer.toHexString(device));
5246                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
5247                         : AudioSystem.getOutputDeviceName(device);
5248                 if (!deviceName.isEmpty()) {
5249                     pw.print(" (");
5250                     pw.print(deviceName);
5251                     pw.print(")");
5252                 }
5253                 pw.print(": ");
5254                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
5255                 pw.print(index);
5256             }
5257             pw.println();
5258             pw.print("   Devices: ");
5259             final int devices = getDevicesForStream(mStreamType);
5260             int device, i = 0, n = 0;
5261             // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive
5262             // (the default device is not returned by getDevicesForStream)
5263             while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) {
5264                 if ((devices & device) != 0) {
5265                     if (n++ > 0) {
5266                         pw.print(", ");
5267                     }
5268                     pw.print(AudioSystem.getOutputDeviceName(device));
5269                 }
5270                 i++;
5271             }
5272         }
5273     }
5274 
5275     /** Thread that handles native AudioSystem control. */
5276     private class AudioSystemThread extends Thread {
AudioSystemThread()5277         AudioSystemThread() {
5278             super("AudioService");
5279         }
5280 
5281         @Override
run()5282         public void run() {
5283             // Set this thread up so the handler will work on it
5284             Looper.prepare();
5285 
5286             synchronized(AudioService.this) {
5287                 mAudioHandler = new AudioHandler();
5288 
5289                 // Notify that the handler has been created
5290                 AudioService.this.notify();
5291             }
5292 
5293             // Listen for volume change requests that are set by VolumePanel
5294             Looper.loop();
5295         }
5296     }
5297 
5298     private static final class DeviceVolumeUpdate {
5299         final int mStreamType;
5300         final int mDevice;
5301         final @NonNull String mCaller;
5302         private static final int NO_NEW_INDEX = -2049;
5303         private final int mVssVolIndex;
5304 
5305         // Constructor with volume index, meant to cause this volume to be set and applied for the
5306         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)5307         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
5308             mStreamType = streamType;
5309             mVssVolIndex = vssVolIndex;
5310             mDevice = device;
5311             mCaller = caller;
5312         }
5313 
5314         // Constructor with no volume index, meant to cause re-apply of volume for the given
5315         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)5316         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
5317             mStreamType = streamType;
5318             mVssVolIndex = NO_NEW_INDEX;
5319             mDevice = device;
5320             mCaller = caller;
5321         }
5322 
hasVolumeIndex()5323         boolean hasVolumeIndex() {
5324             return mVssVolIndex != NO_NEW_INDEX;
5325         }
5326 
getVolumeIndex()5327         int getVolumeIndex() throws IllegalStateException {
5328             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
5329             return mVssVolIndex;
5330         }
5331     }
5332 
5333     /** only public for mocking/spying, do not call outside of AudioService */
5334     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)5335     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
5336                                                 String caller) {
5337         sendMsg(mAudioHandler,
5338                 MSG_SET_DEVICE_STREAM_VOLUME,
5339                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
5340                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
5341                 0 /*delay*/);
5342     }
5343 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)5344     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
5345         sendMsg(mAudioHandler,
5346                 MSG_SET_DEVICE_STREAM_VOLUME,
5347                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
5348                 new DeviceVolumeUpdate(streamType, device, caller),
5349                 0 /*delay*/);
5350     }
5351 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)5352     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
5353         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
5354         if (update.hasVolumeIndex()) {
5355             final int index = update.getVolumeIndex();
5356             streamState.setIndex(index, update.mDevice, update.mCaller);
5357             sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller + " dev:0x"
5358                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
5359         } else {
5360             sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller
5361                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
5362         }
5363         setDeviceVolume(streamState, update.mDevice);
5364     }
5365 
setDeviceVolume(VolumeStreamState streamState, int device)5366     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
5367 
5368         final boolean isAvrcpAbsVolSupported = mDeviceBroker.isAvrcpAbsoluteVolumeSupported();
5369 
5370         synchronized (VolumeStreamState.class) {
5371             // Apply volume
5372             streamState.applyDeviceVolume_syncVSS(device, isAvrcpAbsVolSupported);
5373 
5374             // Apply change to all streams using this one as alias
5375             int numStreamTypes = AudioSystem.getNumStreamTypes();
5376             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5377                 if (streamType != streamState.mStreamType &&
5378                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
5379                     // Make sure volume is also maxed out on A2DP device for aliased stream
5380                     // that may have a different device selected
5381                     int streamDevice = getDeviceForStream(streamType);
5382                     if ((device != streamDevice) && isAvrcpAbsVolSupported
5383                             && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) {
5384                         mStreamStates[streamType].applyDeviceVolume_syncVSS(device,
5385                                 isAvrcpAbsVolSupported);
5386                     }
5387                     mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice,
5388                             isAvrcpAbsVolSupported);
5389                 }
5390             }
5391         }
5392         // Post a persist volume msg
5393         sendMsg(mAudioHandler,
5394                 MSG_PERSIST_VOLUME,
5395                 SENDMSG_QUEUE,
5396                 device,
5397                 0,
5398                 streamState,
5399                 PERSIST_DELAY);
5400 
5401     }
5402 
5403     /** Handles internal volume messages in separate volume thread. */
5404     private class AudioHandler extends Handler {
5405 
setAllVolumes(VolumeStreamState streamState)5406         private void setAllVolumes(VolumeStreamState streamState) {
5407 
5408             // Apply volume
5409             streamState.applyAllVolumes();
5410 
5411             // Apply change to all streams using this one as alias
5412             int numStreamTypes = AudioSystem.getNumStreamTypes();
5413             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5414                 if (streamType != streamState.mStreamType &&
5415                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
5416                     mStreamStates[streamType].applyAllVolumes();
5417                 }
5418             }
5419         }
5420 
persistVolume(VolumeStreamState streamState, int device)5421         private void persistVolume(VolumeStreamState streamState, int device) {
5422             if (mUseFixedVolume) {
5423                 return;
5424             }
5425             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
5426                 return;
5427             }
5428             if (streamState.hasValidSettingsName()) {
5429                 System.putIntForUser(mContentResolver,
5430                         streamState.getSettingNameForDevice(device),
5431                         (streamState.getIndex(device) + 5)/ 10,
5432                         UserHandle.USER_CURRENT);
5433             }
5434         }
5435 
persistRingerMode(int ringerMode)5436         private void persistRingerMode(int ringerMode) {
5437             if (mUseFixedVolume) {
5438                 return;
5439             }
5440             Settings.Global.putInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
5441         }
5442 
onPersistSafeVolumeState(int state)5443         private void onPersistSafeVolumeState(int state) {
5444             Settings.Global.putInt(mContentResolver,
5445                     Settings.Global.AUDIO_SAFE_VOLUME_STATE,
5446                     state);
5447         }
5448 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)5449         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
5450                 @AudioManager.VolumeAdjustment int direction) {
5451             try {
5452                 apc.notifyVolumeAdjust(direction);
5453             } catch(Exception e) {
5454                 // nothing we can do about this. Do not log error, too much potential for spam
5455             }
5456         }
5457 
5458         @Override
handleMessage(Message msg)5459         public void handleMessage(Message msg) {
5460             switch (msg.what) {
5461 
5462                 case MSG_SET_DEVICE_VOLUME:
5463                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
5464                     break;
5465 
5466                 case MSG_SET_ALL_VOLUMES:
5467                     setAllVolumes((VolumeStreamState) msg.obj);
5468                     break;
5469 
5470                 case MSG_PERSIST_VOLUME:
5471                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
5472                     break;
5473 
5474                 case MSG_PERSIST_VOLUME_GROUP:
5475                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
5476                     vgs.persistVolumeGroup(msg.arg1);
5477                     break;
5478 
5479                 case MSG_PERSIST_RINGER_MODE:
5480                     // note that the value persisted is the current ringer mode, not the
5481                     // value of ringer mode as of the time the request was made to persist
5482                     persistRingerMode(getRingerModeInternal());
5483                     break;
5484 
5485                 case MSG_AUDIO_SERVER_DIED:
5486                     onAudioServerDied();
5487                     break;
5488 
5489                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
5490                     onDispatchAudioServerStateChange(msg.arg1 == 1);
5491                     break;
5492 
5493                 case MSG_UNLOAD_SOUND_EFFECTS:
5494                     mSfxHelper.unloadSoundEffects();
5495                     break;
5496 
5497                 case MSG_LOAD_SOUND_EFFECTS:
5498                 {
5499                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
5500                     if (mSystemReady) {
5501                         mSfxHelper.loadSoundEffects(reply);
5502                     } else {
5503                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
5504                         if (reply != null) {
5505                             reply.run(false);
5506                         }
5507                     }
5508                 }
5509                     break;
5510 
5511                 case MSG_PLAY_SOUND_EFFECT:
5512                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
5513                     break;
5514 
5515                 case MSG_SET_FORCE_USE:
5516                 {
5517                     final String eventSource = (String) msg.obj;
5518                     final int useCase = msg.arg1;
5519                     final int config = msg.arg2;
5520                     if (useCase == AudioSystem.FOR_MEDIA) {
5521                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
5522                                 + eventSource);
5523                         break;
5524                     }
5525                     sForceUseLogger.log(
5526                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
5527                     AudioSystem.setForceUse(useCase, config);
5528                 }
5529                     break;
5530 
5531                 case MSG_DISABLE_AUDIO_FOR_UID:
5532                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
5533                             msg.arg2 /* uid */);
5534                     mAudioEventWakeLock.release();
5535                     break;
5536 
5537                 case MSG_CHECK_MUSIC_ACTIVE:
5538                     onCheckMusicActive((String) msg.obj);
5539                     break;
5540 
5541                 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED:
5542                 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:
5543                     onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED),
5544                             (String) msg.obj);
5545                     break;
5546                 case MSG_PERSIST_SAFE_VOLUME_STATE:
5547                     onPersistSafeVolumeState(msg.arg1);
5548                     break;
5549 
5550                 case MSG_SYSTEM_READY:
5551                     onSystemReady();
5552                     break;
5553 
5554                 case MSG_INDICATE_SYSTEM_READY:
5555                     onIndicateSystemReady();
5556                     break;
5557 
5558                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
5559                     onAccessoryPlugMediaUnmute(msg.arg1);
5560                     break;
5561 
5562                 case MSG_PERSIST_MUSIC_ACTIVE_MS:
5563                     final int musicActiveMs = msg.arg1;
5564                     Settings.Secure.putIntForUser(mContentResolver,
5565                             Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, musicActiveMs,
5566                             UserHandle.USER_CURRENT);
5567                     break;
5568 
5569                 case MSG_UNMUTE_STREAM:
5570                     onUnmuteStream(msg.arg1, msg.arg2);
5571                     break;
5572 
5573                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
5574                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
5575                     break;
5576 
5577                 case MSG_NOTIFY_VOL_EVENT:
5578                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
5579                     break;
5580 
5581                 case MSG_ENABLE_SURROUND_FORMATS:
5582                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
5583                     break;
5584 
5585                 case MSG_UPDATE_RINGER_MODE:
5586                     onUpdateRingerModeServiceInt();
5587                     break;
5588 
5589                 case MSG_SET_DEVICE_STREAM_VOLUME:
5590                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
5591                     break;
5592 
5593                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
5594                     onObserveDevicesForAllStreams();
5595                     break;
5596 
5597                 case MSG_HDMI_VOLUME_CHECK:
5598                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
5599                     break;
5600 
5601                 case MSG_PLAYBACK_CONFIG_CHANGE:
5602                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
5603                     break;
5604             }
5605         }
5606     }
5607 
5608     private class SettingsObserver extends ContentObserver {
5609 
SettingsObserver()5610         SettingsObserver() {
5611             super(new Handler());
5612             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
5613                     Settings.Global.ZEN_MODE), false, this);
5614             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
5615                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
5616             mContentResolver.registerContentObserver(Settings.System.getUriFor(
5617                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
5618             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
5619                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
5620             mContentResolver.registerContentObserver(Settings.System.getUriFor(
5621                     Settings.System.MASTER_MONO), false, this);
5622             mContentResolver.registerContentObserver(Settings.System.getUriFor(
5623                     Settings.System.MASTER_BALANCE), false, this);
5624 
5625             mEncodedSurroundMode = Settings.Global.getInt(
5626                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
5627                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
5628             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
5629                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
5630 
5631             mEnabledSurroundFormats = Settings.Global.getString(
5632                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
5633             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
5634                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
5635 
5636             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
5637                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
5638             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
5639                     Settings.Secure.RTT_CALLING_MODE), false, this);
5640         }
5641 
5642         @Override
onChange(boolean selfChange)5643         public void onChange(boolean selfChange) {
5644             super.onChange(selfChange);
5645             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
5646             //       However there appear to be some missing locks around mRingerAndZenModeMutedStreams
5647             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
5648             //       mRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
5649             synchronized (mSettingsLock) {
5650                 if (updateRingerAndZenModeAffectedStreams()) {
5651                     /*
5652                      * Ensure all stream types that should be affected by ringer mode
5653                      * are in the proper state.
5654                      */
5655                     setRingerModeInt(getRingerModeInternal(), false);
5656                 }
5657                 readDockAudioSettings(mContentResolver);
5658                 updateMasterMono(mContentResolver);
5659                 updateMasterBalance(mContentResolver);
5660                 updateEncodedSurroundOutput();
5661                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
5662                 updateAssistantUId(false);
5663                 updateRttEanbled(mContentResolver);
5664             }
5665         }
5666 
updateEncodedSurroundOutput()5667         private void updateEncodedSurroundOutput() {
5668             int newSurroundMode = Settings.Global.getInt(
5669                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
5670                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
5671             // Did it change?
5672             if (mEncodedSurroundMode != newSurroundMode) {
5673                 // Send to AudioPolicyManager
5674                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
5675                 mDeviceBroker.toggleHdmiIfConnected_Async();
5676                 mEncodedSurroundMode = newSurroundMode;
5677                 mSurroundModeChanged = true;
5678             } else {
5679                 mSurroundModeChanged = false;
5680             }
5681         }
5682     }
5683 
avrcpSupportsAbsoluteVolume(String address, boolean support)5684     public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
5685         // address is not used for now, but may be used when multiple a2dp devices are supported
5686         sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
5687                 + address + " support=" + support));
5688         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
5689         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
5690                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
5691                     mStreamStates[AudioSystem.STREAM_MUSIC], 0);
5692     }
5693 
5694     /**
5695      * @return true if there is currently a registered dynamic mixing policy that affects media
5696      * and is not a render + loopback policy
5697      */
5698     // only public for mocking/spying
5699     @VisibleForTesting
hasMediaDynamicPolicy()5700     public boolean hasMediaDynamicPolicy() {
5701         synchronized (mAudioPolicies) {
5702             if (mAudioPolicies.isEmpty()) {
5703                 return false;
5704             }
5705             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
5706             for (AudioPolicyProxy app : appColl) {
5707                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
5708                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
5709                     return true;
5710                 }
5711             }
5712             return false;
5713         }
5714     }
5715 
checkMusicActive(int deviceType, String caller)5716     /*package*/ void checkMusicActive(int deviceType, String caller) {
5717         if (mSafeMediaVolumeDevices.contains(deviceType)) {
5718             sendMsg(mAudioHandler,
5719                     MSG_CHECK_MUSIC_ACTIVE,
5720                     SENDMSG_REPLACE,
5721                     0,
5722                     0,
5723                     caller,
5724                     MUSIC_ACTIVE_POLL_PERIOD_MS);
5725         }
5726     }
5727 
5728     /**
5729      * Receiver for misc intent broadcasts the Phone app cares about.
5730      */
5731     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
5732         @Override
onReceive(Context context, Intent intent)5733         public void onReceive(Context context, Intent intent) {
5734             final String action = intent.getAction();
5735             int outDevice;
5736             int inDevice;
5737             int state;
5738 
5739             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
5740                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
5741                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
5742                 int config;
5743                 switch (dockState) {
5744                     case Intent.EXTRA_DOCK_STATE_DESK:
5745                         config = AudioSystem.FORCE_BT_DESK_DOCK;
5746                         break;
5747                     case Intent.EXTRA_DOCK_STATE_CAR:
5748                         config = AudioSystem.FORCE_BT_CAR_DOCK;
5749                         break;
5750                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
5751                         config = AudioSystem.FORCE_ANALOG_DOCK;
5752                         break;
5753                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
5754                         config = AudioSystem.FORCE_DIGITAL_DOCK;
5755                         break;
5756                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
5757                     default:
5758                         config = AudioSystem.FORCE_NONE;
5759                 }
5760                 // Low end docks have a menu to enable or disable audio
5761                 // (see mDockAudioMediaEnabled)
5762                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
5763                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
5764                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
5765                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
5766                             "ACTION_DOCK_EVENT intent");
5767                 }
5768                 mDockState = dockState;
5769             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
5770                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
5771                 mDeviceBroker.receiveBtEvent(intent);
5772             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
5773                 if (mMonitorRotation) {
5774                     RotationHelper.enable();
5775                 }
5776                 AudioSystem.setParameters("screen_state=on");
5777             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
5778                 if (mMonitorRotation) {
5779                     //reduce wakeups (save current) by only listening when display is on
5780                     RotationHelper.disable();
5781                 }
5782                 AudioSystem.setParameters("screen_state=off");
5783             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
5784                 handleConfigurationChanged(context);
5785             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
5786                 if (mUserSwitchedReceived) {
5787                     // attempt to stop music playback for background user except on first user
5788                     // switch (i.e. first boot)
5789                     mDeviceBroker.postBroadcastBecomingNoisy();
5790                 }
5791                 mUserSwitchedReceived = true;
5792                 // the current audio focus owner is no longer valid
5793                 mMediaFocusControl.discardAudioFocusOwner();
5794 
5795                 // load volume settings for new user
5796                 readAudioSettings(true /*userSwitch*/);
5797                 // preserve STREAM_MUSIC volume from one user to the next.
5798                 sendMsg(mAudioHandler,
5799                         MSG_SET_ALL_VOLUMES,
5800                         SENDMSG_QUEUE,
5801                         0,
5802                         0,
5803                         mStreamStates[AudioSystem.STREAM_MUSIC], 0);
5804             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
5805                 // Disable audio recording for the background user/profile
5806                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
5807                 if (userId >= 0) {
5808                     // TODO Kill recording streams instead of killing processes holding permission
5809                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
5810                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
5811                 }
5812                 UserManagerService.getInstance().setUserRestriction(
5813                         UserManager.DISALLOW_RECORD_AUDIO, true, userId);
5814             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
5815                 // Enable audio recording for foreground user/profile
5816                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
5817                 UserManagerService.getInstance().setUserRestriction(
5818                         UserManager.DISALLOW_RECORD_AUDIO, false, userId);
5819             } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
5820                 state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
5821                 if (state == BluetoothAdapter.STATE_OFF ||
5822                         state == BluetoothAdapter.STATE_TURNING_OFF) {
5823                     mDeviceBroker.disconnectAllBluetoothProfiles();
5824                 }
5825             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
5826                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
5827                 handleAudioEffectBroadcast(context, intent);
5828             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
5829                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
5830                 final String[] suspendedPackages =
5831                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
5832                 if (suspendedPackages == null || suspendedUids == null
5833                         || suspendedPackages.length != suspendedUids.length) {
5834                     return;
5835                 }
5836                 for (int i = 0; i < suspendedUids.length; i++) {
5837                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
5838                         mMediaFocusControl.noFocusForSuspendedApp(
5839                                 suspendedPackages[i], suspendedUids[i]);
5840                     }
5841                 }
5842             }
5843         }
5844     } // end class AudioServiceBroadcastReceiver
5845 
5846     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
5847 
5848         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)5849         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
5850                 Bundle prevRestrictions) {
5851             // Update mic mute state.
5852             {
5853                 final boolean wasRestricted =
5854                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
5855                 final boolean isRestricted =
5856                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
5857                 if (wasRestricted != isRestricted) {
5858                     mMicMuteFromRestrictions = isRestricted;
5859                     setMicrophoneMuteNoCallerCheck(userId);
5860                 }
5861             }
5862 
5863             // Update speaker mute state.
5864             {
5865                 final boolean wasRestricted =
5866                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
5867                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
5868                 final boolean isRestricted =
5869                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
5870                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
5871                 if (wasRestricted != isRestricted) {
5872                     setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
5873                 }
5874             }
5875         }
5876     } // end class AudioServiceUserRestrictionsListener
5877 
handleAudioEffectBroadcast(Context context, Intent intent)5878     private void handleAudioEffectBroadcast(Context context, Intent intent) {
5879         String target = intent.getPackage();
5880         if (target != null) {
5881             Log.w(TAG, "effect broadcast already targeted to " + target);
5882             return;
5883         }
5884         intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
5885         // TODO this should target a user-selected panel
5886         List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
5887                 intent, 0 /* flags */);
5888         if (ril != null && ril.size() != 0) {
5889             ResolveInfo ri = ril.get(0);
5890             if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
5891                 intent.setPackage(ri.activityInfo.packageName);
5892                 context.sendBroadcastAsUser(intent, UserHandle.ALL);
5893                 return;
5894             }
5895         }
5896         Log.w(TAG, "couldn't find receiver package for effect intent");
5897     }
5898 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)5899     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
5900         PackageManager pm = mContext.getPackageManager();
5901         // Find the home activity of the user. It should not be killed to avoid expensive restart,
5902         // when the user switches back. For managed profiles, we should kill all recording apps
5903         ComponentName homeActivityName = null;
5904         if (!oldUser.isManagedProfile()) {
5905             homeActivityName = LocalServices.getService(
5906                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
5907         }
5908         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
5909         List<PackageInfo> packages;
5910         try {
5911             packages = AppGlobals.getPackageManager()
5912                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
5913         } catch (RemoteException e) {
5914             throw new AndroidRuntimeException(e);
5915         }
5916         for (int j = packages.size() - 1; j >= 0; j--) {
5917             PackageInfo pkg = packages.get(j);
5918             // Skip system processes
5919             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
5920                 continue;
5921             }
5922             // Skip packages that have permission to interact across users
5923             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
5924                     == PackageManager.PERMISSION_GRANTED) {
5925                 continue;
5926             }
5927             if (homeActivityName != null
5928                     && pkg.packageName.equals(homeActivityName.getPackageName())
5929                     && pkg.applicationInfo.isSystemApp()) {
5930                 continue;
5931             }
5932             try {
5933                 final int uid = pkg.applicationInfo.uid;
5934                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
5935                         UserHandle.getUserId(uid),
5936                         "killBackgroundUserProcessesWithAudioRecordPermission");
5937             } catch (RemoteException e) {
5938                 Log.w(TAG, "Error calling killUid", e);
5939             }
5940         }
5941     }
5942 
5943 
5944     //==========================================================================================
5945     // Audio Focus
5946     //==========================================================================================
5947     /**
5948      * Returns whether a focus request is eligible to force ducking.
5949      * Will return true if:
5950      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
5951      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
5952      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
5953      * - the uid of the requester is a known accessibility service or root.
5954      * @param aa AudioAttributes of the focus request
5955      * @param uid uid of the focus requester
5956      * @return true if ducking is to be forced
5957      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)5958     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
5959             int request, int uid) {
5960         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
5961                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
5962             return false;
5963         }
5964         final Bundle extraInfo = aa.getBundle();
5965         if (extraInfo == null ||
5966                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
5967             return false;
5968         }
5969         if (uid == 0) {
5970             return true;
5971         }
5972         synchronized (mAccessibilityServiceUidsLock) {
5973             if (mAccessibilityServiceUids != null) {
5974                 int callingUid = Binder.getCallingUid();
5975                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
5976                     if (mAccessibilityServiceUids[i] == callingUid) {
5977                         return true;
5978                     }
5979                 }
5980             }
5981         }
5982         return false;
5983     }
5984 
requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb, int sdk)5985     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
5986             IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
5987             IAudioPolicyCallback pcb, int sdk) {
5988         // permission checks
5989         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
5990             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
5991                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
5992                             android.Manifest.permission.MODIFY_PHONE_STATE)) {
5993                     Log.e(TAG, "Invalid permission to (un)lock audio focus", new Exception());
5994                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
5995                 }
5996             } else {
5997                 // only a registered audio policy can be used to lock focus
5998                 synchronized (mAudioPolicies) {
5999                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
6000                         Log.e(TAG, "Invalid unregistered AudioPolicy to (un)lock audio focus");
6001                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
6002                     }
6003                 }
6004             }
6005         }
6006 
6007         if (callingPackageName == null || clientId == null || aa == null) {
6008             Log.e(TAG, "Invalid null parameter to request audio focus");
6009             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
6010         }
6011 
6012         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
6013                 clientId, callingPackageName, flags, sdk,
6014                 forceFocusDuckingForAccessibility(aa, durationHint, Binder.getCallingUid()));
6015     }
6016 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)6017     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
6018             String callingPackageName) {
6019         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
6020     }
6021 
unregisterAudioFocusClient(String clientId)6022     public void unregisterAudioFocusClient(String clientId) {
6023         mMediaFocusControl.unregisterAudioFocusClient(clientId);
6024     }
6025 
getCurrentAudioFocus()6026     public int getCurrentAudioFocus() {
6027         return mMediaFocusControl.getCurrentAudioFocus();
6028     }
6029 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)6030     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
6031         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
6032     }
6033 
6034     /** only public for mocking/spying, do not call outside of AudioService */
6035     @VisibleForTesting
hasAudioFocusUsers()6036     public boolean hasAudioFocusUsers() {
6037         return mMediaFocusControl.hasAudioFocusUsers();
6038     }
6039 
6040     //==========================================================================================
readCameraSoundForced()6041     private boolean readCameraSoundForced() {
6042         return SystemProperties.getBoolean("audio.camerasound.force", false) ||
6043                 mContext.getResources().getBoolean(
6044                         com.android.internal.R.bool.config_camera_sound_forced);
6045     }
6046 
6047     //==========================================================================================
6048     // Device orientation
6049     //==========================================================================================
6050     /**
6051      * Handles device configuration changes that may map to a change in rotation.
6052      * Monitoring rotation is optional, and is defined by the definition and value
6053      * of the "ro.audio.monitorRotation" system property.
6054      */
handleConfigurationChanged(Context context)6055     private void handleConfigurationChanged(Context context) {
6056         try {
6057             // reading new configuration "safely" (i.e. under try catch) in case anything
6058             // goes wrong.
6059             Configuration config = context.getResources().getConfiguration();
6060             sendMsg(mAudioHandler,
6061                     MSG_CONFIGURE_SAFE_MEDIA_VOLUME,
6062                     SENDMSG_REPLACE,
6063                     0,
6064                     0,
6065                     TAG,
6066                     0);
6067 
6068             boolean cameraSoundForced = readCameraSoundForced();
6069             synchronized (mSettingsLock) {
6070                 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced);
6071                 mCameraSoundForced = cameraSoundForced;
6072                 if (cameraSoundForcedChanged) {
6073                     if (!mIsSingleVolume) {
6074                         synchronized (VolumeStreamState.class) {
6075                             VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
6076                             if (cameraSoundForced) {
6077                                 s.setAllIndexesToMax();
6078                                 mRingerModeAffectedStreams &=
6079                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6080                             } else {
6081                                 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG);
6082                                 mRingerModeAffectedStreams |=
6083                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6084                             }
6085                         }
6086                         // take new state into account for streams muted by ringer mode
6087                         setRingerModeInt(getRingerModeInternal(), false);
6088                     }
6089                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
6090                             cameraSoundForced ?
6091                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
6092                             "handleConfigurationChanged");
6093                     sendMsg(mAudioHandler,
6094                             MSG_SET_ALL_VOLUMES,
6095                             SENDMSG_QUEUE,
6096                             0,
6097                             0,
6098                             mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
6099 
6100                 }
6101             }
6102             mVolumeController.setLayoutDirection(config.getLayoutDirection());
6103         } catch (Exception e) {
6104             Log.e(TAG, "Error handling configuration change: ", e);
6105         }
6106     }
6107 
6108     @Override
setRingtonePlayer(IRingtonePlayer player)6109     public void setRingtonePlayer(IRingtonePlayer player) {
6110         mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);
6111         mRingtonePlayer = player;
6112     }
6113 
6114     @Override
getRingtonePlayer()6115     public IRingtonePlayer getRingtonePlayer() {
6116         return mRingtonePlayer;
6117     }
6118 
6119     @Override
startWatchingRoutes(IAudioRoutesObserver observer)6120     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
6121         return mDeviceBroker.startWatchingRoutes(observer);
6122     }
6123 
6124 
6125     //==========================================================================================
6126     // Safe media volume management.
6127     // MUSIC stream volume level is limited when headphones are connected according to safety
6128     // regulation. When the user attempts to raise the volume above the limit, a warning is
6129     // displayed and the user has to acknowlegde before the volume is actually changed.
6130     // The volume index corresponding to the limit is stored in config_safe_media_volume_index
6131     // property. Platforms with a different limit must set this property accordingly in their
6132     // overlay.
6133     //==========================================================================================
6134 
6135     // mSafeMediaVolumeState indicates whether the media volume is limited over headphones.
6136     // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected
6137     // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or
6138     // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it
6139     // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume()
6140     // (when user opts out).
6141     private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
6142     private static final int SAFE_MEDIA_VOLUME_DISABLED = 1;
6143     private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2;  // confirmed
6144     private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3;  // unconfirmed
6145     private int mSafeMediaVolumeState;
6146     private final Object mSafeMediaVolumeStateLock = new Object();
6147 
6148     private int mMcc = 0;
6149     // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
6150     private int mSafeMediaVolumeIndex;
6151     // mSafeUsbMediaVolumeDbfs is the cached value of the config_safe_media_volume_usb_mB
6152     // property, divided by 100.0.
6153     private float mSafeUsbMediaVolumeDbfs;
6154     // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index
6155     // corresponding to a gain of mSafeUsbMediaVolumeDbfs (defaulting to -37dB) in audio
6156     // flinger mixer.
6157     // We remove -22 dBs from the theoretical -15dB to account for the EQ + bass boost
6158     // amplification when both effects are on with all band gains at maximum.
6159     // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when
6160     // the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
6161     private int mSafeUsbMediaVolumeIndex;
6162     // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
6163     /*package*/ final Set<Integer> mSafeMediaVolumeDevices = new HashSet<>(
6164             Arrays.asList(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
6165                     AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, AudioSystem.DEVICE_OUT_USB_HEADSET));
6166     // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
6167     // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
6168     // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
6169     private int mMusicActiveMs;
6170     private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
6171     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
6172     private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
6173 
safeMediaVolumeIndex(int device)6174     private int safeMediaVolumeIndex(int device) {
6175         if (!mSafeMediaVolumeDevices.contains(device)) {
6176             return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
6177         }
6178         if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
6179             return mSafeUsbMediaVolumeIndex;
6180         } else {
6181             return mSafeMediaVolumeIndex;
6182         }
6183     }
6184 
setSafeMediaVolumeEnabled(boolean on, String caller)6185     private void setSafeMediaVolumeEnabled(boolean on, String caller) {
6186         synchronized (mSafeMediaVolumeStateLock) {
6187             if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
6188                     (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
6189                 if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
6190                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
6191                     enforceSafeMediaVolume(caller);
6192                 } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) {
6193                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
6194                     mMusicActiveMs = 1;  // nonzero = confirmed
6195                     saveMusicActiveMs();
6196                     sendMsg(mAudioHandler,
6197                             MSG_CHECK_MUSIC_ACTIVE,
6198                             SENDMSG_REPLACE,
6199                             0,
6200                             0,
6201                             caller,
6202                             MUSIC_ACTIVE_POLL_PERIOD_MS);
6203                 }
6204             }
6205         }
6206     }
6207 
enforceSafeMediaVolume(String caller)6208     private void enforceSafeMediaVolume(String caller) {
6209         VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
6210         Set<Integer> devices = mSafeMediaVolumeDevices;
6211 
6212         for (int device : devices) {
6213             int index = streamState.getIndex(device);
6214             if (index > safeMediaVolumeIndex(device)) {
6215                 streamState.setIndex(safeMediaVolumeIndex(device), device, caller);
6216                 sendMsg(mAudioHandler,
6217                         MSG_SET_DEVICE_VOLUME,
6218                         SENDMSG_QUEUE,
6219                         device,
6220                         0,
6221                         streamState,
6222                         0);
6223             }
6224         }
6225     }
6226 
checkSafeMediaVolume(int streamType, int index, int device)6227     private boolean checkSafeMediaVolume(int streamType, int index, int device) {
6228         synchronized (mSafeMediaVolumeStateLock) {
6229             if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)
6230                     && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC)
6231                     && (mSafeMediaVolumeDevices.contains(device))
6232                     && (index > safeMediaVolumeIndex(device))) {
6233                 return false;
6234             }
6235             return true;
6236         }
6237     }
6238 
6239     @Override
disableSafeMediaVolume(String callingPackage)6240     public void disableSafeMediaVolume(String callingPackage) {
6241         enforceVolumeController("disable the safe media volume");
6242         synchronized (mSafeMediaVolumeStateLock) {
6243             setSafeMediaVolumeEnabled(false, callingPackage);
6244             if (mPendingVolumeCommand != null) {
6245                 onSetStreamVolume(mPendingVolumeCommand.mStreamType,
6246                                   mPendingVolumeCommand.mIndex,
6247                                   mPendingVolumeCommand.mFlags,
6248                                   mPendingVolumeCommand.mDevice,
6249                                   callingPackage);
6250                 mPendingVolumeCommand = null;
6251             }
6252         }
6253     }
6254 
6255     //==========================================================================================
6256     // Hdmi CEC:
6257     // - System audio mode:
6258     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
6259     //     to HdmiControlService so that the audio receiver can handle it.
6260     // - CEC sink:
6261     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
6262     //     and volume changes won't be taken into account on this device. Volume adjustments
6263     //     are transformed into key events for the HDMI playback client.
6264     //==========================================================================================
6265 
6266     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)6267     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
6268         mHdmiCecSink = hdmiCecSink;
6269         if (mHdmiCecSink) {
6270             if (DEBUG_VOL) {
6271                 Log.d(TAG, "CEC sink: setting HDMI as full vol device");
6272             }
6273             mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_HDMI);
6274         } else {
6275             if (DEBUG_VOL) {
6276                 Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
6277             }
6278             // Android TV devices without CEC service apply software volume on
6279             // HDMI output
6280             mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_HDMI);
6281         }
6282 
6283         checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI,
6284                 "HdmiPlaybackClient.DisplayStatusCallback");
6285     }
6286 
6287     private class MyHdmiControlStatusChangeListenerCallback
6288             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(boolean isCecEnabled, boolean isCecAvailable)6289         public void onStatusChange(boolean isCecEnabled, boolean isCecAvailable) {
6290             synchronized (mHdmiClientLock) {
6291                 if (mHdmiManager == null) return;
6292                 updateHdmiCecSinkLocked(isCecEnabled ? isCecAvailable : false);
6293             }
6294         }
6295     };
6296 
6297     private final Object mHdmiClientLock = new Object();
6298 
6299     // If HDMI-CEC system audio is supported
6300     private boolean mHdmiSystemAudioSupported = false;
6301     // Set only when device is tv.
6302     @GuardedBy("mHdmiClientLock")
6303     private HdmiTvClient mHdmiTvClient;
6304     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
6305     // cached HdmiControlManager interface
6306     @GuardedBy("mHdmiClientLock")
6307     private HdmiControlManager mHdmiManager;
6308     // Set only when device is a set-top box.
6309     @GuardedBy("mHdmiClientLock")
6310     private HdmiPlaybackClient mHdmiPlaybackClient;
6311     // true if we are a set-top box, an HDMI sink is connected and it supports CEC.
6312     @GuardedBy("mHdmiClientLock")
6313     private boolean mHdmiCecSink;
6314     // Set only when device is an audio system.
6315     @GuardedBy("mHdmiClientLock")
6316     private HdmiAudioSystemClient mHdmiAudioSystemClient;
6317 
6318     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
6319             new MyHdmiControlStatusChangeListenerCallback();
6320 
6321     @Override
setHdmiSystemAudioSupported(boolean on)6322     public int setHdmiSystemAudioSupported(boolean on) {
6323         int device = AudioSystem.DEVICE_NONE;
6324         synchronized (mHdmiClientLock) {
6325             if (mHdmiManager != null) {
6326                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
6327                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
6328                             + "system audio mode.");
6329                     return device;
6330                 }
6331                 if (mHdmiSystemAudioSupported != on) {
6332                     mHdmiSystemAudioSupported = on;
6333                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
6334                         AudioSystem.FORCE_NONE;
6335                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
6336                             "setHdmiSystemAudioSupported");
6337                 }
6338                 device = getDevicesForStream(AudioSystem.STREAM_MUSIC);
6339             }
6340         }
6341         return device;
6342     }
6343 
6344     @Override
isHdmiSystemAudioSupported()6345     public boolean isHdmiSystemAudioSupported() {
6346         return mHdmiSystemAudioSupported;
6347     }
6348 
6349     //==========================================================================================
6350     // Accessibility
6351 
initA11yMonitoring()6352     private void initA11yMonitoring() {
6353         final AccessibilityManager accessibilityManager =
6354                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
6355         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
6356         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
6357         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
6358         accessibilityManager.addAccessibilityServicesStateChangeListener(this, null);
6359     }
6360 
6361     //---------------------------------------------------------------------------------
6362     // A11y: taking touch exploration into account for selecting the default
6363     //   stream override timeout when adjusting volume
6364     //---------------------------------------------------------------------------------
6365 
6366     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
6367     // - STREAM_RING on phones during this period after a notification stopped
6368     // - STREAM_MUSIC otherwise
6369 
6370     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
6371     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
6372 
6373     private static int sStreamOverrideDelayMs;
6374 
6375     @Override
onTouchExplorationStateChanged(boolean enabled)6376     public void onTouchExplorationStateChanged(boolean enabled) {
6377         updateDefaultStreamOverrideDelay(enabled);
6378     }
6379 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)6380     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
6381         if (touchExploreEnabled) {
6382             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
6383         } else {
6384             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
6385         }
6386         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
6387                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
6388     }
6389 
6390     //---------------------------------------------------------------------------------
6391     // A11y: taking a11y state into account for the handling of a11y prompts volume
6392     //---------------------------------------------------------------------------------
6393 
6394     private static boolean sIndependentA11yVolume = false;
6395 
6396     // implementation of AccessibilityServicesStateChangeListener
6397     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)6398     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
6399         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
6400     }
6401 
updateA11yVolumeAlias(boolean a11VolEnabled)6402     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
6403         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
6404         if (sIndependentA11yVolume != a11VolEnabled) {
6405             sIndependentA11yVolume = a11VolEnabled;
6406             // update the volume mapping scheme
6407             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
6408             // update the volume controller behavior
6409             mVolumeController.setA11yMode(sIndependentA11yVolume ?
6410                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
6411                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
6412             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
6413         }
6414     }
6415 
6416     //==========================================================================================
6417     // Camera shutter sound policy.
6418     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
6419     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
6420     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
6421     //==========================================================================================
6422 
6423     // cached value of com.android.internal.R.bool.config_camera_sound_forced
6424     @GuardedBy("mSettingsLock")
6425     private boolean mCameraSoundForced;
6426 
6427     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()6428     public boolean isCameraSoundForced() {
6429         synchronized (mSettingsLock) {
6430             return mCameraSoundForced;
6431         }
6432     }
6433 
6434     //==========================================================================================
6435     // AudioService logging and dumpsys
6436     //==========================================================================================
6437     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
6438     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30;
6439     static final int LOG_NB_EVENTS_FORCE_USE = 20;
6440     static final int LOG_NB_EVENTS_VOLUME = 40;
6441     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
6442 
6443     final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
6444             "phone state (logged after successfull call to AudioSystem.setPhoneState(int))");
6445 
6446     // logs for wired + A2DP device connections:
6447     // - wired: logged before onSetWiredDeviceConnectionState() is executed
6448     // - A2DP: logged at reception of method call
6449     /*package*/ static final AudioEventLogger sDeviceLogger = new AudioEventLogger(
6450             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
6451 
6452     static final AudioEventLogger sForceUseLogger = new AudioEventLogger(
6453             LOG_NB_EVENTS_FORCE_USE,
6454             "force use (logged before setForceUse() is executed)");
6455 
6456     static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
6457             "volume changes (logged when command received by AudioService)");
6458 
6459     final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY,
6460             "dynamic policy events (logged when command received by AudioService)");
6461 
6462     private static final String[] RINGER_MODE_NAMES = new String[] {
6463             "SILENT",
6464             "VIBRATE",
6465             "NORMAL"
6466     };
6467 
dumpRingerMode(PrintWriter pw)6468     private void dumpRingerMode(PrintWriter pw) {
6469         pw.println("\nRinger mode: ");
6470         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
6471         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
6472         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
6473         dumpRingerModeStreams(pw, "muted", mRingerAndZenModeMutedStreams);
6474         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
6475     }
6476 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)6477     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
6478         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
6479         pw.print(Integer.toHexString(streams));
6480         if (streams != 0) {
6481             pw.print(" (");
6482             boolean first = true;
6483             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
6484                 final int stream = (1 << i);
6485                 if ((streams & stream) != 0) {
6486                     if (!first) pw.print(',');
6487                     pw.print(AudioSystem.STREAM_NAMES[i]);
6488                     streams &= ~stream;
6489                     first = false;
6490                 }
6491             }
6492             if (streams != 0) {
6493                 if (!first) pw.print(',');
6494                 pw.print(streams);
6495             }
6496             pw.print(')');
6497         }
6498         pw.println();
6499     }
6500 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)6501     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
6502         Iterator<Integer> it = deviceTypes.iterator();
6503         if (!it.hasNext()) {
6504             return "";
6505         }
6506         final StringBuilder sb = new StringBuilder();
6507         sb.append("0x" + Integer.toHexString(it.next()));
6508         while (it.hasNext()) {
6509             sb.append("," + "0x" + Integer.toHexString(it.next()));
6510         }
6511         return sb.toString();
6512     }
6513 
6514     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)6515     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
6516         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
6517 
6518         if (mAudioHandler != null) {
6519             pw.println("\nMessage handler (watch for unhandled messages):");
6520             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
6521         } else {
6522             pw.println("\nMessage handler is null");
6523         }
6524         mMediaFocusControl.dump(pw);
6525         dumpStreamStates(pw);
6526         dumpVolumeGroups(pw);
6527         dumpRingerMode(pw);
6528         pw.println("\nAudio routes:");
6529         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
6530                 mDeviceBroker.getCurAudioRoutes().mainType));
6531         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
6532 
6533         pw.println("\nOther state:");
6534         pw.print("  mVolumeController="); pw.println(mVolumeController);
6535         pw.print("  mSafeMediaVolumeState=");
6536         pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
6537         pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
6538         pw.print("  mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex);
6539         pw.print("  mSafeUsbMediaVolumeDbfs="); pw.println(mSafeUsbMediaVolumeDbfs);
6540         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
6541         pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
6542         pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
6543         pw.print("  mMcc="); pw.println(mMcc);
6544         pw.print("  mCameraSoundForced="); pw.println(mCameraSoundForced);
6545         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
6546         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
6547         pw.print("  mAvrcpAbsVolSupported=");
6548         pw.println(mDeviceBroker.isAvrcpAbsoluteVolumeSupported());
6549         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
6550         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
6551         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
6552         pw.print("  mHdmiCecSink="); pw.println(mHdmiCecSink);
6553         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
6554         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
6555         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
6556         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
6557 
6558         dumpAudioPolicies(pw);
6559         mDynPolicyLogger.dump(pw);
6560         mPlaybackMonitor.dump(pw);
6561         mRecordMonitor.dump(pw);
6562 
6563         pw.println("\nAudioDeviceBroker:");
6564         mDeviceBroker.dump(pw, "  ");
6565         pw.println("\nSoundEffects:");
6566         mSfxHelper.dump(pw, "  ");
6567 
6568         pw.println("\n");
6569         pw.println("\nEvent logs:");
6570         mModeLogger.dump(pw);
6571         pw.println("\n");
6572         sDeviceLogger.dump(pw);
6573         pw.println("\n");
6574         sForceUseLogger.dump(pw);
6575         pw.println("\n");
6576         sVolumeLogger.dump(pw);
6577     }
6578 
safeMediaVolumeStateToString(int state)6579     private static String safeMediaVolumeStateToString(int state) {
6580         switch(state) {
6581             case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED";
6582             case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED";
6583             case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE";
6584             case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE";
6585         }
6586         return null;
6587     }
6588 
6589     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()6590     private static void readAndSetLowRamDevice()
6591     {
6592         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
6593         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
6594 
6595         try {
6596             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
6597             ActivityManager.getService().getMemoryInfo(info);
6598             totalMemory = info.totalMem;
6599         } catch (RemoteException e) {
6600             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
6601             isLowRamDevice = true;
6602         }
6603 
6604         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
6605         if (status != 0) {
6606             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
6607         }
6608     }
6609 
enforceVolumeController(String action)6610     private void enforceVolumeController(String action) {
6611         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
6612                 "Only SystemUI can " + action);
6613     }
6614 
6615     @Override
setVolumeController(final IVolumeController controller)6616     public void setVolumeController(final IVolumeController controller) {
6617         enforceVolumeController("set the volume controller");
6618 
6619         // return early if things are not actually changing
6620         if (mVolumeController.isSameBinder(controller)) {
6621             return;
6622         }
6623 
6624         // dismiss the old volume controller
6625         mVolumeController.postDismiss();
6626         if (controller != null) {
6627             // we are about to register a new controller, listen for its death
6628             try {
6629                 controller.asBinder().linkToDeath(new DeathRecipient() {
6630                     @Override
6631                     public void binderDied() {
6632                         if (mVolumeController.isSameBinder(controller)) {
6633                             Log.w(TAG, "Current remote volume controller died, unregistering");
6634                             setVolumeController(null);
6635                         }
6636                     }
6637                 }, 0);
6638             } catch (RemoteException e) {
6639                 // noop
6640             }
6641         }
6642         mVolumeController.setController(controller);
6643         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
6644     }
6645 
6646     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)6647     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
6648         enforceVolumeController("notify about volume controller visibility");
6649 
6650         // return early if the controller is not current
6651         if (!mVolumeController.isSameBinder(controller)) {
6652             return;
6653         }
6654 
6655         mVolumeController.setVisible(visible);
6656         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
6657     }
6658 
6659     @Override
setVolumePolicy(VolumePolicy policy)6660     public void setVolumePolicy(VolumePolicy policy) {
6661         enforceVolumeController("set volume policy");
6662         if (policy != null && !policy.equals(mVolumePolicy)) {
6663             mVolumePolicy = policy;
6664             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
6665         }
6666     }
6667 
6668     public static class VolumeController {
6669         private static final String TAG = "VolumeController";
6670 
6671         private IVolumeController mController;
6672         private boolean mVisible;
6673         private long mNextLongPress;
6674         private int mLongPressTimeout;
6675 
setController(IVolumeController controller)6676         public void setController(IVolumeController controller) {
6677             mController = controller;
6678             mVisible = false;
6679         }
6680 
loadSettings(ContentResolver cr)6681         public void loadSettings(ContentResolver cr) {
6682             mLongPressTimeout = Settings.Secure.getIntForUser(cr,
6683                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
6684         }
6685 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)6686         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
6687             if (isMute) {
6688                 return false;
6689             }
6690             boolean suppress = false;
6691             if (resolvedStream != AudioSystem.STREAM_MUSIC && mController != null) {
6692                 final long now = SystemClock.uptimeMillis();
6693                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
6694                     // ui will become visible
6695                     if (mNextLongPress < now) {
6696                         mNextLongPress = now + mLongPressTimeout;
6697                     }
6698                     suppress = true;
6699                 } else if (mNextLongPress > 0) {  // in a long-press
6700                     if (now > mNextLongPress) {
6701                         // long press triggered, no more suppression
6702                         mNextLongPress = 0;
6703                     } else {
6704                         // keep suppressing until the long press triggers
6705                         suppress = true;
6706                     }
6707                 }
6708             }
6709             return suppress;
6710         }
6711 
setVisible(boolean visible)6712         public void setVisible(boolean visible) {
6713             mVisible = visible;
6714         }
6715 
isSameBinder(IVolumeController controller)6716         public boolean isSameBinder(IVolumeController controller) {
6717             return Objects.equals(asBinder(), binder(controller));
6718         }
6719 
asBinder()6720         public IBinder asBinder() {
6721             return binder(mController);
6722         }
6723 
binder(IVolumeController controller)6724         private static IBinder binder(IVolumeController controller) {
6725             return controller == null ? null : controller.asBinder();
6726         }
6727 
6728         @Override
toString()6729         public String toString() {
6730             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
6731         }
6732 
postDisplaySafeVolumeWarning(int flags)6733         public void postDisplaySafeVolumeWarning(int flags) {
6734             if (mController == null)
6735                 return;
6736             try {
6737                 mController.displaySafeVolumeWarning(flags);
6738             } catch (RemoteException e) {
6739                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
6740             }
6741         }
6742 
postVolumeChanged(int streamType, int flags)6743         public void postVolumeChanged(int streamType, int flags) {
6744             if (mController == null)
6745                 return;
6746             try {
6747                 mController.volumeChanged(streamType, flags);
6748             } catch (RemoteException e) {
6749                 Log.w(TAG, "Error calling volumeChanged", e);
6750             }
6751         }
6752 
postMasterMuteChanged(int flags)6753         public void postMasterMuteChanged(int flags) {
6754             if (mController == null)
6755                 return;
6756             try {
6757                 mController.masterMuteChanged(flags);
6758             } catch (RemoteException e) {
6759                 Log.w(TAG, "Error calling masterMuteChanged", e);
6760             }
6761         }
6762 
setLayoutDirection(int layoutDirection)6763         public void setLayoutDirection(int layoutDirection) {
6764             if (mController == null)
6765                 return;
6766             try {
6767                 mController.setLayoutDirection(layoutDirection);
6768             } catch (RemoteException e) {
6769                 Log.w(TAG, "Error calling setLayoutDirection", e);
6770             }
6771         }
6772 
postDismiss()6773         public void postDismiss() {
6774             if (mController == null)
6775                 return;
6776             try {
6777                 mController.dismiss();
6778             } catch (RemoteException e) {
6779                 Log.w(TAG, "Error calling dismiss", e);
6780             }
6781         }
6782 
setA11yMode(int a11yMode)6783         public void setA11yMode(int a11yMode) {
6784             if (mController == null)
6785                 return;
6786             try {
6787                 mController.setA11yMode(a11yMode);
6788             } catch (RemoteException e) {
6789                 Log.w(TAG, "Error calling setA11Mode", e);
6790             }
6791         }
6792     }
6793 
6794     /**
6795      * Interface for system components to get some extra functionality through
6796      * LocalServices.
6797      */
6798     final class AudioServiceInternal extends AudioManagerInternal {
6799         @Override
setRingerModeDelegate(RingerModeDelegate delegate)6800         public void setRingerModeDelegate(RingerModeDelegate delegate) {
6801             mRingerModeDelegate = delegate;
6802             if (mRingerModeDelegate != null) {
6803                 synchronized (mSettingsLock) {
6804                     updateRingerAndZenModeAffectedStreams();
6805                 }
6806                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
6807             }
6808         }
6809 
6810         @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, String callingPackage, int uid)6811         public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
6812                 String callingPackage, int uid) {
6813             // direction and stream type swap here because the public
6814             // adjustSuggested has a different order than the other methods.
6815             adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage,
6816                     callingPackage, uid);
6817         }
6818 
6819         @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, String callingPackage, int uid)6820         public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
6821                 String callingPackage, int uid) {
6822             if (direction != AudioManager.ADJUST_SAME) {
6823                 sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
6824                         direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
6825                         .append(" uid:").append(uid).toString()));
6826             }
6827             adjustStreamVolume(streamType, direction, flags, callingPackage,
6828                     callingPackage, uid);
6829         }
6830 
6831         @Override
setStreamVolumeForUid(int streamType, int direction, int flags, String callingPackage, int uid)6832         public void setStreamVolumeForUid(int streamType, int direction, int flags,
6833                 String callingPackage, int uid) {
6834             setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid);
6835         }
6836 
6837         @Override
getRingerModeInternal()6838         public int getRingerModeInternal() {
6839             return AudioService.this.getRingerModeInternal();
6840         }
6841 
6842         @Override
setRingerModeInternal(int ringerMode, String caller)6843         public void setRingerModeInternal(int ringerMode, String caller) {
6844             AudioService.this.setRingerModeInternal(ringerMode, caller);
6845         }
6846 
6847         @Override
silenceRingerModeInternal(String caller)6848         public void silenceRingerModeInternal(String caller) {
6849             AudioService.this.silenceRingerModeInternal(caller);
6850         }
6851 
6852         @Override
updateRingerModeAffectedStreamsInternal()6853         public void updateRingerModeAffectedStreamsInternal() {
6854             synchronized (mSettingsLock) {
6855                 if (updateRingerAndZenModeAffectedStreams()) {
6856                     setRingerModeInt(getRingerModeInternal(), false);
6857                 }
6858             }
6859         }
6860 
6861         @Override
setAccessibilityServiceUids(IntArray uids)6862         public void setAccessibilityServiceUids(IntArray uids) {
6863             synchronized (mAccessibilityServiceUidsLock) {
6864                 if (uids.size() == 0) {
6865                     mAccessibilityServiceUids = null;
6866                 } else {
6867                     boolean changed = (mAccessibilityServiceUids == null)
6868                             || (mAccessibilityServiceUids.length != uids.size());
6869                     if (!changed) {
6870                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
6871                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
6872                                 changed = true;
6873                                 break;
6874                             }
6875                         }
6876                     }
6877                     if (changed) {
6878                         mAccessibilityServiceUids = uids.toArray();
6879                     }
6880                 }
6881                 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
6882             }
6883         }
6884     }
6885 
6886     //==========================================================================================
6887     // Audio policy management
6888     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)6889     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
6890             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
6891             boolean isVolumeController, IMediaProjection projection) {
6892         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
6893 
6894         if (!isPolicyRegisterAllowed(policyConfig,
6895                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
6896                                      isVolumeController,
6897                                      projection)) {
6898             Slog.w(TAG, "Permission denied to register audio policy for pid "
6899                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
6900                     + ", need MODIFY_AUDIO_ROUTING or MediaProjection that can project audio");
6901             return null;
6902         }
6903 
6904         mDynPolicyLogger.log((new AudioEventLogger.StringEvent("registerAudioPolicy for "
6905                 + pcb.asBinder() + " with config:" + policyConfig)).printLog(TAG));
6906 
6907         String regId = null;
6908         synchronized (mAudioPolicies) {
6909             if (mAudioPolicies.containsKey(pcb.asBinder())) {
6910                 Slog.e(TAG, "Cannot re-register policy");
6911                 return null;
6912             }
6913             try {
6914                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
6915                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection);
6916                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
6917                 regId = app.getRegistrationId();
6918                 mAudioPolicies.put(pcb.asBinder(), app);
6919             } catch (RemoteException e) {
6920                 // audio policy owner has already died!
6921                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
6922                         " binder death", e);
6923                 return null;
6924             } catch (IllegalStateException e) {
6925                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
6926                 return null;
6927             }
6928         }
6929         return regId;
6930     }
6931 
6932     /**
6933      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
6934      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
6935      * as those policy do not modify the audio routing.
6936      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)6937     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
6938                                             boolean hasFocusAccess,
6939                                             boolean isVolumeController,
6940                                             IMediaProjection projection) {
6941 
6942         boolean requireValidProjection = false;
6943         boolean requireCaptureAudioOrMediaOutputPerm = false;
6944         boolean requireModifyRouting = false;
6945 
6946         if (hasFocusAccess || isVolumeController) {
6947             requireModifyRouting |= true;
6948         } else if (policyConfig.getMixes().isEmpty()) {
6949             // An empty policy could be used to lock the focus or add mixes later
6950             requireModifyRouting |= true;
6951         }
6952         for (AudioMix mix : policyConfig.getMixes()) {
6953             // If mix is requesting a privileged capture
6954             if (mix.getRule().allowPrivilegedPlaybackCapture()) {
6955                 // then it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
6956                 requireCaptureAudioOrMediaOutputPerm |= true;
6957                 // and its format must be low quality enough
6958                 String error = mix.canBeUsedForPrivilegedCapture(mix.getFormat());
6959                 if (error != null) {
6960                     Log.e(TAG, error);
6961                     return false;
6962                 }
6963             }
6964 
6965             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
6966             // otherwise MODIFY_AUDIO_ROUTING permission is required
6967             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
6968                 requireValidProjection |= true;
6969             } else {
6970                 requireModifyRouting |= true;
6971             }
6972         }
6973 
6974         if (requireCaptureAudioOrMediaOutputPerm
6975                 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT)
6976                 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) {
6977             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
6978                       + "CAPTURE_AUDIO_OUTPUT system permission");
6979             return false;
6980         }
6981 
6982         if (requireValidProjection && !canProjectAudio(projection)) {
6983             return false;
6984         }
6985 
6986         if (requireModifyRouting
6987                 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) {
6988             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
6989             return false;
6990         }
6991 
6992         return true;
6993     }
6994 
callerHasPermission(String permission)6995     private boolean callerHasPermission(String permission) {
6996         return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
6997     }
6998 
6999     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)7000     private boolean canProjectAudio(IMediaProjection projection) {
7001         if (projection == null) {
7002             Log.e(TAG, "MediaProjection is null");
7003             return false;
7004         }
7005 
7006         IMediaProjectionManager projectionService = getProjectionService();
7007         if (projectionService == null) {
7008             Log.e(TAG, "Can't get service IMediaProjectionManager");
7009             return false;
7010         }
7011 
7012         try {
7013             if (!projectionService.isValidMediaProjection(projection)) {
7014                 Log.w(TAG, "App passed invalid MediaProjection token");
7015                 return false;
7016             }
7017         } catch (RemoteException e) {
7018             Log.e(TAG, "Can't call .isValidMediaProjection() on IMediaProjectionManager"
7019                     + projectionService.asBinder(), e);
7020             return false;
7021         }
7022 
7023         try {
7024             if (!projection.canProjectAudio()) {
7025                 Log.w(TAG, "App passed MediaProjection that can not project audio");
7026                 return false;
7027             }
7028         } catch (RemoteException e) {
7029             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
7030                     + projection.asBinder(), e);
7031             return false;
7032         }
7033 
7034         return true;
7035     }
7036 
getProjectionService()7037     private IMediaProjectionManager getProjectionService() {
7038         if (mProjectionService == null) {
7039             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
7040             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
7041         }
7042         return mProjectionService;
7043     }
7044 
7045     /**
7046      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
7047      * Declared oneway
7048      * @param pcb nullable because on service interface
7049      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)7050     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
7051         unregisterAudioPolicy(pcb);
7052     }
7053 
7054     /**
7055      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
7056      * @param pcb nullable because on service interface
7057      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)7058     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
7059         if (pcb == null) {
7060             return;
7061         }
7062         unregisterAudioPolicyInt(pcb);
7063     }
7064 
7065 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb)7066     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb) {
7067         mDynPolicyLogger.log((new AudioEventLogger.StringEvent("unregisterAudioPolicyAsync for "
7068                 + pcb.asBinder()).printLog(TAG)));
7069         synchronized (mAudioPolicies) {
7070             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
7071             if (app == null) {
7072                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
7073                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
7074                 return;
7075             } else {
7076                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
7077             }
7078             app.release();
7079         }
7080         // TODO implement clearing mix attribute matching info in native audio policy
7081     }
7082 
7083     /**
7084      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
7085      * @param errorMsg log warning if permission check failed.
7086      * @return null if the operation on the audio mixes should be cancelled.
7087      */
7088     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)7089     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
7090         // permission check
7091         final boolean hasPermissionForPolicy =
7092                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
7093                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
7094         if (!hasPermissionForPolicy) {
7095             Slog.w(TAG, errorMsg + " for pid " +
7096                     + Binder.getCallingPid() + " / uid "
7097                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
7098             return null;
7099         }
7100         // policy registered?
7101         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
7102         if (app == null) {
7103             Slog.w(TAG, errorMsg + " for pid " +
7104                     + Binder.getCallingPid() + " / uid "
7105                     + Binder.getCallingUid() + ", unregistered policy");
7106             return null;
7107         }
7108         return app;
7109     }
7110 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)7111     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
7112         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
7113                 + " with config:" + policyConfig); }
7114         synchronized (mAudioPolicies) {
7115             final AudioPolicyProxy app =
7116                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
7117             if (app == null){
7118                 return AudioManager.ERROR;
7119             }
7120             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
7121                 ? AudioManager.SUCCESS : AudioManager.ERROR;
7122         }
7123     }
7124 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)7125     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
7126         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
7127                 + " with config:" + policyConfig); }
7128         synchronized (mAudioPolicies) {
7129             final AudioPolicyProxy app =
7130                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
7131             if (app == null) {
7132                 return AudioManager.ERROR;
7133             }
7134             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
7135                 ? AudioManager.SUCCESS : AudioManager.ERROR;
7136         }
7137     }
7138 
7139     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)7140     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
7141             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
7142         if (DEBUG_AP) {
7143             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
7144         }
7145         synchronized (mAudioPolicies) {
7146             final AudioPolicyProxy app =
7147                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
7148             if (app == null) {
7149                 return AudioManager.ERROR;
7150             }
7151             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
7152                 return AudioManager.ERROR;
7153             }
7154             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
7155         }
7156     }
7157 
7158     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)7159     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
7160         if (DEBUG_AP) {
7161             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
7162         }
7163         synchronized (mAudioPolicies) {
7164             final AudioPolicyProxy app =
7165                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
7166             if (app == null) {
7167                 return AudioManager.ERROR;
7168             }
7169             return app.removeUidDeviceAffinities(uid);
7170         }
7171     }
7172 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)7173     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
7174         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
7175                 + " policy " +  pcb.asBinder());
7176         synchronized (mAudioPolicies) {
7177             final AudioPolicyProxy app =
7178                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
7179             if (app == null){
7180                 return AudioManager.ERROR;
7181             }
7182             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
7183                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
7184                 return AudioManager.ERROR;
7185             }
7186             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
7187                 // is there already one policy managing ducking?
7188                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
7189                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
7190                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
7191                         return AudioManager.ERROR;
7192                     }
7193                 }
7194             }
7195             app.mFocusDuckBehavior = duckingBehavior;
7196             mMediaFocusControl.setDuckingInExtPolicyAvailable(
7197                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
7198         }
7199         return AudioManager.SUCCESS;
7200     }
7201 
7202     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()7203     public boolean hasRegisteredDynamicPolicy() {
7204         synchronized (mAudioPolicies) {
7205             return !mAudioPolicies.isEmpty();
7206         }
7207     }
7208 
7209     private final Object mExtVolumeControllerLock = new Object();
7210     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)7211     private void setExtVolumeController(IAudioPolicyCallback apc) {
7212         if (!mContext.getResources().getBoolean(
7213                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
7214             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
7215                     " handled in PhoneWindowManager");
7216             return;
7217         }
7218         synchronized (mExtVolumeControllerLock) {
7219             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
7220                 Log.e(TAG, "Cannot set external volume controller: existing controller");
7221             }
7222             mExtVolumeController = apc;
7223         }
7224     }
7225 
dumpAudioPolicies(PrintWriter pw)7226     private void dumpAudioPolicies(PrintWriter pw) {
7227         pw.println("\nAudio policies:");
7228         synchronized (mAudioPolicies) {
7229             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
7230                 pw.println(policy.toLogFriendlyString());
7231             }
7232         }
7233     }
7234 
7235     //======================
7236     // Audio policy callbacks from AudioSystem for dynamic policies
7237     //======================
7238     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
7239             new AudioSystem.DynamicPolicyCallback() {
7240         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
7241             if (!TextUtils.isEmpty(regId)) {
7242                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
7243                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
7244             }
7245         }
7246     };
7247 
onDynPolicyMixStateUpdate(String regId, int state)7248     private void onDynPolicyMixStateUpdate(String regId, int state) {
7249         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
7250         synchronized (mAudioPolicies) {
7251             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
7252                 for (AudioMix mix : policy.getMixes()) {
7253                     if (mix.getRegistration().equals(regId)) {
7254                         try {
7255                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
7256                         } catch (RemoteException e) {
7257                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
7258                                     + policy.mPolicyCallback.asBinder(), e);
7259                         }
7260                         return;
7261                     }
7262                 }
7263             }
7264         }
7265     }
7266 
7267     //======================
7268     // Audio policy callbacks from AudioSystem for recording configuration updates
7269     //======================
7270     private final RecordingActivityMonitor mRecordMonitor;
7271 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)7272     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
7273         final boolean isPrivileged =
7274                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
7275                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
7276         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
7277     }
7278 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)7279     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
7280         mRecordMonitor.unregisterRecordingCallback(rcdb);
7281     }
7282 
getActiveRecordingConfigurations()7283     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
7284         final boolean isPrivileged =
7285                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
7286                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
7287         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
7288     }
7289 
7290     //======================
7291     // Audio recording state notification from clients
7292     //======================
7293     /**
7294      * Track a recorder provided by the client
7295      */
trackRecorder(IBinder recorder)7296     public int trackRecorder(IBinder recorder) {
7297         return mRecordMonitor.trackRecorder(recorder);
7298     }
7299 
7300     /**
7301      * Receive an event from the client about a tracked recorder
7302      */
recorderEvent(int riid, int event)7303     public void recorderEvent(int riid, int event) {
7304         mRecordMonitor.recorderEvent(riid, event);
7305     }
7306 
7307     /**
7308      * Stop tracking the recorder
7309      */
releaseRecorder(int riid)7310     public void releaseRecorder(int riid) {
7311         mRecordMonitor.releaseRecorder(riid);
7312     }
7313 
disableRingtoneSync(final int userId)7314     public void disableRingtoneSync(final int userId) {
7315         final int callingUserId = UserHandle.getCallingUserId();
7316         if (callingUserId != userId) {
7317             mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
7318                     "disable sound settings syncing for another profile");
7319         }
7320         final long token = Binder.clearCallingIdentity();
7321         try {
7322             // Disable the sync setting so the profile uses its own sound settings.
7323             Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.SYNC_PARENT_SOUNDS,
7324                     0 /* false */, userId);
7325         } finally {
7326             Binder.restoreCallingIdentity(token);
7327         }
7328     }
7329 
7330     //======================
7331     // Audio playback notification
7332     //======================
7333     private final PlaybackActivityMonitor mPlaybackMonitor;
7334 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)7335     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
7336         final boolean isPrivileged =
7337                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
7338                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
7339         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
7340     }
7341 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)7342     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
7343         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
7344     }
7345 
getActivePlaybackConfigurations()7346     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
7347         final boolean isPrivileged =
7348                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
7349                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
7350         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
7351     }
7352 
trackPlayer(PlayerBase.PlayerIdCard pic)7353     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
7354         return mPlaybackMonitor.trackPlayer(pic);
7355     }
7356 
playerAttributes(int piid, AudioAttributes attr)7357     public void playerAttributes(int piid, AudioAttributes attr) {
7358         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
7359     }
7360 
playerEvent(int piid, int event)7361     public void playerEvent(int piid, int event) {
7362         mPlaybackMonitor.playerEvent(piid, event, Binder.getCallingUid());
7363     }
7364 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)7365     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
7366         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
7367     }
7368 
releasePlayer(int piid)7369     public void releasePlayer(int piid) {
7370         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
7371     }
7372 
7373     /**
7374      * Specifies whether the audio played by this app may or may not be captured by other apps or
7375      * the system.
7376      *
7377      * @param capturePolicy one of
7378      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
7379      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
7380      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
7381      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
7382      * @throws IllegalArgumentException if the argument is not a valid value.
7383      */
setAllowedCapturePolicy(int capturePolicy)7384     public int setAllowedCapturePolicy(int capturePolicy) {
7385         int callingUid = Binder.getCallingUid();
7386         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
7387         final long identity = Binder.clearCallingIdentity();
7388         synchronized (mPlaybackMonitor) {
7389             int result = AudioSystem.setAllowedCapturePolicy(callingUid, flags);
7390             if (result == AudioSystem.AUDIO_STATUS_OK) {
7391                 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
7392             }
7393             Binder.restoreCallingIdentity(identity);
7394             return result;
7395         }
7396     }
7397 
7398     /**
7399      * Return the capture policy.
7400      * @return the cached capture policy for the calling uid.
7401      */
getAllowedCapturePolicy()7402     public int getAllowedCapturePolicy() {
7403         int callingUid = Binder.getCallingUid();
7404         final long identity = Binder.clearCallingIdentity();
7405         int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
7406         Binder.restoreCallingIdentity(identity);
7407         return capturePolicy;
7408     }
7409 
7410     //======================
7411     // Audio device management
7412     //======================
7413     private final AudioDeviceBroker mDeviceBroker;
7414 
7415     //======================
7416     // Audio policy proxy
7417     //======================
7418     private static final class AudioDeviceArray {
7419         final @NonNull int[] mDeviceTypes;
7420         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)7421         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
7422             mDeviceTypes = types;
7423             mDeviceAddresses = addresses;
7424         }
7425     }
7426 
7427     /**
7428      * This internal class inherits from AudioPolicyConfig, each instance contains all the
7429      * mixes of an AudioPolicy and their configurations.
7430      */
7431     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
7432         private static final String TAG = "AudioPolicyProxy";
7433         final IAudioPolicyCallback mPolicyCallback;
7434         final boolean mHasFocusListener;
7435         final boolean mIsVolumeController;
7436         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
7437                 new HashMap<Integer, AudioDeviceArray>();
7438 
7439         final IMediaProjection mProjection;
7440         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()7441             public void onStop() {
7442                 unregisterAudioPolicyAsync(mPolicyCallback);
7443             }
7444         };
7445         UnregisterOnStopCallback mProjectionCallback;
7446 
7447         /**
7448          * Audio focus ducking behavior for an audio policy.
7449          * This variable reflects the value that was successfully set in
7450          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
7451          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
7452          * is handling ducking for audio focus.
7453          */
7454         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
7455         boolean mIsFocusPolicy = false;
7456         boolean mIsTestFocusPolicy = false;
7457 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)7458         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
7459                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
7460                 boolean isVolumeController, IMediaProjection projection) {
7461             super(config);
7462             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
7463             mPolicyCallback = token;
7464             mHasFocusListener = hasFocusListener;
7465             mIsVolumeController = isVolumeController;
7466             mProjection = projection;
7467             if (mHasFocusListener) {
7468                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
7469                 // can only ever be true if there is a focus listener
7470                 if (isFocusPolicy) {
7471                     mIsFocusPolicy = true;
7472                     mIsTestFocusPolicy = isTestFocusPolicy;
7473                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
7474                 }
7475             }
7476             if (mIsVolumeController) {
7477                 setExtVolumeController(mPolicyCallback);
7478             }
7479             if (mProjection != null) {
7480                 mProjectionCallback = new UnregisterOnStopCallback();
7481                 try {
7482                     mProjection.registerCallback(mProjectionCallback);
7483                 } catch (RemoteException e) {
7484                     release();
7485                     throw new IllegalStateException("MediaProjection callback registration failed, "
7486                             + "could not link to " + projection + " binder death", e);
7487                 }
7488             }
7489             int status = connectMixes();
7490             if (status != AudioSystem.SUCCESS) {
7491                 release();
7492                 throw new IllegalStateException("Could not connect mix, error: " + status);
7493             }
7494         }
7495 
binderDied()7496         public void binderDied() {
7497             Log.i(TAG, "audio policy " + mPolicyCallback + " died");
7498             release();
7499         }
7500 
getRegistrationId()7501         String getRegistrationId() {
7502             return getRegistration();
7503         }
7504 
release()7505         void release() {
7506             if (mIsFocusPolicy) {
7507                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
7508             }
7509             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
7510                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
7511             }
7512             if (mHasFocusListener) {
7513                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
7514             }
7515             if (mProjectionCallback != null) {
7516                 try {
7517                     mProjection.unregisterCallback(mProjectionCallback);
7518                 } catch (RemoteException e) {
7519                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
7520                 }
7521             }
7522             if (mIsVolumeController) {
7523                 synchronized (mExtVolumeControllerLock) {
7524                     mExtVolumeController = null;
7525                 }
7526             }
7527             final long identity = Binder.clearCallingIdentity();
7528             AudioSystem.registerPolicyMixes(mMixes, false);
7529             Binder.restoreCallingIdentity(identity);
7530             synchronized (mAudioPolicies) {
7531                 mAudioPolicies.remove(mPolicyCallback.asBinder());
7532             }
7533             try {
7534                 mPolicyCallback.notifyUnregistration();
7535             } catch (RemoteException e) { }
7536         }
7537 
hasMixAffectingUsage(int usage, int excludedFlags)7538         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
7539             for (AudioMix mix : mMixes) {
7540                 if (mix.isAffectingUsage(usage)
7541                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
7542                     return true;
7543                 }
7544             }
7545             return false;
7546         }
7547 
7548         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)7549         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
7550                 @NonNull String[] deviceAddresses) {
7551             for (int i = 0; i < deviceTypes.length; i++) {
7552                 boolean hasDevice = false;
7553                 for (AudioMix mix : mMixes) {
7554                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
7555                     // is reached by this mix
7556                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
7557                         hasDevice = true;
7558                         break;
7559                     }
7560                 }
7561                 if (!hasDevice) {
7562                     return false;
7563                 }
7564             }
7565             return true;
7566         }
7567 
addMixes(@onNull ArrayList<AudioMix> mixes)7568         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
7569             // TODO optimize to not have to unregister the mixes already in place
7570             synchronized (mMixes) {
7571                 AudioSystem.registerPolicyMixes(mMixes, false);
7572                 this.add(mixes);
7573                 return AudioSystem.registerPolicyMixes(mMixes, true);
7574             }
7575         }
7576 
removeMixes(@onNull ArrayList<AudioMix> mixes)7577         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
7578             // TODO optimize to not have to unregister the mixes already in place
7579             synchronized (mMixes) {
7580                 AudioSystem.registerPolicyMixes(mMixes, false);
7581                 this.remove(mixes);
7582                 return AudioSystem.registerPolicyMixes(mMixes, true);
7583             }
7584         }
7585 
connectMixes()7586         @AudioSystem.AudioSystemError int connectMixes() {
7587             final long identity = Binder.clearCallingIdentity();
7588             int status = AudioSystem.registerPolicyMixes(mMixes, true);
7589             Binder.restoreCallingIdentity(identity);
7590             return status;
7591         }
7592 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)7593         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
7594             final Integer Uid = new Integer(uid);
7595             int res;
7596             if (mUidDeviceAffinities.remove(Uid) != null) {
7597                 final long identity = Binder.clearCallingIdentity();
7598                 res = AudioSystem.removeUidDeviceAffinities(uid);
7599                 Binder.restoreCallingIdentity(identity);
7600                 if (res != AudioSystem.SUCCESS) {
7601                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
7602                             + " cannot call AudioSystem.setUidDeviceAffinities");
7603                     return AudioManager.ERROR;
7604                 }
7605             }
7606             final long identity = Binder.clearCallingIdentity();
7607             res = AudioSystem.setUidDeviceAffinities(uid, types, addresses);
7608             Binder.restoreCallingIdentity(identity);
7609             if (res == AudioSystem.SUCCESS) {
7610                 mUidDeviceAffinities.put(Uid, new AudioDeviceArray(types, addresses));
7611                 return AudioManager.SUCCESS;
7612             }
7613             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
7614             return AudioManager.ERROR;
7615         }
7616 
removeUidDeviceAffinities(int uid)7617         int removeUidDeviceAffinities(int uid) {
7618             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
7619                 final long identity = Binder.clearCallingIdentity();
7620                 final int res = AudioSystem.removeUidDeviceAffinities(uid);
7621                 Binder.restoreCallingIdentity(identity);
7622                 if (res == AudioSystem.SUCCESS) {
7623                     return AudioManager.SUCCESS;
7624                 }
7625             }
7626             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
7627             return AudioManager.ERROR;
7628         }
7629 
7630         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()7631         public String toLogFriendlyString() {
7632             String textDump = super.toLogFriendlyString();
7633             textDump += " Proxy:\n";
7634             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
7635             if (mIsFocusPolicy) {
7636                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
7637                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
7638                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
7639             }
7640             textDump += "   media projection= " + mProjection + "\n";
7641             return textDump;
7642         }
7643     };
7644 
7645     //======================
7646     // Audio policy: focus
7647     //======================
7648     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)7649     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
7650         if (afi == null) {
7651             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
7652         }
7653         if (pcb == null) {
7654             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
7655         }
7656         synchronized (mAudioPolicies) {
7657             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
7658                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
7659             }
7660             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
7661         }
7662     }
7663 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)7664     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
7665             IAudioPolicyCallback pcb) {
7666         if (afi == null) {
7667             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
7668         }
7669         if (pcb == null) {
7670             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
7671         }
7672         synchronized (mAudioPolicies) {
7673             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
7674                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
7675             }
7676             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
7677         }
7678     }
7679 
7680 
7681     //======================
7682     // Audioserver state displatch
7683     //======================
7684     private class AsdProxy implements IBinder.DeathRecipient {
7685         private final IAudioServerStateDispatcher mAsd;
7686 
AsdProxy(IAudioServerStateDispatcher asd)7687         AsdProxy(IAudioServerStateDispatcher asd) {
7688             mAsd = asd;
7689         }
7690 
binderDied()7691         public void binderDied() {
7692             synchronized (mAudioServerStateListeners) {
7693                 mAudioServerStateListeners.remove(mAsd.asBinder());
7694             }
7695         }
7696 
callback()7697         IAudioServerStateDispatcher callback() {
7698             return mAsd;
7699         }
7700     }
7701 
7702     private HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
7703             new HashMap<IBinder, AsdProxy>();
7704 
checkMonitorAudioServerStatePermission()7705     private void checkMonitorAudioServerStatePermission() {
7706         if (!(mContext.checkCallingOrSelfPermission(
7707                     android.Manifest.permission.MODIFY_PHONE_STATE) ==
7708                 PackageManager.PERMISSION_GRANTED ||
7709               mContext.checkCallingOrSelfPermission(
7710                     android.Manifest.permission.MODIFY_AUDIO_ROUTING) ==
7711                 PackageManager.PERMISSION_GRANTED)) {
7712             throw new SecurityException("Not allowed to monitor audioserver state");
7713         }
7714     }
7715 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)7716     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
7717         checkMonitorAudioServerStatePermission();
7718         synchronized (mAudioServerStateListeners) {
7719             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
7720                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
7721                 return;
7722             }
7723             AsdProxy asdp = new AsdProxy(asd);
7724             try {
7725                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
7726             } catch (RemoteException e) {
7727 
7728             }
7729             mAudioServerStateListeners.put(asd.asBinder(), asdp);
7730         }
7731     }
7732 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)7733     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
7734         checkMonitorAudioServerStatePermission();
7735         synchronized (mAudioServerStateListeners) {
7736             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
7737             if (asdp == null) {
7738                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
7739                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
7740                 return;
7741             } else {
7742                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
7743             }
7744         }
7745     }
7746 
isAudioServerRunning()7747     public boolean isAudioServerRunning() {
7748         checkMonitorAudioServerStatePermission();
7749         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
7750     }
7751 
7752     //======================
7753     // Audio HAL process dump
7754     //======================
7755 
7756     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
7757 
getAudioHalPids()7758     private Set<Integer> getAudioHalPids() {
7759         try {
7760             IServiceManager serviceManager = IServiceManager.getService();
7761             ArrayList<IServiceManager.InstanceDebugInfo> dump =
7762                     serviceManager.debugDump();
7763             HashSet<Integer> pids = new HashSet<>();
7764             for (IServiceManager.InstanceDebugInfo info : dump) {
7765                 if (info.pid != IServiceManager.PidConstant.NO_PID
7766                         && info.interfaceName != null
7767                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
7768                     pids.add(info.pid);
7769                 }
7770             }
7771             return pids;
7772         } catch (RemoteException e) {
7773             return new HashSet<Integer>();
7774         }
7775     }
7776 
updateAudioHalPids()7777     private void updateAudioHalPids() {
7778         Set<Integer> pidsSet = getAudioHalPids();
7779         if (pidsSet.isEmpty()) {
7780             Slog.w(TAG, "Could not retrieve audio HAL service pids");
7781             return;
7782         }
7783         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
7784         AudioSystem.setAudioHalPids(pidsArray);
7785     }
7786 
7787     //======================
7788     // misc
7789     //======================
7790     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
7791             new HashMap<IBinder, AudioPolicyProxy>();
7792     @GuardedBy("mAudioPolicies")
7793     private int mAudioPolicyCounter = 0;
7794 }
7795