Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cee7203f authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "Send device connection intents from AudioService" into jb-dev

parents 43cee47d b1fbaacc
Loading
Loading
Loading
Loading
+49 −10
Original line number Diff line number Diff line
@@ -33,7 +33,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.Settings;
import android.util.Log;

@@ -65,6 +69,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
    private final BluetoothAdapter mAdapter;
    private int   mTargetA2dpState;
    private BluetoothDevice mPlayingA2dpDevice;
    private IntentBroadcastHandler mIntentBroadcastHandler;
    private final WakeLock mWakeLock;

    private static final int MSG_CONNECTION_STATE_CHANGED = 0;

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
@@ -131,6 +139,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
    public BluetoothA2dpService(Context context, BluetoothService bluetoothService) {
        mContext = context;

        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BluetoothA2dpService");

        mIntentBroadcastHandler = new IntentBroadcastHandler();

        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

        mBluetoothService = bluetoothService;
@@ -514,17 +527,15 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
                adjustOtherSinkPriorities(device);
            }

            Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
            intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
            int delay = mAudioManager.setBluetoothA2dpDeviceConnectionState(device, state);

            if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);

            mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
                                                        prevState);
            mWakeLock.acquire();
            mIntentBroadcastHandler.sendMessageDelayed(mIntentBroadcastHandler.obtainMessage(
                                                            MSG_CONNECTION_STATE_CHANGED,
                                                            prevState,
                                                            state,
                                                            device),
                                                       delay);
        }
    }

