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

Commit c383b407 authored by Eric Laurent's avatar Eric Laurent Committed by Android Git Automerger
Browse files

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

* commit 'cee7203f':
  Send device connection intents from AudioService
parents 64846efd cee7203f
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();
        }
    };