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