@@ -586,6 +597,34 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
        }
    }

    /** Handles A2DP connection state change intent broadcasts. */
    private class IntentBroadcastHandler extends Handler {

        private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
            Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
            intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
            mContext.sendBroadcast(intent, BLUETOOTH_PERM);

            if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);

            mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
                                                        prevState);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CONNECTION_STATE_CHANGED:
                    onConnectionStateChanged((BluetoothDevice) msg.obj, msg.arg1, msg.arg2);
                    mWakeLock.release();
                    break;
            }
        }
    }

    @Override
    protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+37 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.media;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -2376,6 +2377,42 @@ public class AudioManager {
        }
    }

     /**
     * Indicate wired accessory connection state change.
     * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
     * @param state  new connection state: 1 connected, 0 disconnected
     * @param name   device name
     * {@hide}
     */
    public void setWiredDeviceConnectionState(int device, int state, String name) {
        IAudioService service = getService();
        try {
            service.setWiredDeviceConnectionState(device, state, name);
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e);
        }
    }

     /**
     * Indicate A2DP sink connection state change.
     * @param device Bluetooth device connected/disconnected
     * @param state  new connection state (BluetoothProfile.STATE_xxx)
     * @return a delay in ms that the caller should wait before broadcasting
     * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
     * {@hide}
     */
    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) {
        IAudioService service = getService();
        int delay = 0;
        try {
            delay = service.setBluetoothA2dpDeviceConnectionState(device, state);
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e);
        } finally {
            return delay;
        }
    }

    /** {@hide} */
    public IRingtonePlayer getRingtonePlayer() {
        try {
+125 −50
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
    private static final int MSG_RCDISPLAY_UPDATE = 13;
    private static final int MSG_SET_ALL_VOLUMES = 14;
    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
    private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;


    // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -442,15 +444,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

        // Register for device connection intent broadcasts.
        IntentFilter intentFilter =
                new IntentFilter(Intent.ACTION_HEADSET_PLUG);

        intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
                new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
        intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
        intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
        intentFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
        intentFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
        intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
        intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
        intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
        intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
@@ -1961,7 +1957,19 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                deviceList = a2dp.getConnectedDevices();
                if (deviceList.size() > 0) {
                    btDevice = deviceList.get(0);
                    handleA2dpConnectionStateChange(btDevice, a2dp.getConnectionState(btDevice));
                    synchronized (mConnectedDevices) {
                        int state = a2dp.getConnectionState(btDevice);
                        int delay = checkSendBecomingNoisyIntent(
                                                AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                                (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
                        sendMsg(mAudioHandler,
                                MSG_SET_A2DP_CONNECTION_STATE,
                                SENDMSG_QUEUE,
                                state,
                                0,
                                btDevice,
                                delay);
                    }
                }
                break;

@@ -2262,6 +2270,36 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        return device;
    }

    public void setWiredDeviceConnectionState(int device, int state, String name) {
        synchronized (mConnectedDevices) {
            int delay = checkSendBecomingNoisyIntent(device, state);
            sendMsg(mAudioHandler,
                    MSG_SET_WIRED_DEVICE_CONNECTION_STATE,
                    SENDMSG_QUEUE,
                    device,
                    state,
                    name,
                    delay);
        }
    }

    public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)
    {
        int delay;
        synchronized (mConnectedDevices) {
            delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                                            (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
            sendMsg(mAudioHandler,
                    MSG_SET_A2DP_CONNECTION_STATE,
                    SENDMSG_QUEUE,
                    state,
                    0,
                    device,
                    delay);
        }
        return delay;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Inner classes
    ///////////////////////////////////////////////////////////////////////////
@@ -2959,6 +2997,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                case MSG_BT_HEADSET_CNCT_FAILED:
                    resetBluetoothSco();
                    break;

                case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
                    onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
                    break;

                case MSG_SET_A2DP_CONNECTION_STATE:
                    onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
                    break;
            }
        }
    }
@@ -3020,7 +3066,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {

    // must be called synchronized on mConnectedDevices
    private void makeA2dpDeviceUnavailableNow(String address) {
        sendBecomingNoisyIntent();
        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                AudioSystem.DEVICE_STATE_UNAVAILABLE,
                address);
@@ -3050,7 +3095,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
    }

    private void handleA2dpConnectionStateChange(BluetoothDevice btDevice, int state)
    private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
    {
        if (btDevice == null) {
            return;
@@ -3116,6 +3161,76 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        return false;
    }

    // Devices which removal triggers intent ACTION_AUDIO_BECOMING_NOISY. The intent is only
    // sent if none of these devices is connected.
    int mBecomingNoisyIntentDevices =
            AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
            AudioSystem.DEVICE_OUT_ALL_A2DP;

    // must be called before removing the device from mConnectedDevices
    private int checkSendBecomingNoisyIntent(int device, int state) {
        int delay = 0;
        if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) {
            int devices = 0;
            for (int dev : mConnectedDevices.keySet()) {
                if ((dev & mBecomingNoisyIntentDevices) != 0) {
                   devices |= dev;
                }
            }
            if (devices == device) {
                delay = 1000;
                sendBecomingNoisyIntent();
            }
        }

        if (mAudioHandler.hasMessages(MSG_SET_A2DP_CONNECTION_STATE) ||
                mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
            delay = 1000;
        }
        return delay;
    }

    private void sendDeviceConnectionIntent(int device, int state, String name)
    {
        Intent intent = new Intent();

        intent.putExtra("state", state);
        intent.putExtra("name", name);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

        if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
            intent.setAction(Intent.ACTION_HEADSET_PLUG);
            intent.putExtra("microphone", 1);
        } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
            intent.setAction(Intent.ACTION_HEADSET_PLUG);
            intent.putExtra("microphone", 0);
        } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
            intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
        } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
            intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
        } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
            intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
        }

        ActivityManagerNative.broadcastStickyIntent(intent, null);
    }

    private void onSetWiredDeviceConnectionState(int device, int state, String name)
    {
        synchronized (mConnectedDevices) {
            if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
                setBluetoothA2dpOnInt(true);
            }
            handleDeviceConnection((state == 1), device, "");
            if ((state != 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
                setBluetoothA2dpOnInt(false);
            }
            sendDeviceConnectionIntent(device, state, name);
        }
    }

    /* cache of the address of the last dock the device was connected to */
    private String mDockAddress;

