Home | History | Annotate | Download | only in audio
      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.os.Process.FIRST_APPLICATION_UID;
     24 
     25 import android.Manifest;
     26 import android.app.ActivityManager;
     27 import android.app.ActivityManagerInternal;
     28 import android.app.ActivityManagerNative;
     29 import android.app.AppGlobals;
     30 import android.app.AppOpsManager;
     31 import android.app.NotificationManager;
     32 import android.bluetooth.BluetoothA2dp;
     33 import android.bluetooth.BluetoothAdapter;
     34 import android.bluetooth.BluetoothClass;
     35 import android.bluetooth.BluetoothDevice;
     36 import android.bluetooth.BluetoothHeadset;
     37 import android.bluetooth.BluetoothProfile;
     38 import android.content.BroadcastReceiver;
     39 import android.content.ComponentName;
     40 import android.content.ContentResolver;
     41 import android.content.Context;
     42 import android.content.Intent;
     43 import android.content.IntentFilter;
     44 import android.content.pm.ApplicationInfo;
     45 import android.content.pm.PackageInfo;
     46 import android.content.pm.PackageManager;
     47 import android.content.pm.UserInfo;
     48 import android.content.res.Configuration;
     49 import android.content.res.Resources;
     50 import android.content.res.XmlResourceParser;
     51 import android.database.ContentObserver;
     52 import android.hardware.hdmi.HdmiControlManager;
     53 import android.hardware.hdmi.HdmiPlaybackClient;
     54 import android.hardware.hdmi.HdmiTvClient;
     55 import android.hardware.usb.UsbManager;
     56 import android.media.AudioAttributes;
     57 import android.media.AudioDevicePort;
     58 import android.media.AudioSystem;
     59 import android.media.AudioFormat;
     60 import android.media.AudioManager;
     61 import android.media.AudioManagerInternal;
     62 import android.media.AudioPort;
     63 import android.media.AudioRecordingConfiguration;
     64 import android.media.AudioRoutesInfo;
     65 import android.media.IAudioFocusDispatcher;
     66 import android.media.IAudioRoutesObserver;
     67 import android.media.IAudioService;
     68 import android.media.IRecordingConfigDispatcher;
     69 import android.media.IRingtonePlayer;
     70 import android.media.IVolumeController;
     71 import android.media.MediaPlayer;
     72 import android.media.SoundPool;
     73 import android.media.VolumePolicy;
     74 import android.media.MediaPlayer.OnCompletionListener;
     75 import android.media.MediaPlayer.OnErrorListener;
     76 import android.media.audiopolicy.AudioMix;
     77 import android.media.audiopolicy.AudioPolicy;
     78 import android.media.audiopolicy.AudioPolicyConfig;
     79 import android.media.audiopolicy.IAudioPolicyCallback;
     80 import android.os.Binder;
     81 import android.os.Build;
     82 import android.os.Bundle;
     83 import android.os.Environment;
     84 import android.os.Handler;
     85 import android.os.IBinder;
     86 import android.os.Looper;
     87 import android.os.Message;
     88 import android.os.PowerManager;
     89 import android.os.RemoteCallbackList;
     90 import android.os.RemoteException;
     91 import android.os.SystemClock;
     92 import android.os.SystemProperties;
     93 import android.os.UserHandle;
     94 import android.os.UserManager;
     95 import android.os.UserManagerInternal;
     96 import android.os.UserManagerInternal.UserRestrictionsListener;
     97 import android.os.Vibrator;
     98 import android.provider.Settings;
     99 import android.provider.Settings.System;
    100 import android.telecom.TelecomManager;
    101 import android.text.TextUtils;
    102 import android.util.AndroidRuntimeException;
    103 import android.util.ArrayMap;
    104 import android.util.ArraySet;
    105 import android.util.Log;
    106 import android.util.MathUtils;
    107 import android.util.Slog;
    108 import android.util.SparseIntArray;
    109 import android.view.KeyEvent;
    110 import android.view.accessibility.AccessibilityManager;
    111 
    112 import com.android.internal.util.XmlUtils;
    113 import com.android.server.EventLogTags;
    114 import com.android.server.LocalServices;
    115 import com.android.server.SystemService;
    116 import com.android.server.pm.UserManagerService;
    117 
    118 import org.xmlpull.v1.XmlPullParserException;
    119 
    120 import java.io.FileDescriptor;
    121 import java.io.IOException;
    122 import java.io.PrintWriter;
    123 import java.lang.reflect.Field;
    124 import java.util.ArrayList;
    125 import java.util.HashMap;
    126 import java.util.Iterator;
    127 import java.util.List;
    128 import java.util.NoSuchElementException;
    129 import java.util.Objects;
    130 
    131 /**
    132  * The implementation of the volume manager service.
    133  * <p>
    134  * This implementation focuses on delivering a responsive UI. Most methods are
    135  * asynchronous to external calls. For example, the task of setting a volume
    136  * will update our internal state, but in a separate thread will set the system
    137  * volume and later persist to the database. Similarly, setting the ringer mode
    138  * will update the state and broadcast a change and in a separate thread later
    139  * persist the ringer mode.
    140  *
    141  * @hide
    142  */
    143 public class AudioService extends IAudioService.Stub {
    144 
    145     private static final String TAG = "AudioService";
    146 
    147     /** Debug audio mode */
    148     protected static final boolean DEBUG_MODE = Log.isLoggable(TAG + ".MOD", Log.DEBUG);
    149 
    150     /** Debug audio policy feature */
    151     protected static final boolean DEBUG_AP = Log.isLoggable(TAG + ".AP", Log.DEBUG);
    152 
    153     /** Debug volumes */
    154     protected static final boolean DEBUG_VOL = Log.isLoggable(TAG + ".VOL", Log.DEBUG);
    155 
    156     /** debug calls to devices APIs */
    157     protected static final boolean DEBUG_DEVICES = Log.isLoggable(TAG + ".DEVICES", Log.DEBUG);
    158 
    159     /** How long to delay before persisting a change in volume/ringer mode. */
    160     private static final int PERSIST_DELAY = 500;
    161 
    162     /** How long to delay after a volume down event before unmuting a stream */
    163     private static final int UNMUTE_STREAM_DELAY = 350;
    164 
    165     /**
    166      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
    167      */
    168     private static final int FLAG_ADJUST_VOLUME = 1;
    169 
    170     private final Context mContext;
    171     private final ContentResolver mContentResolver;
    172     private final AppOpsManager mAppOps;
    173 
    174     // the platform type affects volume and silent mode behavior
    175     private final int mPlatformType;
    176 
    177     private boolean isPlatformVoice() {
    178         return mPlatformType == AudioSystem.PLATFORM_VOICE;
    179     }
    180 
    181     private boolean isPlatformTelevision() {
    182         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
    183     }
    184 
    185     /** The controller for the volume UI. */
    186     private final VolumeController mVolumeController = new VolumeController();
    187     private final ControllerService mControllerService = new ControllerService();
    188 
    189     // sendMsg() flags
    190     /** If the msg is already queued, replace it with this one. */
    191     private static final int SENDMSG_REPLACE = 0;
    192     /** If the msg is already queued, ignore this one and leave the old. */
    193     private static final int SENDMSG_NOOP = 1;
    194     /** If the msg is already queued, queue this one and leave the old. */
    195     private static final int SENDMSG_QUEUE = 2;
    196 
    197     // AudioHandler messages
    198     private static final int MSG_SET_DEVICE_VOLUME = 0;
    199     private static final int MSG_PERSIST_VOLUME = 1;
    200     private static final int MSG_PERSIST_RINGER_MODE = 3;
    201     private static final int MSG_AUDIO_SERVER_DIED = 4;
    202     private static final int MSG_PLAY_SOUND_EFFECT = 5;
    203     private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
    204     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
    205     private static final int MSG_SET_FORCE_USE = 8;
    206     private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
    207     private static final int MSG_SET_ALL_VOLUMES = 10;
    208     private static final int MSG_REPORT_NEW_ROUTES = 12;
    209     private static final int MSG_SET_FORCE_BT_A2DP_USE = 13;
    210     private static final int MSG_CHECK_MUSIC_ACTIVE = 14;
    211     private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 15;
    212     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 16;
    213     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 17;
    214     private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 18;
    215     private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 19;
    216     private static final int MSG_UNLOAD_SOUND_EFFECTS = 20;
    217     private static final int MSG_SYSTEM_READY = 21;
    218     private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 22;
    219     private static final int MSG_UNMUTE_STREAM = 24;
    220     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 25;
    221     private static final int MSG_INDICATE_SYSTEM_READY = 26;
    222     // start of messages handled under wakelock
    223     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
    224     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
    225     private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100;
    226     private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
    227     private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
    228     // end of messages handled under wakelock
    229 
    230     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
    231     // Timeout for connection to bluetooth headset service
    232     private static final int BT_HEADSET_CNCT_TIMEOUT_MS = 3000;
    233 
    234     // retry delay in case of failure to indicate system ready to AudioFlinger
    235     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
    236 
    237     /** @see AudioSystemThread */
    238     private AudioSystemThread mAudioSystemThread;
    239     /** @see AudioHandler */
    240     private AudioHandler mAudioHandler;
    241     /** @see VolumeStreamState */
    242     private VolumeStreamState[] mStreamStates;
    243     private SettingsObserver mSettingsObserver;
    244 
    245     private int mMode = AudioSystem.MODE_NORMAL;
    246     // protects mRingerMode
    247     private final Object mSettingsLock = new Object();
    248 
    249     private SoundPool mSoundPool;
    250     private final Object mSoundEffectsLock = new Object();
    251     private static final int NUM_SOUNDPOOL_CHANNELS = 4;
    252 
    253     /* Sound effect file names  */
    254     private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/";
    255     private static final List<String> SOUND_EFFECT_FILES = new ArrayList<String>();
    256 
    257     /* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to
    258      * file index in SOUND_EFFECT_FILES[] (first column) and indicating if effect
    259      * uses soundpool (second column) */
    260     private final int[][] SOUND_EFFECT_FILES_MAP = new int[AudioManager.NUM_SOUND_EFFECTS][2];
    261 
    262    /** Maximum volume index values for audio streams */
    263     private static int[] MAX_STREAM_VOLUME = new int[] {
    264         5,  // STREAM_VOICE_CALL
    265         7,  // STREAM_SYSTEM
    266         7,  // STREAM_RING
    267         15, // STREAM_MUSIC
    268         7,  // STREAM_ALARM
    269         7,  // STREAM_NOTIFICATION
    270         15, // STREAM_BLUETOOTH_SCO
    271         7,  // STREAM_SYSTEM_ENFORCED
    272         15, // STREAM_DTMF
    273         15  // STREAM_TTS
    274     };
    275 
    276     /** Minimum volume index values for audio streams */
    277     private static int[] MIN_STREAM_VOLUME = new int[] {
    278         1,  // STREAM_VOICE_CALL
    279         0,  // STREAM_SYSTEM
    280         0,  // STREAM_RING
    281         0,  // STREAM_MUSIC
    282         0,  // STREAM_ALARM
    283         0,  // STREAM_NOTIFICATION
    284         0,  // STREAM_BLUETOOTH_SCO
    285         0,  // STREAM_SYSTEM_ENFORCED
    286         0,  // STREAM_DTMF
    287         0   // STREAM_TTS
    288     };
    289 
    290     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
    291      * of another stream: This avoids multiplying the volume settings for hidden
    292      * stream types that follow other stream behavior for volume settings
    293      * NOTE: do not create loops in aliases!
    294      * Some streams alias to different streams according to device category (phone or tablet) or
    295      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
    296      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
    297      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
    298      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
    299     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
    300         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
    301         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
    302         AudioSystem.STREAM_RING,            // STREAM_RING
    303         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
    304         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
    305         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
    306         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
    307         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
    308         AudioSystem.STREAM_RING,            // STREAM_DTMF
    309         AudioSystem.STREAM_MUSIC            // STREAM_TTS
    310     };
    311     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
    312         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
    313         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
    314         AudioSystem.STREAM_MUSIC,       // STREAM_RING
    315         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
    316         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
    317         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
    318         AudioSystem.STREAM_MUSIC,       // STREAM_BLUETOOTH_SCO
    319         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
    320         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
    321         AudioSystem.STREAM_MUSIC        // STREAM_TTS
    322     };
    323     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
    324         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
    325         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
    326         AudioSystem.STREAM_RING,            // STREAM_RING
    327         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
    328         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
    329         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
    330         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
    331         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
    332         AudioSystem.STREAM_RING,            // STREAM_DTMF
    333         AudioSystem.STREAM_MUSIC            // STREAM_TTS
    334     };
    335     private int[] mStreamVolumeAlias;
    336 
    337     /**
    338      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
    339      * after mapping through mStreamVolumeAlias.
    340      */
    341     private static final int[] STREAM_VOLUME_OPS = new int[] {
    342         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
    343         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
    344         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
    345         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
    346         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
    347         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
    348         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
    349         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
    350         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
    351         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
    352     };
    353 
    354     private final boolean mUseFixedVolume;
    355 
    356     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
    357         public void onError(int error) {
    358             switch (error) {
    359             case AudioSystem.AUDIO_STATUS_SERVER_DIED:
    360                 sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
    361                         SENDMSG_NOOP, 0, 0, null, 0);
    362                 break;
    363             default:
    364                 break;
    365             }
    366         }
    367     };
    368 
    369     /**
    370      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
    371      * {@link AudioManager#RINGER_MODE_SILENT}, or
    372      * {@link AudioManager#RINGER_MODE_VIBRATE}.
    373      */
    374     // protected by mSettingsLock
    375     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
    376     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
    377 
    378     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
    379     private int mRingerModeAffectedStreams = 0;
    380 
    381     // Streams currently muted by ringer mode
    382     private int mRingerModeMutedStreams;
    383 
    384     /** Streams that can be muted. Do not resolve to aliases when checking.
    385      * @see System#MUTE_STREAMS_AFFECTED */
    386     private int mMuteAffectedStreams;
    387 
    388     /**
    389      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
    390      * mVibrateSetting is just maintained during deprecation period but vibration policy is
    391      * now only controlled by mHasVibrator and mRingerMode
    392      */
    393     private int mVibrateSetting;
    394 
    395     // Is there a vibrator
    396     private final boolean mHasVibrator;
    397 
    398     // Broadcast receiver for device connections intent broadcasts
    399     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
    400 
    401     /** Interface for UserManagerService. */
    402     private final UserManagerInternal mUserManagerInternal;
    403 
    404     private final UserRestrictionsListener mUserRestrictionsListener =
    405             new AudioServiceUserRestrictionsListener();
    406 
    407     // Devices currently connected
    408     // Use makeDeviceListKey() to make a unique key for this list.
    409     private class DeviceListSpec {
    410         int mDeviceType;
    411         String mDeviceName;
    412         String mDeviceAddress;
    413 
    414         public DeviceListSpec(int deviceType, String deviceName, String deviceAddress) {
    415             mDeviceType = deviceType;
    416             mDeviceName = deviceName;
    417             mDeviceAddress = deviceAddress;
    418         }
    419 
    420         public String toString() {
    421             return "[type:0x" + Integer.toHexString(mDeviceType) + " name:" + mDeviceName
    422                     + " address:" + mDeviceAddress + "]";
    423         }
    424     }
    425 
    426     // Generate a unique key for the mConnectedDevices List by composing the device "type"
    427     // and the "address" associated with a specific instance of that device type
    428     private String makeDeviceListKey(int device, String deviceAddress) {
    429         return "0x" + Integer.toHexString(device) + ":" + deviceAddress;
    430     }
    431 
    432     private final ArrayMap<String, DeviceListSpec> mConnectedDevices = new ArrayMap<>();
    433 
    434     // Forced device usage for communications
    435     private int mForcedUseForComm;
    436 
    437     // List of binder death handlers for setMode() client processes.
    438     // The last process to have called setMode() is at the top of the list.
    439     private final ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>();
    440 
    441     // List of clients having issued a SCO start request
    442     private final ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>();
    443 
    444     // BluetoothHeadset API to control SCO connection
    445     private BluetoothHeadset mBluetoothHeadset;
    446 
    447     // Bluetooth headset device
    448     private BluetoothDevice mBluetoothHeadsetDevice;
    449 
    450     // Indicate if SCO audio connection is currently active and if the initiator is
    451     // audio service (internal) or bluetooth headset (external)
    452     private int mScoAudioState;
    453     // SCO audio state is not active
    454     private static final int SCO_STATE_INACTIVE = 0;
    455     // SCO audio activation request waiting for headset service to connect
    456     private static final int SCO_STATE_ACTIVATE_REQ = 1;
    457     // SCO audio state is active or starting due to a request from AudioManager API
    458     private static final int SCO_STATE_ACTIVE_INTERNAL = 3;
    459     // SCO audio deactivation request waiting for headset service to connect
    460     private static final int SCO_STATE_DEACTIVATE_REQ = 5;
    461 
    462     // SCO audio state is active due to an action in BT handsfree (either voice recognition or
    463     // in call audio)
    464     private static final int SCO_STATE_ACTIVE_EXTERNAL = 2;
    465     // Deactivation request for all SCO connections (initiated by audio mode change)
    466     // waiting for headset service to connect
    467     private static final int SCO_STATE_DEACTIVATE_EXT_REQ = 4;
    468 
    469     // Indicates the mode used for SCO audio connection. The mode is virtual call if the request
    470     // originated from an app targeting an API version before JB MR2 and raw audio after that.
    471     private int mScoAudioMode;
    472     // SCO audio mode is undefined
    473     private static final int SCO_MODE_UNDEFINED = -1;
    474     // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
    475     private static final int SCO_MODE_VIRTUAL_CALL = 0;
    476     // SCO audio mode is raw audio (BluetoothHeadset.connectAudio())
    477     private static final int SCO_MODE_RAW = 1;
    478     // SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition())
    479     private static final int SCO_MODE_VR = 2;
    480 
    481     private static final int SCO_MODE_MAX = 2;
    482 
    483     // Current connection state indicated by bluetooth headset
    484     private int mScoConnectionState;
    485 
    486     // true if boot sequence has been completed
    487     private boolean mSystemReady;
    488     // true if Intent.ACTION_USER_SWITCHED has ever been received
    489     private boolean mUserSwitchedReceived;
    490     // listener for SoundPool sample load completion indication
    491     private SoundPoolCallback mSoundPoolCallBack;
    492     // thread for SoundPool listener
    493     private SoundPoolListenerThread mSoundPoolListenerThread;
    494     // message looper for SoundPool listener
    495     private Looper mSoundPoolLooper = null;
    496     // volume applied to sound played with playSoundEffect()
    497     private static int sSoundEffectVolumeDb;
    498     // previous volume adjustment direction received by checkForRingerModeChange()
    499     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
    500     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
    501     // is controlled by Vol keys.
    502     private int  mVolumeControlStream = -1;
    503     private final Object mForceControlStreamLock = new Object();
    504     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
    505     // server process so in theory it is not necessary to monitor the client death.
    506     // However it is good to be ready for future evolutions.
    507     private ForceControlStreamClient mForceControlStreamClient = null;
    508     // Used to play ringtones outside system_server
    509     private volatile IRingtonePlayer mRingtonePlayer;
    510 
    511     private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
    512 
    513     // Request to override default use of A2DP for media.
    514     private boolean mBluetoothA2dpEnabled;
    515     private final Object mBluetoothA2dpEnabledLock = new Object();
    516 
    517     // Monitoring of audio routes.  Protected by mCurAudioRoutes.
    518     final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
    519     final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers
    520             = new RemoteCallbackList<IAudioRoutesObserver>();
    521 
    522     // Devices for which the volume is fixed and VolumePanel slider should be disabled
    523     int mFixedVolumeDevices = AudioSystem.DEVICE_OUT_HDMI |
    524             AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET |
    525             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET |
    526             AudioSystem.DEVICE_OUT_HDMI_ARC |
    527             AudioSystem.DEVICE_OUT_SPDIF |
    528             AudioSystem.DEVICE_OUT_AUX_LINE;
    529     int mFullVolumeDevices = 0;
    530 
    531     // TODO merge orientation and rotation
    532     private final boolean mMonitorOrientation;
    533     private final boolean mMonitorRotation;
    534 
    535     private boolean mDockAudioMediaEnabled = true;
    536 
    537     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
    538 
    539     // Used when safe volume warning message display is requested by setStreamVolume(). In this
    540     // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand
    541     // and used later when/if disableSafeMediaVolume() is called.
    542     private StreamVolumeCommand mPendingVolumeCommand;
    543 
    544     private PowerManager.WakeLock mAudioEventWakeLock;
    545 
    546     private final MediaFocusControl mMediaFocusControl;
    547 
    548     // Reference to BluetoothA2dp to query for AbsoluteVolume.
    549     private BluetoothA2dp mA2dp;
    550     // lock always taken synchronized on mConnectedDevices
    551     private final Object mA2dpAvrcpLock = new Object();
    552     // If absolute volume is supported in AVRCP device
    553     private boolean mAvrcpAbsVolSupported = false;
    554 
    555     private static Long mLastDeviceConnectMsgTime = new Long(0);
    556 
    557     private NotificationManager mNm;
    558     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
    559     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
    560     private long mLoweredFromNormalToVibrateTime;
    561 
    562     // Intent "extra" data keys.
    563     public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName";
    564     public static final String CONNECT_INTENT_KEY_STATE = "state";
    565     public static final String CONNECT_INTENT_KEY_ADDRESS = "address";
    566     public static final String CONNECT_INTENT_KEY_HAS_PLAYBACK = "hasPlayback";
    567     public static final String CONNECT_INTENT_KEY_HAS_CAPTURE = "hasCapture";
    568     public static final String CONNECT_INTENT_KEY_HAS_MIDI = "hasMIDI";
    569     public static final String CONNECT_INTENT_KEY_DEVICE_CLASS = "class";
    570 
    571     // Defines the format for the connection "address" for ALSA devices
    572     public static String makeAlsaAddressString(int card, int device) {
    573         return "card=" + card + ";device=" + device + ";";
    574     }
    575 
    576     public static final class Lifecycle extends SystemService {
    577         private AudioService mService;
    578 
    579         public Lifecycle(Context context) {
    580             super(context);
    581             mService = new AudioService(context);
    582         }
    583 
    584         @Override
    585         public void onStart() {
    586             publishBinderService(Context.AUDIO_SERVICE, mService);
    587         }
    588 
    589         @Override
    590         public void onBootPhase(int phase) {
    591             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
    592                 mService.systemReady();
    593             }
    594         }
    595     }
    596 
    597     ///////////////////////////////////////////////////////////////////////////
    598     // Construction
    599     ///////////////////////////////////////////////////////////////////////////
    600 
    601     /** @hide */
    602     public AudioService(Context context) {
    603         mContext = context;
    604         mContentResolver = context.getContentResolver();
    605         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
    606 
    607         mPlatformType = AudioSystem.getPlatformType(context);
    608 
    609         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
    610 
    611         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    612         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
    613 
    614         Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    615         mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
    616 
    617         // Initialize volume
    618         int maxVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps",
    619                 MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
    620         if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
    621             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxVolume;
    622             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = (maxVolume * 3) / 4;
    623         }
    624         maxVolume = SystemProperties.getInt("ro.config.media_vol_steps",
    625                 MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
    626         if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
    627             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume;
    628             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4;
    629         }
    630 
    631         sSoundEffectVolumeDb = context.getResources().getInteger(
    632                 com.android.internal.R.integer.config_soundEffectVolumeDb);
    633 
    634         mForcedUseForComm = AudioSystem.FORCE_NONE;
    635 
    636         createAudioSystemThread();
    637 
    638         AudioSystem.setErrorCallback(mAudioSystemCallback);
    639 
    640         boolean cameraSoundForced = readCameraSoundForced();
    641         mCameraSoundForced = new Boolean(cameraSoundForced);
    642         sendMsg(mAudioHandler,
    643                 MSG_SET_FORCE_USE,
    644                 SENDMSG_QUEUE,
    645                 AudioSystem.FOR_SYSTEM,
    646                 cameraSoundForced ?
    647                         AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
    648                 null,
    649                 0);
    650 
    651         mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver,
    652                                                         Settings.Global.AUDIO_SAFE_VOLUME_STATE,
    653                                                         SAFE_MEDIA_VOLUME_NOT_CONFIGURED));
    654         // The default safe volume index read here will be replaced by the actual value when
    655         // the mcc is read by onConfigureSafeVolume()
    656         mSafeMediaVolumeIndex = mContext.getResources().getInteger(
    657                 com.android.internal.R.integer.config_safe_media_volume_index) * 10;
    658 
    659         mUseFixedVolume = mContext.getResources().getBoolean(
    660                 com.android.internal.R.bool.config_useFixedVolume);
    661 
    662         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
    663         // array initialized by updateStreamVolumeAlias()
    664         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
    665         readPersistedSettings();
    666         readUserRestrictions();
    667         mSettingsObserver = new SettingsObserver();
    668         createStreamStates();
    669 
    670         mMediaFocusControl = new MediaFocusControl(mContext);
    671 
    672         readAndSetLowRamDevice();
    673 
    674         // Call setRingerModeInt() to apply correct mute
    675         // state on streams affected by ringer mode.
    676         mRingerModeMutedStreams = 0;
    677         setRingerModeInt(getRingerModeInternal(), false);
    678 
    679         // Register for device connection intent broadcasts.
    680         IntentFilter intentFilter =
    681                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
    682         intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
    683         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
    684         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
    685         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
    686         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
    687         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
    688         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
    689         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    690         intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
    691 
    692         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
    693         // TODO merge orientation and rotation
    694         mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false);
    695         if (mMonitorOrientation) {
    696             Log.v(TAG, "monitoring device orientation");
    697             // initialize orientation in AudioSystem
    698             setOrientationForAudioSystem();
    699         }
    700         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
    701         if (mMonitorRotation) {
    702             RotationHelper.init(mContext, mAudioHandler);
    703         }
    704 
    705         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
    706 
    707         LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
    708 
    709         mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
    710 
    711         mRecordMonitor.initMonitor();
    712     }
    713 
    714     public void systemReady() {
    715         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
    716                 0, 0, null, 0);
    717     }
    718 
    719     public void onSystemReady() {
    720         mSystemReady = true;
    721         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE,
    722                 0, 0, null, 0);
    723 
    724         mScoConnectionState = AudioManager.SCO_AUDIO_STATE_ERROR;
    725         resetBluetoothSco();
    726         getBluetoothHeadset();
    727         //FIXME: this is to maintain compatibility with deprecated intent
    728         // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
    729         Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
    730         newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE,
    731                 AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
    732         sendStickyBroadcastToAll(newIntent);
    733 
    734         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    735         if (adapter != null) {
    736             adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
    737                                     BluetoothProfile.A2DP);
    738         }
    739 
    740         mHdmiManager =
    741                 (HdmiControlManager) mContext.getSystemService(Context.HDMI_CONTROL_SERVICE);
    742         if (mHdmiManager != null) {
    743             synchronized (mHdmiManager) {
    744                 mHdmiTvClient = mHdmiManager.getTvClient();
    745                 if (mHdmiTvClient != null) {
    746                     mFixedVolumeDevices &= ~AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER;
    747                 }
    748                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
    749                 mHdmiCecSink = false;
    750             }
    751         }
    752 
    753         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    754 
    755         sendMsg(mAudioHandler,
    756                 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,
    757                 SENDMSG_REPLACE,
    758                 0,
    759                 0,
    760                 TAG,
    761                 SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
    762 
    763         StreamOverride.init(mContext);
    764         mControllerService.init();
    765         onIndicateSystemReady();
    766     }
    767 
    768     void onIndicateSystemReady() {
    769         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
    770             return;
    771         }
    772         sendMsg(mAudioHandler,
    773                 MSG_INDICATE_SYSTEM_READY,
    774                 SENDMSG_REPLACE,
    775                 0,
    776                 0,
    777                 null,
    778                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
    779     }
    780 
    781     public void onAudioServerDied() {
    782         if (!mSystemReady ||
    783                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
    784             Log.e(TAG, "Audioserver died.");
    785             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
    786                     null, 500);
    787             return;
    788         }
    789         Log.e(TAG, "Audioserver started.");
    790 
    791         // indicate to audio HAL that we start the reconfiguration phase after a media
    792         // server crash
    793         // Note that we only execute this when the media server
    794         // process restarts after a crash, not the first time it is started.
    795         AudioSystem.setParameters("restarting=true");
    796 
    797         readAndSetLowRamDevice();
    798 
    799         // Restore device connection states
    800         synchronized (mConnectedDevices) {
    801             for (int i = 0; i < mConnectedDevices.size(); i++) {
    802                 DeviceListSpec spec = mConnectedDevices.valueAt(i);
    803                 AudioSystem.setDeviceConnectionState(
    804                                                 spec.mDeviceType,
    805                                                 AudioSystem.DEVICE_STATE_AVAILABLE,
    806                                                 spec.mDeviceAddress,
    807                                                 spec.mDeviceName);
    808             }
    809         }
    810         // Restore call state
    811         AudioSystem.setPhoneState(mMode);
    812 
    813         // Restore forced usage for communcations and record
    814         AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm);
    815         AudioSystem.setForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm);
    816         AudioSystem.setForceUse(AudioSystem.FOR_SYSTEM, mCameraSoundForced ?
    817                         AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE);
    818 
    819         // Restore stream volumes
    820         int numStreamTypes = AudioSystem.getNumStreamTypes();
    821         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
    822             VolumeStreamState streamState = mStreamStates[streamType];
    823             AudioSystem.initStreamVolume(
    824                 streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
    825 
    826             streamState.applyAllVolumes();
    827         }
    828 
    829         // Restore mono mode
    830         updateMasterMono(mContentResolver);
    831 
    832         // Restore ringer mode
    833         setRingerModeInt(getRingerModeInternal(), false);
    834 
    835         // Reset device orientation (if monitored for this device)
    836         if (mMonitorOrientation) {
    837             setOrientationForAudioSystem();
    838         }
    839         if (mMonitorRotation) {
    840             RotationHelper.updateOrientation();
    841         }
    842 
    843         synchronized (mBluetoothA2dpEnabledLock) {
    844             AudioSystem.setForceUse(AudioSystem.FOR_MEDIA,
    845                     mBluetoothA2dpEnabled ?
    846                             AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP);
    847         }
    848 
    849         synchronized (mSettingsLock) {
    850             AudioSystem.setForceUse(AudioSystem.FOR_DOCK,
    851                     mDockAudioMediaEnabled ?
    852                             AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE);
    853             sendEncodedSurroundMode(mContentResolver);
    854         }
    855         if (mHdmiManager != null) {
    856             synchronized (mHdmiManager) {
    857                 if (mHdmiTvClient != null) {
    858                     setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
    859                 }
    860             }
    861         }
    862 
    863         synchronized (mAudioPolicies) {
    864             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
    865                 policy.connectMixes();
    866             }
    867         }
    868 
    869         onIndicateSystemReady();
    870         // indicate the end of reconfiguration phase to audio HAL
    871         AudioSystem.setParameters("restarting=false");
    872     }
    873 
    874     private void createAudioSystemThread() {
    875         mAudioSystemThread = new AudioSystemThread();
    876         mAudioSystemThread.start();
    877         waitForAudioHandlerCreation();
    878     }
    879 
    880     /** Waits for the volume handler to be created by the other thread. */
    881     private void waitForAudioHandlerCreation() {
    882         synchronized(this) {
    883             while (mAudioHandler == null) {
    884                 try {
    885                     // Wait for mAudioHandler to be set by the other thread
    886                     wait();
    887                 } catch (InterruptedException e) {
    888                     Log.e(TAG, "Interrupted while waiting on volume handler.");
    889                 }
    890             }
    891         }
    892     }
    893 
    894     private void checkAllAliasStreamVolumes() {
    895         synchronized (VolumeStreamState.class) {
    896             int numStreamTypes = AudioSystem.getNumStreamTypes();
    897             for (int streamType = 0; streamType < numStreamTypes; streamType++) {
    898                 if (streamType != mStreamVolumeAlias[streamType]) {
    899                     mStreamStates[streamType].
    900                                     setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]],
    901                                             TAG);
    902                 }
    903                 // apply stream volume
    904                 if (!mStreamStates[streamType].mIsMuted) {
    905                     mStreamStates[streamType].applyAllVolumes();
    906                 }
    907             }
    908         }
    909     }
    910 
    911     private void checkAllFixedVolumeDevices()
    912     {
    913         int numStreamTypes = AudioSystem.getNumStreamTypes();
    914         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
    915             mStreamStates[streamType].checkFixedVolumeDevices();
    916         }
    917     }
    918 
    919     private void checkAllFixedVolumeDevices(int streamType) {
    920         mStreamStates[streamType].checkFixedVolumeDevices();
    921     }
    922 
    923     private void checkMuteAffectedStreams() {
    924         // any stream with a min level > 0 is not muteable by definition
    925         for (int i = 0; i < mStreamStates.length; i++) {
    926             final VolumeStreamState vss = mStreamStates[i];
    927             if (vss.mIndexMin > 0) {
    928                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
    929             }
    930         }
    931     }
    932 
    933     private void createStreamStates() {
    934         int numStreamTypes = AudioSystem.getNumStreamTypes();
    935         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
    936 
    937         for (int i = 0; i < numStreamTypes; i++) {
    938             streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[mStreamVolumeAlias[i]], i);
    939         }
    940 
    941         checkAllFixedVolumeDevices();
    942         checkAllAliasStreamVolumes();
    943         checkMuteAffectedStreams();
    944     }
    945 
    946     private void dumpStreamStates(PrintWriter pw) {
    947         pw.println("\nStream volumes (device: index)");
    948         int numStreamTypes = AudioSystem.getNumStreamTypes();
    949         for (int i = 0; i < numStreamTypes; i++) {
    950             pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":");
    951             mStreamStates[i].dump(pw);
    952             pw.println("");
    953         }
    954         pw.print("\n- mute affected streams = 0x");
    955         pw.println(Integer.toHexString(mMuteAffectedStreams));
    956     }
    957 
    958     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
    959         int dtmfStreamAlias;
    960 
    961         switch (mPlatformType) {
    962         case AudioSystem.PLATFORM_VOICE:
    963             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE;
    964             dtmfStreamAlias = AudioSystem.STREAM_RING;
    965             break;
    966         case AudioSystem.PLATFORM_TELEVISION:
    967             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
    968             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
    969             break;
    970         default:
    971             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT;
    972             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
    973         }
    974 
    975         if (isPlatformTelevision()) {
    976             mRingerModeAffectedStreams = 0;
    977         } else {
    978             if (isInCommunication()) {
    979                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
    980                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
    981             } else {
    982                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
    983             }
    984         }
    985 
    986         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
    987         if (updateVolumes) {
    988             mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
    989                     caller);
    990             // apply stream mute states according to new value of mRingerModeAffectedStreams
    991             setRingerModeInt(getRingerModeInternal(), false);
    992             sendMsg(mAudioHandler,
    993                     MSG_SET_ALL_VOLUMES,
    994                     SENDMSG_QUEUE,
    995                     0,
    996                     0,
    997                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
    998         }
    999     }
   1000 
   1001     private void readDockAudioSettings(ContentResolver cr)
   1002     {
   1003         mDockAudioMediaEnabled = Settings.Global.getInt(
   1004                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
   1005 
   1006         sendMsg(mAudioHandler,
   1007                 MSG_SET_FORCE_USE,
   1008                 SENDMSG_QUEUE,
   1009                 AudioSystem.FOR_DOCK,
   1010                 mDockAudioMediaEnabled ?
   1011                         AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE,
   1012                 null,
   1013                 0);
   1014     }
   1015 
   1016 
   1017     private void updateMasterMono(ContentResolver cr)
   1018     {
   1019         final boolean masterMono = System.getIntForUser(
   1020                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
   1021         if (DEBUG_VOL) {
   1022             Log.d(TAG, String.format("Master mono %b", masterMono));
   1023         }
   1024         AudioSystem.setMasterMono(masterMono);
   1025     }
   1026 
   1027     private void sendEncodedSurroundMode(ContentResolver cr)
   1028     {
   1029         int encodedSurroundMode = Settings.Global.getInt(
   1030                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
   1031                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
   1032         sendEncodedSurroundMode(encodedSurroundMode);
   1033     }
   1034 
   1035     private void sendEncodedSurroundMode(int encodedSurroundMode)
   1036     {
   1037         // initialize to guaranteed bad value
   1038         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
   1039         switch (encodedSurroundMode) {
   1040             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
   1041                 forceSetting = AudioSystem.FORCE_NONE;
   1042                 break;
   1043             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
   1044                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
   1045                 break;
   1046             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
   1047                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
   1048                 break;
   1049             default:
   1050                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
   1051                         + encodedSurroundMode);
   1052                 break;
   1053         }
   1054         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
   1055             sendMsg(mAudioHandler,
   1056                     MSG_SET_FORCE_USE,
   1057                     SENDMSG_QUEUE,
   1058                     AudioSystem.FOR_ENCODED_SURROUND,
   1059                     forceSetting,
   1060                     null,
   1061                     0);
   1062         }
   1063     }
   1064 
   1065     private void readPersistedSettings() {
   1066         final ContentResolver cr = mContentResolver;
   1067 
   1068         int ringerModeFromSettings =
   1069                 Settings.Global.getInt(
   1070                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
   1071         int ringerMode = ringerModeFromSettings;
   1072         // sanity check in case the settings are restored from a device with incompatible
   1073         // ringer modes
   1074         if (!isValidRingerMode(ringerMode)) {
   1075             ringerMode = AudioManager.RINGER_MODE_NORMAL;
   1076         }
   1077         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
   1078             ringerMode = AudioManager.RINGER_MODE_SILENT;
   1079         }
   1080         if (ringerMode != ringerModeFromSettings) {
   1081             Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode);
   1082         }
   1083         if (mUseFixedVolume || isPlatformTelevision()) {
   1084             ringerMode = AudioManager.RINGER_MODE_NORMAL;
   1085         }
   1086         synchronized(mSettingsLock) {
   1087             mRingerMode = ringerMode;
   1088             if (mRingerModeExternal == -1) {
   1089                 mRingerModeExternal = mRingerMode;
   1090             }
   1091 
   1092             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
   1093             // are still needed while setVibrateSetting() and getVibrateSetting() are being
   1094             // deprecated.
   1095             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
   1096                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
   1097                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
   1098                                                             : AudioManager.VIBRATE_SETTING_OFF);
   1099             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
   1100                                             AudioManager.VIBRATE_TYPE_RINGER,
   1101                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
   1102                                                             : AudioManager.VIBRATE_SETTING_OFF);
   1103 
   1104             updateRingerModeAffectedStreams();
   1105             readDockAudioSettings(cr);
   1106             sendEncodedSurroundMode(cr);
   1107         }
   1108 
   1109         mMuteAffectedStreams = System.getIntForUser(cr,
   1110                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
   1111                 UserHandle.USER_CURRENT);
   1112 
   1113         updateMasterMono(cr);
   1114 
   1115         // Each stream will read its own persisted settings
   1116 
   1117         // Broadcast the sticky intents
   1118         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
   1119         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
   1120 
   1121         // Broadcast vibrate settings
   1122         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
   1123         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
   1124 
   1125         // Load settings for the volume controller
   1126         mVolumeController.loadSettings(cr);
   1127     }
   1128 
   1129     private void readUserRestrictions() {
   1130         final int currentUser = getCurrentUserId();
   1131 
   1132         // Check the current user restriction.
   1133         boolean masterMute =
   1134                 mUserManagerInternal.getUserRestriction(currentUser,
   1135                         UserManager.DISALLLOW_UNMUTE_DEVICE)
   1136                         || mUserManagerInternal.getUserRestriction(currentUser,
   1137                         UserManager.DISALLOW_ADJUST_VOLUME);
   1138         if (mUseFixedVolume) {
   1139             masterMute = false;
   1140             AudioSystem.setMasterVolume(1.0f);
   1141         }
   1142         if (DEBUG_VOL) {
   1143             Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
   1144         }
   1145         setSystemAudioMute(masterMute);
   1146         AudioSystem.setMasterMute(masterMute);
   1147         broadcastMasterMuteStatus(masterMute);
   1148 
   1149         boolean microphoneMute = mUserManagerInternal.getUserRestriction(
   1150                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
   1151         if (DEBUG_VOL) {
   1152             Log.d(TAG, String.format("Mic mute %s, user=%d", microphoneMute, currentUser));
   1153         }
   1154         AudioSystem.muteMicrophone(microphoneMute);
   1155     }
   1156 
   1157     private int rescaleIndex(int index, int srcStream, int dstStream) {
   1158         return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex();
   1159     }
   1160 
   1161     ///////////////////////////////////////////////////////////////////////////
   1162     // IPC methods
   1163     ///////////////////////////////////////////////////////////////////////////
   1164     /** @see AudioManager#adjustVolume(int, int) */
   1165     public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
   1166             String callingPackage, String caller) {
   1167         adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
   1168                 caller, Binder.getCallingUid());
   1169     }
   1170 
   1171     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
   1172             String callingPackage, String caller, int uid) {
   1173         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
   1174                 + ", flags=" + flags + ", caller=" + caller);
   1175         int streamType;
   1176         boolean isMute = isMuteAdjust(direction);
   1177         if (mVolumeControlStream != -1) {
   1178             streamType = mVolumeControlStream;
   1179         } else {
   1180             streamType = getActiveStreamType(suggestedStreamType);
   1181         }
   1182         ensureValidStreamType(streamType);
   1183         final int resolvedStream = mStreamVolumeAlias[streamType];
   1184 
   1185         // Play sounds on STREAM_RING only.
   1186         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
   1187                 resolvedStream != AudioSystem.STREAM_RING) {
   1188             flags &= ~AudioManager.FLAG_PLAY_SOUND;
   1189         }
   1190 
   1191         // For notifications/ring, show the ui before making any adjustments
   1192         // Don't suppress mute/unmute requests
   1193         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {
   1194             direction = 0;
   1195             flags &= ~AudioManager.FLAG_PLAY_SOUND;
   1196             flags &= ~AudioManager.FLAG_VIBRATE;
   1197             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
   1198         }
   1199 
   1200         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
   1201     }
   1202 
   1203     /** @see AudioManager#adjustStreamVolume(int, int, int) */
   1204     public void adjustStreamVolume(int streamType, int direction, int flags,
   1205             String callingPackage) {
   1206         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
   1207                 Binder.getCallingUid());
   1208     }
   1209 
   1210     private void adjustStreamVolume(int streamType, int direction, int flags,
   1211             String callingPackage, String caller, int uid) {
   1212         if (mUseFixedVolume) {
   1213             return;
   1214         }
   1215         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
   1216                 + ", flags=" + flags + ", caller=" + caller);
   1217 
   1218         ensureValidDirection(direction);
   1219         ensureValidStreamType(streamType);
   1220 
   1221         boolean isMuteAdjust = isMuteAdjust(direction);
   1222 
   1223         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
   1224             return;
   1225         }
   1226 
   1227         // use stream type alias here so that streams with same alias have the same behavior,
   1228         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
   1229         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
   1230         int streamTypeAlias = mStreamVolumeAlias[streamType];
   1231 
   1232         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
   1233 
   1234         final int device = getDeviceForStream(streamTypeAlias);
   1235 
   1236         int aliasIndex = streamState.getIndex(device);
   1237         boolean adjustVolume = true;
   1238         int step;
   1239 
   1240         // skip a2dp absolute volume control request when the device
   1241         // is not an a2dp device
   1242         if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 &&
   1243             (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
   1244             return;
   1245         }
   1246 
   1247         // If we are being called by the system (e.g. hardware keys) check for current user
   1248         // so we handle user restrictions correctly.
   1249         if (uid == android.os.Process.SYSTEM_UID) {
   1250             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
   1251         }
   1252         if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
   1253                 != AppOpsManager.MODE_ALLOWED) {
   1254             return;
   1255         }
   1256 
   1257         // reset any pending volume command
   1258         synchronized (mSafeMediaVolumeState) {
   1259             mPendingVolumeCommand = null;
   1260         }
   1261 
   1262         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
   1263         if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
   1264                ((device & mFixedVolumeDevices) != 0)) {
   1265             flags |= AudioManager.FLAG_FIXED_VOLUME;
   1266 
   1267             // Always toggle between max safe volume and 0 for fixed volume devices where safe
   1268             // volume is enforced, and max and 0 for the others.
   1269             // This is simulated by stepping by the full allowed volume range
   1270             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
   1271                     (device & mSafeMediaVolumeDevices) != 0) {
   1272                 step = mSafeMediaVolumeIndex;
   1273             } else {
   1274                 step = streamState.getMaxIndex();
   1275             }
   1276             if (aliasIndex != 0) {
   1277                 aliasIndex = step;
   1278             }
   1279         } else {
   1280             // convert one UI step (+/-1) into a number of internal units on the stream alias
   1281             step = rescaleIndex(10, streamType, streamTypeAlias);
   1282         }
   1283 
   1284         // If either the client forces allowing ringer modes for this adjustment,
   1285         // or the stream type is one that is affected by ringer modes
   1286         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
   1287                 (streamTypeAlias == getUiSoundsStreamType())) {
   1288             int ringerMode = getRingerModeInternal();
   1289             // do not vibrate if already in vibrate mode
   1290             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
   1291                 flags &= ~AudioManager.FLAG_VIBRATE;
   1292             }
   1293             // Check if the ringer mode handles this adjustment. If it does we don't
   1294             // need to adjust the volume further.
   1295             final int result = checkForRingerModeChange(aliasIndex, direction, step,
   1296                     streamState.mIsMuted, callingPackage, flags);
   1297             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
   1298             // If suppressing a volume adjustment in silent mode, display the UI hint
   1299             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
   1300                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
   1301             }
   1302             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
   1303             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
   1304                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
   1305             }
   1306         }
   1307         // If the ringermode is suppressing media, prevent changes
   1308         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
   1309             adjustVolume = false;
   1310         }
   1311         int oldIndex = mStreamStates[streamType].getIndex(device);
   1312 
   1313         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
   1314             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
   1315 
   1316             // Check if volume update should be send to AVRCP
   1317             if (streamTypeAlias == AudioSystem.STREAM_MUSIC &&
   1318                 (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
   1319                 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
   1320                 synchronized (mA2dpAvrcpLock) {
   1321                     if (mA2dp != null && mAvrcpAbsVolSupported) {
   1322                         mA2dp.adjustAvrcpAbsoluteVolume(direction);
   1323                     }
   1324                 }
   1325             }
   1326 
   1327             if (isMuteAdjust) {
   1328                 boolean state;
   1329                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
   1330                     state = !streamState.mIsMuted;
   1331                 } else {
   1332                     state = direction == AudioManager.ADJUST_MUTE;
   1333                 }
   1334                 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
   1335                     setSystemAudioMute(state);
   1336                 }
   1337                 for (int stream = 0; stream < mStreamStates.length; stream++) {
   1338                     if (streamTypeAlias == mStreamVolumeAlias[stream]) {
   1339                         if (!(readCameraSoundForced()
   1340                                     && (mStreamStates[stream].getStreamType()
   1341                                         == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
   1342                             mStreamStates[stream].mute(state);
   1343                         }
   1344                     }
   1345                 }
   1346             } else if ((direction == AudioManager.ADJUST_RAISE) &&
   1347                     !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
   1348                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
   1349                 mVolumeController.postDisplaySafeVolumeWarning(flags);
   1350             } else if (streamState.adjustIndex(direction * step, device, caller)
   1351                     || streamState.mIsMuted) {
   1352                 // Post message to set system volume (it in turn will post a
   1353                 // message to persist).
   1354                 if (streamState.mIsMuted) {
   1355                     // Unmute the stream if it was previously muted
   1356                     if (direction == AudioManager.ADJUST_RAISE) {
   1357                         // unmute immediately for volume up
   1358                         streamState.mute(false);
   1359                     } else if (direction == AudioManager.ADJUST_LOWER) {
   1360                         if (mPlatformType == AudioSystem.PLATFORM_TELEVISION) {
   1361                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
   1362                                     streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
   1363                         }
   1364                     }
   1365                 }
   1366                 sendMsg(mAudioHandler,
   1367                         MSG_SET_DEVICE_VOLUME,
   1368                         SENDMSG_QUEUE,
   1369                         device,
   1370                         0,
   1371                         streamState,
   1372                         0);
   1373             }
   1374 
   1375             // Check if volume update should be sent to Hdmi system audio.
   1376             int newIndex = mStreamStates[streamType].getIndex(device);
   1377             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
   1378                 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
   1379             }
   1380             if (mHdmiManager != null) {
   1381                 synchronized (mHdmiManager) {
   1382                     // mHdmiCecSink true => mHdmiPlaybackClient != null
   1383                     if (mHdmiCecSink &&
   1384                             streamTypeAlias == AudioSystem.STREAM_MUSIC &&
   1385                             oldIndex != newIndex) {
   1386                         synchronized (mHdmiPlaybackClient) {
   1387                             int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN :
   1388                                     KeyEvent.KEYCODE_VOLUME_UP;
   1389                             final long ident = Binder.clearCallingIdentity();
   1390                             try {
   1391                                 mHdmiPlaybackClient.sendKeyEvent(keyCode, true);
   1392                                 mHdmiPlaybackClient.sendKeyEvent(keyCode, false);
   1393                             } finally {
   1394                                 Binder.restoreCallingIdentity(ident);
   1395                             }
   1396                         }
   1397                     }
   1398                 }
   1399             }
   1400         }
   1401         int index = mStreamStates[streamType].getIndex(device);
   1402         sendVolumeUpdate(streamType, oldIndex, index, flags);
   1403     }
   1404 
   1405     // Called after a delay when volume down is pressed while muted
   1406     private void onUnmuteStream(int stream, int flags) {
   1407         VolumeStreamState streamState = mStreamStates[stream];
   1408         streamState.mute(false);
   1409 
   1410         final int device = getDeviceForStream(stream);
   1411         final int index = mStreamStates[stream].getIndex(device);
   1412         sendVolumeUpdate(stream, index, index, flags);
   1413     }
   1414 
   1415     private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) {
   1416         if (mHdmiManager == null
   1417                 || mHdmiTvClient == null
   1418                 || oldVolume == newVolume
   1419                 || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0) return;
   1420 
   1421         // Sets the audio volume of AVR when we are in system audio mode. The new volume info
   1422         // is tranformed to HDMI-CEC commands and passed through CEC bus.
   1423         synchronized (mHdmiManager) {
   1424             if (!mHdmiSystemAudioSupported) return;
   1425             synchronized (mHdmiTvClient) {
   1426                 final long token = Binder.clearCallingIdentity();
   1427                 try {
   1428                     mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume);
   1429                 } finally {
   1430                     Binder.restoreCallingIdentity(token);
   1431                 }
   1432             }
   1433         }
   1434     }
   1435 
   1436     // StreamVolumeCommand contains the information needed to defer the process of
   1437     // setStreamVolume() in case the user has to acknowledge the safe volume warning message.
   1438     class StreamVolumeCommand {
   1439         public final int mStreamType;
   1440         public final int mIndex;
   1441         public final int mFlags;
   1442         public final int mDevice;
   1443 
   1444         StreamVolumeCommand(int streamType, int index, int flags, int device) {
   1445             mStreamType = streamType;
   1446             mIndex = index;
   1447             mFlags = flags;
   1448             mDevice = device;
   1449         }
   1450 
   1451         @Override
   1452         public String toString() {
   1453             return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
   1454                     .append(mIndex).append(",flags=").append(mFlags).append(",device=")
   1455                     .append(mDevice).append('}').toString();
   1456         }
   1457     };
   1458 
   1459     private int getNewRingerMode(int stream, int index, int flags) {
   1460         // setting volume on ui sounds stream type also controls silent mode
   1461         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
   1462                 (stream == getUiSoundsStreamType())) {
   1463             int newRingerMode;
   1464             if (index == 0) {
   1465                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
   1466                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
   1467                                 : AudioManager.RINGER_MODE_NORMAL;
   1468             } else {
   1469                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
   1470             }
   1471             return newRingerMode;
   1472         }
   1473         return getRingerModeExternal();
   1474     }
   1475 
   1476     private boolean isAndroidNPlus(String caller) {
   1477         try {
   1478             final ApplicationInfo applicationInfo =
   1479                     mContext.getPackageManager().getApplicationInfoAsUser(
   1480                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
   1481             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
   1482                 return true;
   1483             }
   1484             return false;
   1485         } catch (PackageManager.NameNotFoundException e) {
   1486             return true;
   1487         }
   1488     }
   1489 
   1490     private boolean wouldToggleZenMode(int newMode) {
   1491         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
   1492                 && newMode != AudioManager.RINGER_MODE_SILENT) {
   1493             return true;
   1494         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
   1495                 && newMode == AudioManager.RINGER_MODE_SILENT) {
   1496             return true;
   1497         }
   1498         return false;
   1499     }
   1500 
   1501     private void onSetStreamVolume(int streamType, int index, int flags, int device,
   1502             String caller) {
   1503         final int stream = mStreamVolumeAlias[streamType];
   1504         setStreamVolumeInt(stream, index, device, false, caller);
   1505         // setting volume on ui sounds stream type also controls silent mode
   1506         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
   1507                 (stream == getUiSoundsStreamType())) {
   1508             setRingerMode(getNewRingerMode(stream, index, flags),
   1509                     TAG + ".onSetStreamVolume", false /*external*/);
   1510         }
   1511         // setting non-zero volume for a muted stream unmutes the stream and vice versa
   1512         mStreamStates[stream].mute(index == 0);
   1513     }
   1514 
   1515     /** @see AudioManager#setStreamVolume(int, int, int) */
   1516     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
   1517         setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
   1518                 Binder.getCallingUid());
   1519     }
   1520 
   1521     private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
   1522             String caller, int uid) {
   1523         if (mUseFixedVolume) {
   1524             return;
   1525         }
   1526 
   1527         ensureValidStreamType(streamType);
   1528         int streamTypeAlias = mStreamVolumeAlias[streamType];
   1529         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
   1530 
   1531         final int device = getDeviceForStream(streamType);
   1532         int oldIndex;
   1533 
   1534         // skip a2dp absolute volume control request when the device
   1535         // is not an a2dp device
   1536         if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 &&
   1537             (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
   1538             return;
   1539         }
   1540         // If we are being called by the system (e.g. hardware keys) check for current user
   1541         // so we handle user restrictions correctly.
   1542         if (uid == android.os.Process.SYSTEM_UID) {
   1543             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
   1544         }
   1545         if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
   1546                 != AppOpsManager.MODE_ALLOWED) {
   1547             return;
   1548         }
   1549 
   1550         if (isAndroidNPlus(callingPackage)
   1551                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
   1552                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
   1553             throw new SecurityException("Not allowed to change Do Not Disturb state");
   1554         }
   1555 
   1556         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
   1557             return;
   1558         }
   1559 
   1560         synchronized (mSafeMediaVolumeState) {
   1561             // reset any pending volume command
   1562             mPendingVolumeCommand = null;
   1563 
   1564             oldIndex = streamState.getIndex(device);
   1565 
   1566             index = rescaleIndex(index * 10, streamType, streamTypeAlias);
   1567 
   1568             if (streamTypeAlias == AudioSystem.STREAM_MUSIC &&
   1569                 (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
   1570                 (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
   1571                 synchronized (mA2dpAvrcpLock) {
   1572                     if (mA2dp != null && mAvrcpAbsVolSupported) {
   1573                         mA2dp.setAvrcpAbsoluteVolume(index / 10);
   1574                     }
   1575                 }
   1576             }
   1577 
   1578             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
   1579                 setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags);
   1580             }
   1581 
   1582             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
   1583             if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
   1584                     ((device & mFixedVolumeDevices) != 0)) {
   1585                 flags |= AudioManager.FLAG_FIXED_VOLUME;
   1586 
   1587                 // volume is either 0 or max allowed for fixed volume devices
   1588                 if (index != 0) {
   1589                     if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
   1590                             (device & mSafeMediaVolumeDevices) != 0) {
   1591                         index = mSafeMediaVolumeIndex;
   1592                     } else {
   1593                         index = streamState.getMaxIndex();
   1594                     }
   1595                 }
   1596             }
   1597 
   1598             if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
   1599                 mVolumeController.postDisplaySafeVolumeWarning(flags);
   1600                 mPendingVolumeCommand = new StreamVolumeCommand(
   1601                                                     streamType, index, flags, device);
   1602             } else {
   1603                 onSetStreamVolume(streamType, index, flags, device, caller);
   1604                 index = mStreamStates[streamType].getIndex(device);
   1605             }
   1606         }
   1607         sendVolumeUpdate(streamType, oldIndex, index, flags);
   1608     }
   1609 
   1610     // No ringer affected streams can be changed in total silence mode except those that
   1611     // will cause the device to exit total silence mode.
   1612     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
   1613         if (mNm.getZenMode() == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
   1614                 && isStreamMutedByRingerMode(streamTypeAlias)) {
   1615             if (!(((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
   1616                     (streamTypeAlias == getUiSoundsStreamType()))) {
   1617                 return false;
   1618             }
   1619         }
   1620         return true;
   1621     }
   1622 
   1623     /** @see AudioManager#forceVolumeControlStream(int) */
   1624     public void forceVolumeControlStream(int streamType, IBinder cb) {
   1625         synchronized(mForceControlStreamLock) {
   1626             mVolumeControlStream = streamType;
   1627             if (mVolumeControlStream == -1) {
   1628                 if (mForceControlStreamClient != null) {
   1629                     mForceControlStreamClient.release();
   1630                     mForceControlStreamClient = null;
   1631                 }
   1632             } else {
   1633                 mForceControlStreamClient = new ForceControlStreamClient(cb);
   1634             }
   1635         }
   1636     }
   1637 
   1638     private class ForceControlStreamClient implements IBinder.DeathRecipient {
   1639         private IBinder mCb; // To be notified of client's death
   1640 
   1641         ForceControlStreamClient(IBinder cb) {
   1642             if (cb != null) {
   1643                 try {
   1644                     cb.linkToDeath(this, 0);
   1645                 } catch (RemoteException e) {
   1646                     // Client has died!
   1647                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
   1648                     cb = null;
   1649                 }
   1650             }
   1651             mCb = cb;
   1652         }
   1653 
   1654         public void binderDied() {
   1655             synchronized(mForceControlStreamLock) {
   1656                 Log.w(TAG, "SCO client died");
   1657                 if (mForceControlStreamClient != this) {
   1658                     Log.w(TAG, "unregistered control stream client died");
   1659                 } else {
   1660                     mForceControlStreamClient = null;
   1661                     mVolumeControlStream = -1;
   1662                 }
   1663             }
   1664         }
   1665 
   1666         public void release() {
   1667             if (mCb != null) {
   1668                 mCb.unlinkToDeath(this, 0);
   1669                 mCb = null;
   1670             }
   1671         }
   1672     }
   1673 
   1674     private void sendBroadcastToAll(Intent intent) {
   1675         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   1676         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   1677         final long ident = Binder.clearCallingIdentity();
   1678         try {
   1679             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
   1680         } finally {
   1681             Binder.restoreCallingIdentity(ident);
   1682         }
   1683     }
   1684 
   1685     private void sendStickyBroadcastToAll(Intent intent) {
   1686         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   1687         final long ident = Binder.clearCallingIdentity();
   1688         try {
   1689             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   1690         } finally {
   1691             Binder.restoreCallingIdentity(ident);
   1692         }
   1693     }
   1694 
   1695     private int getCurrentUserId() {
   1696         final long ident = Binder.clearCallingIdentity();
   1697         try {
   1698             UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser();
   1699             return currentUser.id;
   1700         } catch (RemoteException e) {
   1701             // Activity manager not running, nothing we can do assume user 0.
   1702         } finally {
   1703             Binder.restoreCallingIdentity(ident);
   1704         }
   1705         return UserHandle.USER_SYSTEM;
   1706     }
   1707 
   1708     // UI update and Broadcast Intent
   1709     private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
   1710         streamType = mStreamVolumeAlias[streamType];
   1711 
   1712         if (streamType == AudioSystem.STREAM_MUSIC) {
   1713             flags = updateFlagsForSystemAudio(flags);
   1714         }
   1715         mVolumeController.postVolumeChanged(streamType, flags);
   1716     }
   1717 
   1718     // If Hdmi-CEC system audio mode is on, we show volume bar only when TV
   1719     // receives volume notification from Audio Receiver.
   1720     private int updateFlagsForSystemAudio(int flags) {
   1721         if (mHdmiTvClient != null) {
   1722             synchronized (mHdmiTvClient) {
   1723                 if (mHdmiSystemAudioSupported &&
   1724                         ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) {
   1725                     flags &= ~AudioManager.FLAG_SHOW_UI;
   1726                 }
   1727             }
   1728         }
   1729         return flags;
   1730     }
   1731 
   1732     // UI update and Broadcast Intent
   1733     private void sendMasterMuteUpdate(boolean muted, int flags) {
   1734         mVolumeController.postMasterMuteChanged(updateFlagsForSystemAudio(flags));
   1735         broadcastMasterMuteStatus(muted);
   1736     }
   1737 
   1738     private void broadcastMasterMuteStatus(boolean muted) {
   1739         Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
   1740         intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
   1741         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
   1742                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
   1743         sendStickyBroadcastToAll(intent);
   1744     }
   1745 
   1746     /**
   1747      * Sets the stream state's index, and posts a message to set system volume.
   1748      * This will not call out to the UI. Assumes a valid stream type.
   1749      *
   1750      * @param streamType Type of the stream
   1751      * @param index Desired volume index of the stream
   1752      * @param device the device whose volume must be changed
   1753      * @param force If true, set the volume even if the desired volume is same
   1754      * as the current volume.
   1755      */
   1756     private void setStreamVolumeInt(int streamType,
   1757                                     int index,
   1758                                     int device,
   1759                                     boolean force,
   1760                                     String caller) {
   1761         VolumeStreamState streamState = mStreamStates[streamType];
   1762 
   1763         if (streamState.setIndex(index, device, caller) || force) {
   1764             // Post message to set system volume (it in turn will post a message
   1765             // to persist).
   1766             sendMsg(mAudioHandler,
   1767                     MSG_SET_DEVICE_VOLUME,
   1768                     SENDMSG_QUEUE,
   1769                     device,
   1770                     0,
   1771                     streamState,
   1772                     0);
   1773         }
   1774     }
   1775 
   1776     private void setSystemAudioMute(boolean state) {
   1777         if (mHdmiManager == null || mHdmiTvClient == null) return;
   1778         synchronized (mHdmiManager) {
   1779             if (!mHdmiSystemAudioSupported) return;
   1780             synchronized (mHdmiTvClient) {
   1781                 final long token = Binder.clearCallingIdentity();
   1782                 try {
   1783                     mHdmiTvClient.setSystemAudioMute(state);
   1784                 } finally {
   1785                     Binder.restoreCallingIdentity(token);
   1786                 }
   1787             }
   1788         }
   1789     }
   1790 
   1791     /** get stream mute state. */
   1792     public boolean isStreamMute(int streamType) {
   1793         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
   1794             streamType = getActiveStreamType(streamType);
   1795         }
   1796         synchronized (VolumeStreamState.class) {
   1797             return mStreamStates[streamType].mIsMuted;
   1798         }
   1799     }
   1800 
   1801     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
   1802         private IBinder mICallback; // To be notified of client's death
   1803 
   1804         RmtSbmxFullVolDeathHandler(IBinder cb) {
   1805             mICallback = cb;
   1806             try {
   1807                 cb.linkToDeath(this, 0/*flags*/);
   1808             } catch (RemoteException e) {
   1809                 Log.e(TAG, "can't link to death", e);
   1810             }
   1811         }
   1812 
   1813         boolean isHandlerFor(IBinder cb) {
   1814             return mICallback.equals(cb);
   1815         }
   1816 
   1817         void forget() {
   1818             try {
   1819                 mICallback.unlinkToDeath(this, 0/*flags*/);
   1820             } catch (NoSuchElementException e) {
   1821                 Log.e(TAG, "error unlinking to death", e);
   1822             }
   1823         }
   1824 
   1825         public void binderDied() {
   1826             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
   1827             forceRemoteSubmixFullVolume(false, mICallback);
   1828         }
   1829     }
   1830 
   1831     /**
   1832      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
   1833      * @return true if there is a registered death handler, false otherwise */
   1834     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
   1835         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
   1836         while (it.hasNext()) {
   1837             final RmtSbmxFullVolDeathHandler handler = it.next();
   1838             if (handler.isHandlerFor(cb)) {
   1839                 handler.forget();
   1840                 mRmtSbmxFullVolDeathHandlers.remove(handler);
   1841                 return true;
   1842             }
   1843         }
   1844         return false;
   1845     }
   1846 
   1847     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
   1848     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
   1849         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
   1850         while (it.hasNext()) {
   1851             if (it.next().isHandlerFor(cb)) {
   1852                 return true;
   1853             }
   1854         }
   1855         return false;
   1856     }
   1857 
   1858     private int mRmtSbmxFullVolRefCount = 0;
   1859     private ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
   1860             new ArrayList<RmtSbmxFullVolDeathHandler>();
   1861 
   1862     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
   1863         if (cb == null) {
   1864             return;
   1865         }
   1866         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
   1867                         android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) {
   1868             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
   1869             return;
   1870         }
   1871         synchronized(mRmtSbmxFullVolDeathHandlers) {
   1872             boolean applyRequired = false;
   1873             if (startForcing) {
   1874                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
   1875                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
   1876                     if (mRmtSbmxFullVolRefCount == 0) {
   1877                         mFullVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
   1878                         mFixedVolumeDevices |= AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
   1879                         applyRequired = true;
   1880                     }
   1881                     mRmtSbmxFullVolRefCount++;
   1882                 }
   1883             } else {
   1884                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
   1885                     mRmtSbmxFullVolRefCount--;
   1886                     if (mRmtSbmxFullVolRefCount == 0) {
   1887                         mFullVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
   1888                         mFixedVolumeDevices &= ~AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
   1889                         applyRequired = true;
   1890                     }
   1891                 }
   1892             }
   1893             if (applyRequired) {
   1894                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
   1895                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
   1896                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
   1897             }
   1898         }
   1899     }
   1900 
   1901     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
   1902             int userId) {
   1903         // If we are being called by the system check for user we are going to change
   1904         // so we handle user restrictions correctly.
   1905         if (uid == android.os.Process.SYSTEM_UID) {
   1906             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
   1907         }
   1908         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
   1909         if (!mute && mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage)
   1910                 != AppOpsManager.MODE_ALLOWED) {
   1911             return;
   1912         }
   1913         if (userId != UserHandle.getCallingUserId() &&
   1914                 mContext.checkCallingOrSelfPermission(
   1915                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   1916                 != PackageManager.PERMISSION_GRANTED) {
   1917             return;
   1918         }
   1919         setMasterMuteInternalNoCallerCheck(mute, flags, userId);
   1920     }
   1921 
   1922     private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
   1923         if (DEBUG_VOL) {
   1924             Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
   1925         }
   1926         if (mUseFixedVolume) {
   1927             return; // If using fixed volume, we don't mute.
   1928         }
   1929         if (getCurrentUserId() == userId) {
   1930             if (mute != AudioSystem.getMasterMute()) {
   1931                 setSystemAudioMute(mute);
   1932                 AudioSystem.setMasterMute(mute);
   1933                 sendMasterMuteUpdate(mute, flags);
   1934 
   1935                 Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
   1936                 intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, mute);
   1937                 sendBroadcastToAll(intent);
   1938             }
   1939         }
   1940     }
   1941 
   1942     /** get master mute state. */
   1943     public boolean isMasterMute() {
   1944         return AudioSystem.getMasterMute();
   1945     }
   1946 
   1947     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) {
   1948         setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(),
   1949                 userId);
   1950     }
   1951 
   1952     /** @see AudioManager#getStreamVolume(int) */
   1953     public int getStreamVolume(int streamType) {
   1954         ensureValidStreamType(streamType);
   1955         int device = getDeviceForStream(streamType);
   1956         synchronized (VolumeStreamState.class) {
   1957             int index = mStreamStates[streamType].getIndex(device);
   1958 
   1959             // by convention getStreamVolume() returns 0 when a stream is muted.
   1960             if (mStreamStates[streamType].mIsMuted) {
   1961                 index = 0;
   1962             }
   1963             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
   1964                     (device & mFixedVolumeDevices) != 0) {
   1965                 index = mStreamStates[streamType].getMaxIndex();
   1966             }
   1967             return (index + 5) / 10;
   1968         }
   1969     }
   1970 
   1971     /** @see AudioManager#getStreamMaxVolume(int) */
   1972     public int getStreamMaxVolume(int streamType) {
   1973         ensureValidStreamType(streamType);
   1974         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
   1975     }
   1976 
   1977     /** @see AudioManager#getStreamMinVolume(int) */
   1978     public int getStreamMinVolume(int streamType) {
   1979         ensureValidStreamType(streamType);
   1980         return (mStreamStates[streamType].getMinIndex() + 5) / 10;
   1981     }
   1982 
   1983     /** Get last audible volume before stream was muted. */
   1984     public int getLastAudibleStreamVolume(int streamType) {
   1985         ensureValidStreamType(streamType);
   1986         int device = getDeviceForStream(streamType);
   1987         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
   1988     }
   1989 
   1990     /** @see AudioManager#getUiSoundsStreamType()  */
   1991     public int getUiSoundsStreamType() {
   1992         return mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
   1993     }
   1994 
   1995     /** @see AudioManager#setMicrophoneMute(boolean) */
   1996     @Override
   1997     public void setMicrophoneMute(boolean on, String callingPackage, int userId) {
   1998         // If we are being called by the system check for user we are going to change
   1999         // so we handle user restrictions correctly.
   2000         int uid = Binder.getCallingUid();
   2001         if (uid == android.os.Process.SYSTEM_UID) {
   2002             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
   2003         }
   2004         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
   2005         if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage)
   2006                 != AppOpsManager.MODE_ALLOWED) {
   2007             return;
   2008         }
   2009         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
   2010             return;
   2011         }
   2012         if (userId != UserHandle.getCallingUserId() &&
   2013                 mContext.checkCallingOrSelfPermission(
   2014                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
   2015                 != PackageManager.PERMISSION_GRANTED) {
   2016             return;
   2017         }
   2018         setMicrophoneMuteNoCallerCheck(on, userId);
   2019     }
   2020 
   2021     private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) {
   2022         if (DEBUG_VOL) {
   2023             Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId));
   2024         }
   2025         // If mute is for current user actually mute, else just persist the setting
   2026         // which will be loaded on user switch.
   2027         if (getCurrentUserId() == userId) {
   2028             AudioSystem.muteMicrophone(on);
   2029         }
   2030         // Post a persist microphone msg.
   2031     }
   2032 
   2033     @Override
   2034     public int getRingerModeExternal() {
   2035         synchronized(mSettingsLock) {
   2036             return mRingerModeExternal;
   2037         }
   2038     }
   2039 
   2040     @Override
   2041     public int getRingerModeInternal() {
   2042         synchronized(mSettingsLock) {
   2043             return mRingerMode;
   2044         }
   2045     }
   2046 
   2047     private void ensureValidRingerMode(int ringerMode) {
   2048         if (!isValidRingerMode(ringerMode)) {
   2049             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
   2050         }
   2051     }
   2052 
   2053     /** @see AudioManager#isValidRingerMode(int) */
   2054     public boolean isValidRingerMode(int ringerMode) {
   2055         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
   2056     }
   2057 
   2058     public void setRingerModeExternal(int ringerMode, String caller) {
   2059         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
   2060                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
   2061             throw new SecurityException("Not allowed to change Do Not Disturb state");
   2062         }
   2063 
   2064         setRingerMode(ringerMode, caller, true /*external*/);
   2065     }
   2066 
   2067     public void setRingerModeInternal(int ringerMode, String caller) {
   2068         enforceVolumeController("setRingerModeInternal");
   2069         setRingerMode(ringerMode, caller, false /*external*/);
   2070     }
   2071 
   2072     private void setRingerMode(int ringerMode, String caller, boolean external) {
   2073         if (mUseFixedVolume || isPlatformTelevision()) {
   2074             return;
   2075         }
   2076         if (caller == null || caller.length() == 0) {
   2077             throw new IllegalArgumentException("Bad caller: " + caller);
   2078         }
   2079         ensureValidRingerMode(ringerMode);
   2080         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
   2081             ringerMode = AudioManager.RINGER_MODE_SILENT;
   2082         }
   2083         final long identity = Binder.clearCallingIdentity();
   2084         try {
   2085             synchronized (mSettingsLock) {
   2086                 final int ringerModeInternal = getRingerModeInternal();
   2087                 final int ringerModeExternal = getRingerModeExternal();
   2088                 if (external) {
   2089                     setRingerModeExt(ringerMode);
   2090                     if (mRingerModeDelegate != null) {
   2091                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
   2092                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
   2093                     }
   2094                     if (ringerMode != ringerModeInternal) {
   2095                         setRingerModeInt(ringerMode, true /*persist*/);
   2096                     }
   2097                 } else /*internal*/ {
   2098                     if (ringerMode != ringerModeInternal) {
   2099                         setRingerModeInt(ringerMode, true /*persist*/);
   2100                     }
   2101                     if (mRingerModeDelegate != null) {
   2102                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
   2103                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
   2104                     }
   2105                     setRingerModeExt(ringerMode);
   2106                 }
   2107             }
   2108         } finally {
   2109             Binder.restoreCallingIdentity(identity);
   2110         }
   2111     }
   2112 
   2113     private void setRingerModeExt(int ringerMode) {
   2114         synchronized(mSettingsLock) {
   2115             if (ringerMode == mRingerModeExternal) return;
   2116             mRingerModeExternal = ringerMode;
   2117         }
   2118         // Send sticky broadcast
   2119         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
   2120     }
   2121 
   2122     private void muteRingerModeStreams() {
   2123         // Mute stream if not previously muted by ringer mode and ringer mode
   2124         // is not RINGER_MODE_NORMAL and stream is affected by ringer mode.
   2125         // Unmute stream if previously muted by ringer mode and ringer mode
   2126         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
   2127         int numStreamTypes = AudioSystem.getNumStreamTypes();
   2128         final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE
   2129                 || mRingerMode == AudioManager.RINGER_MODE_SILENT;
   2130         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
   2131             final boolean isMuted = isStreamMutedByRingerMode(streamType);
   2132             final boolean shouldMute = ringerModeMute && isStreamAffectedByRingerMode(streamType);
   2133             if (isMuted == shouldMute) continue;
   2134             if (!shouldMute) {
   2135                 // unmute
   2136                 // ring and notifications volume should never be 0 when not silenced
   2137                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
   2138                     synchronized (VolumeStreamState.class) {
   2139                         final VolumeStreamState vss = mStreamStates[streamType];
   2140                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
   2141                             int device = vss.mIndexMap.keyAt(i);
   2142                             int value = vss.mIndexMap.valueAt(i);
   2143                             if (value == 0) {
   2144                                 vss.setIndex(10, device, TAG);
   2145                             }
   2146                         }
   2147                         // Persist volume for stream ring when it is changed here
   2148                       final int device = getDeviceForStream(streamType);
   2149                       sendMsg(mAudioHandler,
   2150                               MSG_PERSIST_VOLUME,
   2151                               SENDMSG_QUEUE,
   2152                               device,
   2153                               0,
   2154                               mStreamStates[streamType],
   2155                               PERSIST_DELAY);
   2156                     }
   2157                 }
   2158                 mStreamStates[streamType].mute(false);
   2159                 mRingerModeMutedStreams &= ~(1 << streamType);
   2160             } else {
   2161                 // mute
   2162                 mStreamStates[streamType].mute(true);
   2163                 mRingerModeMutedStreams |= (1 << streamType);
   2164             }
   2165         }
   2166     }
   2167 
   2168     private void setRingerModeInt(int ringerMode, boolean persist) {
   2169         final boolean change;
   2170         synchronized(mSettingsLock) {
   2171             change = mRingerMode != ringerMode;
   2172             mRingerMode = ringerMode;
   2173         }
   2174 
   2175         muteRingerModeStreams();
   2176 
   2177         // Post a persist ringer mode msg
   2178         if (persist) {
   2179             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
   2180                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
   2181         }
   2182         if (change) {
   2183             // Send sticky broadcast
   2184             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
   2185         }
   2186     }
   2187 
   2188     /** @see AudioManager#shouldVibrate(int) */
   2189     public boolean shouldVibrate(int vibrateType) {
   2190         if (!mHasVibrator) return false;
   2191 
   2192         switch (getVibrateSetting(vibrateType)) {
   2193 
   2194             case AudioManager.VIBRATE_SETTING_ON:
   2195                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
   2196 
   2197             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
   2198                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
   2199 
   2200             case AudioManager.VIBRATE_SETTING_OFF:
   2201                 // return false, even for incoming calls
   2202                 return false;
   2203 
   2204             default:
   2205                 return false;
   2206         }
   2207     }
   2208 
   2209     /** @see AudioManager#getVibrateSetting(int) */
   2210     public int getVibrateSetting(int vibrateType) {
   2211         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
   2212         return (mVibrateSetting >> (vibrateType * 2)) & 3;
   2213     }
   2214 
   2215     /** @see AudioManager#setVibrateSetting(int, int) */
   2216     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
   2217 
   2218         if (!mHasVibrator) return;
   2219 
   2220         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
   2221                 vibrateSetting);
   2222 
   2223         // Broadcast change
   2224         broadcastVibrateSetting(vibrateType);
   2225 
   2226     }
   2227 
   2228     private class SetModeDeathHandler implements IBinder.DeathRecipient {
   2229         private IBinder mCb; // To be notified of client's death
   2230         private int mPid;
   2231         private int mMode = AudioSystem.MODE_NORMAL; // Current mode set by this client
   2232 
   2233         SetModeDeathHandler(IBinder cb, int pid) {
   2234             mCb = cb;
   2235             mPid = pid;
   2236         }
   2237 
   2238         public void binderDied() {
   2239             int newModeOwnerPid = 0;
   2240             synchronized(mSetModeDeathHandlers) {
   2241                 Log.w(TAG, "setMode() client died");
   2242                 int index = mSetModeDeathHandlers.indexOf(this);
   2243                 if (index < 0) {
   2244                     Log.w(TAG, "unregistered setMode() client died");
   2245                 } else {
   2246                     newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG);
   2247                 }
   2248             }
   2249             // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
   2250             // SCO connections not started by the application changing the mode
   2251             if (newModeOwnerPid != 0) {
   2252                 final long ident = Binder.clearCallingIdentity();
   2253                 disconnectBluetoothSco(newModeOwnerPid);
   2254                 Binder.restoreCallingIdentity(ident);
   2255             }
   2256         }
   2257 
   2258         public int getPid() {
   2259             return mPid;
   2260         }
   2261 
   2262         public void setMode(int mode) {
   2263             mMode = mode;
   2264         }
   2265 
   2266         public int getMode() {
   2267             return mMode;
   2268         }
   2269 
   2270         public IBinder getBinder() {
   2271             return mCb;
   2272         }
   2273     }
   2274 
   2275     /** @see AudioManager#setMode(int) */
   2276     public void setMode(int mode, IBinder cb, String callingPackage) {
   2277         if (DEBUG_MODE) { Log.v(TAG, "setMode(mode=" + mode + ", callingPackage=" + callingPackage + ")"); }
   2278         if (!checkAudioSettingsPermission("setMode()")) {
   2279             return;
   2280         }
   2281 
   2282         if ( (mode == AudioSystem.MODE_IN_CALL) &&
   2283                 (mContext.checkCallingOrSelfPermission(
   2284                         android.Manifest.permission.MODIFY_PHONE_STATE)
   2285                             != PackageManager.PERMISSION_GRANTED)) {
   2286             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid="
   2287                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
   2288             return;
   2289         }
   2290 
   2291         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
   2292             return;
   2293         }
   2294 
   2295         int newModeOwnerPid = 0;
   2296         synchronized(mSetModeDeathHandlers) {
   2297             if (mode == AudioSystem.MODE_CURRENT) {
   2298                 mode = mMode;
   2299             }
   2300             newModeOwnerPid = setModeInt(mode, cb, Binder.getCallingPid(), callingPackage);
   2301         }
   2302         // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
   2303         // SCO connections not started by the application changing the mode
   2304         if (newModeOwnerPid != 0) {
   2305              disconnectBluetoothSco(newModeOwnerPid);
   2306         }
   2307     }
   2308 
   2309     // must be called synchronized on mSetModeDeathHandlers
   2310     // setModeInt() returns a valid PID if the audio mode was successfully set to
   2311     // any mode other than NORMAL.
   2312     private int setModeInt(int mode, IBinder cb, int pid, String caller) {
   2313         if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller="
   2314                 + caller + ")"); }
   2315         int newModeOwnerPid = 0;
   2316         if (cb == null) {
   2317             Log.e(TAG, "setModeInt() called with null binder");
   2318             return newModeOwnerPid;
   2319         }
   2320 
   2321         SetModeDeathHandler hdlr = null;
   2322         Iterator iter = mSetModeDeathHandlers.iterator();
   2323         while (iter.hasNext()) {
   2324             SetModeDeathHandler h = (SetModeDeathHandler)iter.next();
   2325             if (h.getPid() == pid) {
   2326                 hdlr = h;
   2327                 // Remove from client list so that it is re-inserted at top of list
   2328                 iter.remove();
   2329                 hdlr.getBinder().unlinkToDeath(hdlr, 0);
   2330                 break;
   2331             }
   2332         }
   2333         int status = AudioSystem.AUDIO_STATUS_OK;
   2334         do {
   2335             if (mode == AudioSystem.MODE_NORMAL) {
   2336                 // get new mode from client at top the list if any
   2337                 if (!mSetModeDeathHandlers.isEmpty()) {
   2338                     hdlr = mSetModeDeathHandlers.get(0);
   2339                     cb = hdlr.getBinder();
   2340                     mode = hdlr.getMode();
   2341                     if (DEBUG_MODE) {
   2342                         Log.w(TAG, " using mode=" + mode + " instead due to death hdlr at pid="
   2343                                 + hdlr.mPid);
   2344                     }
   2345                 }
   2346             } else {
   2347                 if (hdlr == null) {
   2348                     hdlr = new SetModeDeathHandler(cb, pid);
   2349                 }
   2350                 // Register for client death notification
   2351                 try {
   2352                     cb.linkToDeath(hdlr, 0);
   2353                 } catch (RemoteException e) {
   2354                     // Client has died!
   2355                     Log.w(TAG, "setMode() could not link to "+cb+" binder death");
   2356                 }
   2357 
   2358                 // Last client to call setMode() is always at top of client list
   2359                 // as required by SetModeDeathHandler.binderDied()
   2360                 mSetModeDeathHandlers.add(0, hdlr);
   2361                 hdlr.setMode(mode);
   2362             }
   2363 
   2364             if (mode != mMode) {
   2365                 status = AudioSystem.setPhoneState(mode);
   2366                 if (status == AudioSystem.AUDIO_STATUS_OK) {
   2367                     if (DEBUG_MODE) { Log.v(TAG, " mode successfully set to " + mode); }
   2368                     mMode = mode;
   2369                 } else {
   2370                     if (hdlr != null) {
   2371                         mSetModeDeathHandlers.remove(hdlr);
   2372                         cb.unlinkToDeath(hdlr, 0);
   2373                     }
   2374                     // force reading new top of mSetModeDeathHandlers stack
   2375                     if (DEBUG_MODE) { Log.w(TAG, " mode set to MODE_NORMAL after phoneState pb"); }
   2376                     mode = AudioSystem.MODE_NORMAL;
   2377                 }
   2378             } else {
   2379                 status = AudioSystem.AUDIO_STATUS_OK;
   2380             }
   2381         } while (status != AudioSystem.AUDIO_STATUS_OK && !mSetModeDeathHandlers.isEmpty());
   2382 
   2383         if (status == AudioSystem.AUDIO_STATUS_OK) {
   2384             if (mode != AudioSystem.MODE_NORMAL) {
   2385                 if (mSetModeDeathHandlers.isEmpty()) {
   2386                     Log.e(TAG, "setMode() different from MODE_NORMAL with empty mode client stack");
   2387                 } else {
   2388                     newModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
   2389                 }
   2390             }
   2391             int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
   2392             int device = getDeviceForStream(streamType);
   2393             int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
   2394             setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, caller);
   2395 
   2396             updateStreamVolumeAlias(true /*updateVolumes*/, caller);
   2397         }
   2398         return newModeOwnerPid;
   2399     }
   2400 
   2401     /** @see AudioManager#getMode() */
   2402     public int getMode() {
   2403         return mMode;
   2404     }
   2405 
   2406     //==========================================================================================
   2407     // Sound Effects
   2408     //==========================================================================================
   2409 
   2410     private static final String TAG_AUDIO_ASSETS = "audio_assets";
   2411     private static final String ATTR_VERSION = "version";
   2412     private static final String TAG_GROUP = "group";
   2413     private static final String ATTR_GROUP_NAME = "name";
   2414     private static final String TAG_ASSET = "asset";
   2415     private static final String ATTR_ASSET_ID = "id";
   2416     private static final String ATTR_ASSET_FILE = "file";
   2417 
   2418     private static final String ASSET_FILE_VERSION = "1.0";
   2419     private static final String GROUP_TOUCH_SOUNDS = "touch_sounds";
   2420 
   2421     private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
   2422 
   2423     class LoadSoundEffectReply {
   2424         public int mStatus = 1;
   2425     };
   2426 
   2427     private void loadTouchSoundAssetDefaults() {
   2428         SOUND_EFFECT_FILES.add("Effect_Tick.ogg");
   2429         for (int i = 0; i < AudioManager.NUM_SOUND_EFFECTS; i++) {
   2430             SOUND_EFFECT_FILES_MAP[i][0] = 0;
   2431             SOUND_EFFECT_FILES_MAP[i][1] = -1;
   2432         }
   2433     }
   2434 
   2435     private void loadTouchSoundAssets() {
   2436         XmlResourceParser parser = null;
   2437 
   2438         // only load assets once.
   2439         if (!SOUND_EFFECT_FILES.isEmpty()) {
   2440             return;
   2441         }
   2442 
   2443         loadTouchSoundAssetDefaults();
   2444 
   2445         try {
   2446             parser = mContext.getResources().getXml(com.android.internal.R.xml.audio_assets);
   2447 
   2448             XmlUtils.beginDocument(parser, TAG_AUDIO_ASSETS);
   2449             String version = parser.getAttributeValue(null, ATTR_VERSION);
   2450             boolean inTouchSoundsGroup = false;
   2451 
   2452             if (ASSET_FILE_VERSION.equals(version)) {
   2453                 while (true) {
   2454                     XmlUtils.nextElement(parser);
   2455                     String element = parser.getName();
   2456                     if (element == null) {
   2457                         break;
   2458                     }
   2459                     if (element.equals(TAG_GROUP)) {
   2460                         String name = parser.getAttributeValue(null, ATTR_GROUP_NAME);
   2461                         if (GROUP_TOUCH_SOUNDS.equals(name)) {
   2462                             inTouchSoundsGroup = true;
   2463                             break;
   2464                         }
   2465                     }
   2466                 }
   2467                 while (inTouchSoundsGroup) {
   2468                     XmlUtils.nextElement(parser);
   2469                     String element = parser.getName();
   2470                     if (element == null) {
   2471                         break;
   2472                     }
   2473                     if (element.equals(TAG_ASSET)) {
   2474                         String id = parser.getAttributeValue(null, ATTR_ASSET_ID);
   2475                         String file = parser.getAttributeValue(null, ATTR_ASSET_FILE);
   2476                         int fx;
   2477 
   2478                         try {
   2479                             Field field = AudioManager.class.getField(id);
   2480                             fx = field.getInt(null);
   2481                         } catch (Exception e) {
   2482                             Log.w(TAG, "Invalid touch sound ID: "+id);
   2483                             continue;
   2484                         }
   2485 
   2486                         int i = SOUND_EFFECT_FILES.indexOf(file);
   2487                         if (i == -1) {
   2488                             i = SOUND_EFFECT_FILES.size();
   2489                             SOUND_EFFECT_FILES.add(file);
   2490                         }
   2491                         SOUND_EFFECT_FILES_MAP[fx][0] = i;
   2492                     } else {
   2493                         break;
   2494                     }
   2495                 }
   2496             }
   2497         } catch (Resources.NotFoundException e) {
   2498             Log.w(TAG, "audio assets file not found", e);
   2499         } catch (XmlPullParserException e) {
   2500             Log.w(TAG, "XML parser exception reading touch sound assets", e);
   2501         } catch (IOException e) {
   2502             Log.w(TAG, "I/O exception reading touch sound assets", e);
   2503         } finally {
   2504             if (parser != null) {
   2505                 parser.close();
   2506             }
   2507         }
   2508     }
   2509 
   2510     /** @see AudioManager#playSoundEffect(int) */
   2511     public void playSoundEffect(int effectType) {
   2512         playSoundEffectVolume(effectType, -1.0f);
   2513     }
   2514 
   2515     /** @see AudioManager#playSoundEffect(int, float) */
   2516     public void playSoundEffectVolume(int effectType, float volume) {
   2517         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
   2518             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
   2519             return;
   2520         }
   2521 
   2522         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
   2523                 effectType, (int) (volume * 1000), null, 0);
   2524     }
   2525 
   2526     /**
   2527      * Loads samples into the soundpool.
   2528      * This method must be called at first when sound effects are enabled
   2529      */
   2530     public boolean loadSoundEffects() {
   2531         int attempts = 3;
   2532         LoadSoundEffectReply reply = new LoadSoundEffectReply();
   2533 
   2534         synchronized (reply) {
   2535             sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
   2536             while ((reply.mStatus == 1) && (attempts-- > 0)) {
   2537                 try {
   2538                     reply.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
   2539                 } catch (InterruptedException e) {
   2540                     Log.w(TAG, "loadSoundEffects Interrupted while waiting sound pool loaded.");
   2541                 }
   2542             }
   2543         }
   2544         return (reply.mStatus == 0);
   2545     }
   2546 
   2547     /**
   2548      *  Unloads samples from the sound pool.
   2549      *  This method can be called to free some memory when
   2550      *  sound effects are disabled.
   2551      */
   2552     public void unloadSoundEffects() {
   2553         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
   2554     }
   2555 
   2556     class SoundPoolListenerThread extends Thread {
   2557         public SoundPoolListenerThread() {
   2558             super("SoundPoolListenerThread");
   2559         }
   2560 
   2561         @Override
   2562         public void run() {
   2563 
   2564             Looper.prepare();
   2565             mSoundPoolLooper = Looper.myLooper();
   2566 
   2567             synchronized (mSoundEffectsLock) {
   2568                 if (mSoundPool != null) {
   2569                     mSoundPoolCallBack = new SoundPoolCallback();
   2570                     mSoundPool.setOnLoadCompleteListener(mSoundPoolCallBack);
   2571                 }
   2572                 mSoundEffectsLock.notify();
   2573             }
   2574             Looper.loop();
   2575         }
   2576     }
   2577 
   2578     private final class SoundPoolCallback implements
   2579             android.media.SoundPool.OnLoadCompleteListener {
   2580 
   2581         int mStatus = 1; // 1 means neither error nor last sample loaded yet
   2582         List<Integer> mSamples = new ArrayList<Integer>();
   2583 
   2584         public int status() {
   2585             return mStatus;
   2586         }
   2587 
   2588         public void setSamples(int[] samples) {
   2589             for (int i = 0; i < samples.length; i++) {
   2590                 // do not wait ack for samples rejected upfront by SoundPool
   2591                 if (samples[i] > 0) {
   2592                     mSamples.add(samples[i]);
   2593                 }
   2594             }
   2595         }
   2596 
   2597         public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
   2598             synchronized (mSoundEffectsLock) {
   2599                 int i = mSamples.indexOf(sampleId);
   2600                 if (i >= 0) {
   2601                     mSamples.remove(i);
   2602                 }
   2603                 if ((status != 0) || mSamples. isEmpty()) {
   2604                     mStatus = status;
   2605                     mSoundEffectsLock.notify();
   2606                 }
   2607             }
   2608         }
   2609     }
   2610 
   2611     /** @see AudioManager#reloadAudioSettings() */
   2612     public void reloadAudioSettings() {
   2613         readAudioSettings(false /*userSwitch*/);
   2614     }
   2615 
   2616     private void readAudioSettings(boolean userSwitch) {
   2617         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
   2618         readPersistedSettings();
   2619         readUserRestrictions();
   2620 
   2621         // restore volume settings
   2622         int numStreamTypes = AudioSystem.getNumStreamTypes();
   2623         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
   2624             VolumeStreamState streamState = mStreamStates[streamType];
   2625 
   2626             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
   2627                 continue;
   2628             }
   2629 
   2630             streamState.readSettings();
   2631             synchronized (VolumeStreamState.class) {
   2632                 // unmute stream that was muted but is not affect by mute anymore
   2633                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
   2634                         !isStreamMutedByRingerMode(streamType)) || mUseFixedVolume)) {
   2635                     streamState.mIsMuted = false;
   2636                 }
   2637             }
   2638         }
   2639 
   2640         // apply new ringer mode before checking volume for alias streams so that streams
   2641         // muted by ringer mode have the correct volume
   2642         setRingerModeInt(getRingerModeInternal(), false);
   2643 
   2644         checkAllFixedVolumeDevices();
   2645         checkAllAliasStreamVolumes();
   2646         checkMuteAffectedStreams();
   2647 
   2648         synchronized (mSafeMediaVolumeState) {
   2649             mMusicActiveMs = MathUtils.constrain(Settings.Secure.getIntForUser(mContentResolver,
   2650                     Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT),
   2651                     0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX);
   2652             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
   2653                 enforceSafeMediaVolume(TAG);
   2654             }
   2655         }
   2656     }
   2657 
   2658     /** @see AudioManager#setSpeakerphoneOn(boolean) */
   2659     public void setSpeakerphoneOn(boolean on){
   2660         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
   2661             return;
   2662         }
   2663 
   2664         if (on) {
   2665             if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
   2666                     sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
   2667                             AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0);
   2668             }
   2669             mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
   2670         } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){
   2671             mForcedUseForComm = AudioSystem.FORCE_NONE;
   2672         }
   2673 
   2674         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
   2675                 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
   2676     }
   2677 
   2678     /** @see AudioManager#isSpeakerphoneOn() */
   2679     public boolean isSpeakerphoneOn() {
   2680         return (mForcedUseForComm == AudioSystem.FORCE_SPEAKER);
   2681     }
   2682 
   2683     /** @see AudioManager#setBluetoothScoOn(boolean) */
   2684     public void setBluetoothScoOn(boolean on) {
   2685         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
   2686             return;
   2687         }
   2688         setBluetoothScoOnInt(on);
   2689     }
   2690 
   2691     public void setBluetoothScoOnInt(boolean on) {
   2692         if (on) {
   2693             mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
   2694         } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
   2695             mForcedUseForComm = AudioSystem.FORCE_NONE;
   2696         }
   2697 
   2698         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
   2699                 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
   2700         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
   2701                 AudioSystem.FOR_RECORD, mForcedUseForComm, null, 0);
   2702     }
   2703 
   2704     /** @see AudioManager#isBluetoothScoOn() */
   2705     public boolean isBluetoothScoOn() {
   2706         return (mForcedUseForComm == AudioSystem.FORCE_BT_SCO);
   2707     }
   2708 
   2709     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
   2710     public void setBluetoothA2dpOn(boolean on) {
   2711         synchronized (mBluetoothA2dpEnabledLock) {
   2712             mBluetoothA2dpEnabled = on;
   2713             sendMsg(mAudioHandler, MSG_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE,
   2714                     AudioSystem.FOR_MEDIA,
   2715                     mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
   2716                     null, 0);
   2717         }
   2718     }
   2719 
   2720     /** @see AudioManager#isBluetoothA2dpOn() */
   2721     public boolean isBluetoothA2dpOn() {
   2722         synchronized (mBluetoothA2dpEnabledLock) {
   2723             return mBluetoothA2dpEnabled;
   2724         }
   2725     }
   2726 
   2727     /** @see AudioManager#startBluetoothSco() */
   2728     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
   2729         int scoAudioMode =
   2730                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
   2731                         SCO_MODE_VIRTUAL_CALL : SCO_MODE_UNDEFINED;
   2732         startBluetoothScoInt(cb, scoAudioMode);
   2733     }
   2734 
   2735     /** @see AudioManager#startBluetoothScoVirtualCall() */
   2736     public void startBluetoothScoVirtualCall(IBinder cb) {
   2737         startBluetoothScoInt(cb, SCO_MODE_VIRTUAL_CALL);
   2738     }
   2739 
   2740     void startBluetoothScoInt(IBinder cb, int scoAudioMode){
   2741         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
   2742                 !mSystemReady) {
   2743             return;
   2744         }
   2745         ScoClient client = getScoClient(cb, true);
   2746         // The calling identity must be cleared before calling ScoClient.incCount().
   2747         // inCount() calls requestScoState() which in turn can call BluetoothHeadset APIs
   2748         // and this must be done on behalf of system server to make sure permissions are granted.
   2749         // The caller identity must be cleared after getScoClient() because it is needed if a new
   2750         // client is created.
   2751         final long ident = Binder.clearCallingIdentity();
   2752         client.incCount(scoAudioMode);
   2753         Binder.restoreCallingIdentity(ident);
   2754     }
   2755 
   2756     /** @see AudioManager#stopBluetoothSco() */
   2757     public void stopBluetoothSco(IBinder cb){
   2758         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
   2759                 !mSystemReady) {
   2760             return;
   2761         }
   2762         ScoClient client = getScoClient(cb, false);
   2763         // The calling identity must be cleared before calling ScoClient.decCount().
   2764         // decCount() calls requestScoState() which in turn can call BluetoothHeadset APIs
   2765         // and this must be done on behalf of system server to make sure permissions are granted.
   2766         final long ident = Binder.clearCallingIdentity();
   2767         if (client != null) {
   2768             client.decCount();
   2769         }
   2770         Binder.restoreCallingIdentity(ident);
   2771     }
   2772 
   2773 
   2774     private class ScoClient implements IBinder.DeathRecipient {
   2775         private IBinder mCb; // To be notified of client's death
   2776         private int mCreatorPid;
   2777         private int mStartcount; // number of SCO connections started by this client
   2778 
   2779         ScoClient(IBinder cb) {
   2780             mCb = cb;
   2781             mCreatorPid = Binder.getCallingPid();
   2782             mStartcount = 0;
   2783         }
   2784 
   2785         public void binderDied() {
   2786             synchronized(mScoClients) {
   2787                 Log.w(TAG, "SCO client died");
   2788                 int index = mScoClients.indexOf(this);
   2789                 if (index < 0) {
   2790                     Log.w(TAG, "unregistered SCO client died");
   2791                 } else {
   2792                     clearCount(true);
   2793                     mScoClients.remove(this);
   2794                 }
   2795             }
   2796         }
   2797 
   2798         public void incCount(int scoAudioMode) {
   2799             synchronized(mScoClients) {
   2800                 requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
   2801                 if (mStartcount == 0) {
   2802                     try {
   2803                         mCb.linkToDeath(this, 0);
   2804                     } catch (RemoteException e) {
   2805                         // client has already died!
   2806                         Log.w(TAG, "ScoClient  incCount() could not link to "+mCb+" binder death");
   2807                     }
   2808                 }
   2809                 mStartcount++;
   2810             }
   2811         }
   2812 
   2813         public void decCount() {
   2814             synchronized(mScoClients) {
   2815                 if (mStartcount == 0) {
   2816                     Log.w(TAG, "ScoClient.decCount() already 0");
   2817                 } else {
   2818                     mStartcount--;
   2819                     if (mStartcount == 0) {
   2820                         try {
   2821                             mCb.unlinkToDeath(this, 0);
   2822                         } catch (NoSuchElementException e) {
   2823                             Log.w(TAG, "decCount() going to 0 but not registered to binder");
   2824                         }
   2825                     }
   2826                     requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
   2827                 }
   2828             }
   2829         }
   2830 
   2831         public void clearCount(boolean stopSco) {
   2832             synchronized(mScoClients) {
   2833                 if (mStartcount != 0) {
   2834                     try {
   2835                         mCb.unlinkToDeath(this, 0);
   2836                     } catch (NoSuchElementException e) {
   2837                         Log.w(TAG, "clearCount() mStartcount: "+mStartcount+" != 0 but not registered to binder");
   2838                     }
   2839                 }
   2840                 mStartcount = 0;
   2841                 if (stopSco) {
   2842                     requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
   2843                 }
   2844             }
   2845         }
   2846 
   2847         public int getCount() {
   2848             return mStartcount;
   2849         }
   2850 
   2851         public IBinder getBinder() {
   2852             return mCb;
   2853         }
   2854 
   2855         public int getPid() {
   2856             return mCreatorPid;
   2857         }
   2858 
   2859         public int totalCount() {
   2860             synchronized(mScoClients) {
   2861                 int count = 0;
   2862                 int size = mScoClients.size();
   2863                 for (int i = 0; i < size; i++) {
   2864                     count += mScoClients.get(i).getCount();
   2865                 }
   2866                 return count;
   2867             }
   2868         }
   2869 
   2870         private void requestScoState(int state, int scoAudioMode) {
   2871             checkScoAudioState();
   2872             if (totalCount() == 0) {
   2873                 if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
   2874                     // Make sure that the state transitions to CONNECTING even if we cannot initiate
   2875                     // the connection.
   2876                     broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
   2877                     // Accept SCO audio activation only in NORMAL audio mode or if the mode is
   2878                     // currently controlled by the same client process.
   2879                     synchronized(mSetModeDeathHandlers) {
   2880                         if ((mSetModeDeathHandlers.isEmpty() ||
   2881                                 mSetModeDeathHandlers.get(0).getPid() == mCreatorPid) &&
   2882                                 (mScoAudioState == SCO_STATE_INACTIVE ||
   2883                                  mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
   2884                             if (mScoAudioState == SCO_STATE_INACTIVE) {
   2885                                 mScoAudioMode = scoAudioMode;
   2886                                 if (scoAudioMode == SCO_MODE_UNDEFINED) {
   2887                                     if (mBluetoothHeadsetDevice != null) {
   2888                                         mScoAudioMode = new Integer(Settings.Global.getInt(
   2889                                                                 mContentResolver,
   2890                                                                 "bluetooth_sco_channel_"+
   2891                                                                 mBluetoothHeadsetDevice.getAddress(),
   2892                                                                 SCO_MODE_VIRTUAL_CALL));
   2893                                         if (mScoAudioMode > SCO_MODE_MAX || mScoAudioMode < 0) {
   2894                                             mScoAudioMode = SCO_MODE_VIRTUAL_CALL;
   2895                                         }
   2896                                     } else {
   2897                                         mScoAudioMode = SCO_MODE_RAW;
   2898                                     }
   2899                                 }
   2900                                 if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
   2901                                     boolean status = false;
   2902                                     if (mScoAudioMode == SCO_MODE_RAW) {
   2903                                         status = mBluetoothHeadset.connectAudio();
   2904                                     } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) {
   2905                                         status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
   2906                                                                             mBluetoothHeadsetDevice);
   2907                                     } else if (mScoAudioMode == SCO_MODE_VR) {
   2908                                         status = mBluetoothHeadset.startVoiceRecognition(
   2909                                                                            mBluetoothHeadsetDevice);
   2910                                     }
   2911 
   2912                                     if (status) {
   2913                                         mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
   2914                                     } else {
   2915                                         broadcastScoConnectionState(
   2916                                                 AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
   2917                                     }
   2918                                 } else if (getBluetoothHeadset()) {
   2919                                     mScoAudioState = SCO_STATE_ACTIVATE_REQ;
   2920                                 }
   2921                             } else {
   2922                                 mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
   2923                                 broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
   2924                             }
   2925                         } else {
   2926                             broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
   2927                         }
   2928                     }
   2929                 } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED &&
   2930                               (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL ||
   2931                                mScoAudioState == SCO_STATE_ACTIVATE_REQ)) {
   2932                     if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) {
   2933                         if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
   2934                             boolean status = false;
   2935                             if (mScoAudioMode == SCO_MODE_RAW) {
   2936                                 status = mBluetoothHeadset.disconnectAudio();
   2937                             } else if (mScoAudioMode == SCO_MODE_VIRTUAL_CALL) {
   2938                                 status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
   2939                                                                         mBluetoothHeadsetDevice);
   2940                             } else if (mScoAudioMode == SCO_MODE_VR) {
   2941                                         status = mBluetoothHeadset.stopVoiceRecognition(
   2942                                                                       mBluetoothHeadsetDevice);
   2943                             }
   2944 
   2945                             if (!status) {
   2946                                 mScoAudioState = SCO_STATE_INACTIVE;
   2947                                 broadcastScoConnectionState(
   2948                                         AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
   2949                             }
   2950                         } else if (getBluetoothHeadset()) {
   2951                             mScoAudioState = SCO_STATE_DEACTIVATE_REQ;
   2952                         }
   2953                     } else {
   2954                         mScoAudioState = SCO_STATE_INACTIVE;
   2955                         broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
   2956                     }
   2957                 }
   2958             }
   2959         }
   2960     }
   2961 
   2962     private void checkScoAudioState() {
   2963         if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null &&
   2964                 mScoAudioState == SCO_STATE_INACTIVE &&
   2965                 mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
   2966                 != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
   2967             mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
   2968         }
   2969     }
   2970 
   2971     private ScoClient getScoClient(IBinder cb, boolean create) {
   2972         synchronized(mScoClients) {
   2973             ScoClient client = null;
   2974             int size = mScoClients.size();
   2975             for (int i = 0; i < size; i++) {
   2976                 client = mScoClients.get(i);
   2977                 if (client.getBinder() == cb)
   2978                     return client;
   2979             }
   2980             if (create) {
   2981                 client = new ScoClient(cb);
   2982                 mScoClients.add(client);
   2983             }
   2984             return client;
   2985         }
   2986     }
   2987 
   2988     public void clearAllScoClients(int exceptPid, boolean stopSco) {
   2989         synchronized(mScoClients) {
   2990             ScoClient savedClient = null;
   2991             int size = mScoClients.size();
   2992             for (int i = 0; i < size; i++) {
   2993                 ScoClient cl = mScoClients.get(i);
   2994                 if (cl.getPid() != exceptPid) {
   2995                     cl.clearCount(stopSco);
   2996                 } else {
   2997                     savedClient = cl;
   2998                 }
   2999             }
   3000             mScoClients.clear();
   3001             if (savedClient != null) {
   3002                 mScoClients.add(savedClient);
   3003             }
   3004         }
   3005     }
   3006 
   3007     private boolean getBluetoothHeadset() {
   3008         boolean result = false;
   3009         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
   3010         if (adapter != null) {
   3011             result = adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
   3012                                     BluetoothProfile.HEADSET);
   3013         }
   3014         // If we could not get a bluetooth headset proxy, send a failure message
   3015         // without delay to reset the SCO audio state and clear SCO clients.
   3016         // If we could get a proxy, send a delayed failure message that will reset our state
   3017         // in case we don't receive onServiceConnected().
   3018         sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED,
   3019                 SENDMSG_REPLACE, 0, 0, null, result ? BT_HEADSET_CNCT_TIMEOUT_MS : 0);
   3020         return result;
   3021     }
   3022 
   3023     private void disconnectBluetoothSco(int exceptPid) {
   3024         synchronized(mScoClients) {
   3025             checkScoAudioState();
   3026             if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL ||
   3027                     mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) {
   3028                 if (mBluetoothHeadsetDevice != null) {
   3029                     if (mBluetoothHeadset != null) {
   3030                         if (!mBluetoothHeadset.stopVoiceRecognition(
   3031                                 mBluetoothHeadsetDevice)) {
   3032                             sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED,
   3033                                     SENDMSG_REPLACE, 0, 0, null, 0);
   3034                         }
   3035                     } else if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL &&
   3036                             getBluetoothHeadset()) {
   3037                         mScoAudioState = SCO_STATE_DEACTIVATE_EXT_REQ;
   3038                     }
   3039                 }
   3040             } else {
   3041                 clearAllScoClients(exceptPid, true);
   3042             }
   3043         }
   3044     }
   3045 
   3046     private void resetBluetoothSco() {
   3047         synchronized(mScoClients) {
   3048             clearAllScoClients(0, false);
   3049             mScoAudioState = SCO_STATE_INACTIVE;
   3050             broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
   3051         }
   3052         AudioSystem.setParameters("A2dpSuspended=false");
   3053         setBluetoothScoOnInt(false);
   3054     }
   3055 
   3056     private void broadcastScoConnectionState(int state) {
   3057         sendMsg(mAudioHandler, MSG_BROADCAST_BT_CONNECTION_STATE,
   3058                 SENDMSG_QUEUE, state, 0, null, 0);
   3059     }
   3060 
   3061     private void onBroadcastScoConnectionState(int state) {
   3062         if (state != mScoConnectionState) {
   3063             Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
   3064             newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, state);
   3065             newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE,
   3066                     mScoConnectionState);
   3067             sendStickyBroadcastToAll(newIntent);
   3068             mScoConnectionState = state;
   3069         }
   3070     }
   3071 
   3072     void setBtScoDeviceConnectionState(BluetoothDevice btDevice, int state) {
   3073         if (btDevice == null) {
   3074             return;
   3075         }
   3076 
   3077         String address = btDevice.getAddress();
   3078         BluetoothClass btClass = btDevice.getBluetoothClass();
   3079         int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
   3080         int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
   3081         if (btClass != null) {
   3082             switch (btClass.getDeviceClass()) {
   3083             case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
   3084             case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
   3085                 outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
   3086                 break;
   3087             case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
   3088                 outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
   3089                 break;
   3090             }
   3091         }
   3092 
   3093         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
   3094             address = "";
   3095         }
   3096 
   3097         boolean connected = (state == BluetoothProfile.STATE_CONNECTED);
   3098 
   3099         String btDeviceName =  btDevice.getName();
   3100         boolean success =
   3101             handleDeviceConnection(connected, outDevice, address, btDeviceName) &&
   3102             handleDeviceConnection(connected, inDevice, address, btDeviceName);
   3103         if (success) {
   3104             synchronized (mScoClients) {
   3105                 if (connected) {
   3106                     mBluetoothHeadsetDevice = btDevice;
   3107                 } else {
   3108                     mBluetoothHeadsetDevice = null;
   3109                     resetBluetoothSco();
   3110                 }
   3111             }
   3112         }
   3113     }
   3114 
   3115     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
   3116         new BluetoothProfile.ServiceListener() {
   3117         public void onServiceConnected(int profile, BluetoothProfile proxy) {
   3118             BluetoothDevice btDevice;
   3119             List<BluetoothDevice> deviceList;
   3120             switch(profile) {
   3121             case BluetoothProfile.A2DP:
   3122                 synchronized (mConnectedDevices) {
   3123                     synchronized (mA2dpAvrcpLock) {
   3124                         mA2dp = (BluetoothA2dp) proxy;
   3125                         deviceList = mA2dp.getConnectedDevices();
   3126                         if (deviceList.size() > 0) {
   3127                             btDevice = deviceList.get(0);
   3128                             int state = mA2dp.getConnectionState(btDevice);
   3129                             int delay = checkSendBecomingNoisyIntent(
   3130                                                 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
   3131                                                 (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
   3132                             queueMsgUnderWakeLock(mAudioHandler,
   3133                                     MSG_SET_A2DP_SINK_CONNECTION_STATE,
   3134                                     state,
   3135                                     0,
   3136                                     btDevice,
   3137                                     delay);
   3138                         }
   3139                     }
   3140                 }
   3141                 break;
   3142 
   3143             case BluetoothProfile.A2DP_SINK:
   3144                 deviceList = proxy.getConnectedDevices();
   3145                 if (deviceList.size() > 0) {
   3146                     btDevice = deviceList.get(0);
   3147                     synchronized (mConnectedDevices) {