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