@@ -3151,12 +3266,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                        config = AudioSystem.FORCE_NONE;
                }
                AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
            } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
                state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                               BluetoothProfile.STATE_DISCONNECTED);
                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                handleA2dpConnectionStateChange(btDevice, state);
            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                               BluetoothProfile.STATE_DISCONNECTED);
@@ -3197,43 +3306,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                        }
                    }
                }
            } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
                state = intent.getIntExtra("state", 0);
                int microphone = intent.getIntExtra("microphone", 0);

                if (microphone != 0) {
                    device = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
                } else {
                    device = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
                }
                // enable A2DP before notifying headset disconnection to avoid glitches
                if (state == 0) {
                    setBluetoothA2dpOnInt(true);
                }
                handleDeviceConnection((state == 1), device, "");
                // disable A2DP after notifying headset connection to avoid glitches
                if (state != 0) {
                    setBluetoothA2dpOnInt(false);
                }
            } else if (action.equals(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG)) {
                state = intent.getIntExtra("state", 0);
                Log.v(TAG, "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = "+state);
                handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, "");
            } else if (action.equals(Intent.ACTION_HDMI_AUDIO_PLUG)) {
                state = intent.getIntExtra("state", 0);
                Log.v(TAG, "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = "+state);
                handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_AUX_DIGITAL, "");
            } else if (action.equals(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG)) {
                state = intent.getIntExtra("state", 0);
                Log.v(TAG,
                      "Broadcast Receiver Got ACTION_DIGITAL_AUDIO_DOCK_PLUG, state = " + state);
                handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, "");
            } else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ||
                           action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) {
                state = intent.getIntExtra("state", 0);
                if (state == 0) {
                    sendBecomingNoisyIntent();
                }
                int alsaCard = intent.getIntExtra("card", -1);
                int alsaDevice = intent.getIntExtra("device", -1);
                String params = (alsaCard == -1 && alsaDevice == -1 ? ""
+4 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.media;

import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.media.IAudioFocusDispatcher;
import android.media.IRemoteControlClient;
@@ -133,4 +134,7 @@ interface IAudioService {
    void setRingtonePlayer(IRingtonePlayer player);
    IRingtonePlayer getRingtonePlayer();
    int getMasterStreamType();

    void setWiredDeviceConnectionState(int device, int state, String name);
    int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
}
+36 −74
Original line number Diff line number Diff line
@@ -139,11 +139,14 @@ class WiredAccessoryObserver extends UEventObserver {
    private final Context mContext;
    private final WakeLock mWakeLock;  // held while there is a pending route change

    private final AudioManager mAudioManager;

    public WiredAccessoryObserver(Context context) {
        mContext = context;
        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryObserver");
        mWakeLock.setReferenceCounted(false);
        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);

        context.registerReceiver(new BootCompletedReceiver(),
            new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
@@ -250,106 +253,65 @@ class WiredAccessoryObserver extends UEventObserver {
        mPrevHeadsetState = mHeadsetState;
        mHeadsetState = headsetState;

        if (headsetState == 0) {
            if (mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_sendAudioBecomingNoisy)) {
                Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
                mContext.sendBroadcast(intent);
            }

            // It can take hundreds of ms flush the audio pipeline after
            // apps pause audio playback, but audio route changes are
            // immediate, so delay the route change by 1000ms.
            // This could be improved once the audio sub-system provides an
            // interface to clear the audio pipeline.
            delay = 1000;
        } else {
            // Insert the same delay for headset connection so that the connection event is not
            // broadcast before the disconnection event in case of fast removal/insertion
            if (mHandler.hasMessages(0)) {
                delay = 1000;
            }
        }
        mWakeLock.acquire();
        mHandler.sendMessageDelayed(mHandler.obtainMessage(0,
        mHandler.sendMessage(mHandler.obtainMessage(0,
                                                    mHeadsetState,
                                                    mPrevHeadsetState,
                                                           mHeadsetName),
                                    delay);
                                                    mHeadsetName));
    }

    private synchronized final void sendIntents(int headsetState, int prevHeadsetState, String headsetName) {
    private synchronized final void setDevicesState(int headsetState,
                                                    int prevHeadsetState,
                                                    String headsetName) {
        int allHeadsets = SUPPORTED_HEADSETS;
        for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
            if ((curHeadset & allHeadsets) != 0) {
                sendIntent(curHeadset, headsetState, prevHeadsetState, headsetName);
                setDeviceState(curHeadset, headsetState, prevHeadsetState, headsetName);
                allHeadsets &= ~curHeadset;
            }
        }
    }

    private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) {
    private final void setDeviceState(int headset,
                                      int headsetState,
                                      int prevHeadsetState,
                                      String headsetName) {
        if ((headsetState & headset) != (prevHeadsetState & headset)) {
            int device;
            int state;

            int state = 0;
            if ((headsetState & headset) != 0) {
                state = 1;
            } else {
                state = 0;
            }
            if((headset == BIT_USB_HEADSET_ANLG) || (headset == BIT_USB_HEADSET_DGTL) ||
               (headset == BIT_HDMI_AUDIO)) {
                Intent intent;

                //  Pack up the values and broadcast them to everyone
                if (headset == BIT_USB_HEADSET_ANLG) {
                    intent = new Intent(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    intent.putExtra("state", state);
                    intent.putExtra("name", headsetName);
                    ActivityManagerNative.broadcastStickyIntent(intent, null);

            if (headset == BIT_HEADSET) {
                device = AudioManager.DEVICE_OUT_WIRED_HEADSET;
            } else if (headset == BIT_HEADSET_NO_MIC){
                device = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
            } else if (headset == BIT_USB_HEADSET_ANLG) {
                device = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
            } else if (headset == BIT_USB_HEADSET_DGTL) {
                    intent = new Intent(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    intent.putExtra("state", state);
                    intent.putExtra("name", headsetName);
                    ActivityManagerNative.broadcastStickyIntent(intent, null);
                device = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
            } else if (headset == BIT_HDMI_AUDIO) {
                    intent = new Intent(Intent.ACTION_HDMI_AUDIO_PLUG);
                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    intent.putExtra("state", state);
                    intent.putExtra("name", headsetName);
                    ActivityManagerNative.broadcastStickyIntent(intent, null);
                }

                if (LOG) Slog.v(TAG, "Intent.ACTION_USB_HEADSET_PLUG: state: "+state+" name: "+headsetName);
                // TODO: Should we require a permission?
            }
            if((headset == BIT_HEADSET) || (headset == BIT_HEADSET_NO_MIC)) {

                //  Pack up the values and broadcast them to everyone
                Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                //int state = 0;
                int microphone = 0;

                if ((headset & HEADSETS_WITH_MIC) != 0) {
                    microphone = 1;
                device = AudioManager.DEVICE_OUT_AUX_DIGITAL;
            } else {
                Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
                return;
            }

                intent.putExtra("state", state);
                intent.putExtra("name", headsetName);
                intent.putExtra("microphone", microphone);
            if (LOG)
                Slog.v(TAG, "device "+headsetName+((state == 1) ? " connected" : " disconnected"));

                if (LOG) Slog.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+headsetName+" mic: "+microphone);
                // TODO: Should we require a permission?
                ActivityManagerNative.broadcastStickyIntent(intent, null);
            }
            mAudioManager.setWiredDeviceConnectionState(device, state, headsetName);
        }
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            sendIntents(msg.arg1, msg.arg2, (String)msg.obj);
            setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
            mWakeLock.release();
        }
    };