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