diff options
| author | Praveen Bharathi <pbharathi@motorola.com> | 2010-10-06 15:23:14 -0500 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2010-11-01 18:41:19 -0700 |
| commit | 21e941bf43362ddc6639a9f2d0828053360f53d7 (patch) | |
| tree | 686b10bd26b899198a744c6e38d4ffa6585714b7 /services | |
| parent | 879ed85598800bd2d87b7fe96d0a763d9b954a6e (diff) | |
| download | frameworks_base-21e941bf43362ddc6639a9f2d0828053360f53d7.zip frameworks_base-21e941bf43362ddc6639a9f2d0828053360f53d7.tar.gz frameworks_base-21e941bf43362ddc6639a9f2d0828053360f53d7.tar.bz2 | |
Added support for dock headset observer
Change-Id: I06b2e65e3bfa10735e6c7fd3349afa9ae7d45292
Signed-off-by: Praveen Bharathi <pbharathi@motorola.com>
Diffstat (limited to 'services')
5 files changed, 292 insertions, 198 deletions
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp index 65d9ef7..86d4c9f 100644 --- a/services/audioflinger/AudioPolicyManagerBase.cpp +++ b/services/audioflinger/AudioPolicyManagerBase.cpp @@ -356,7 +356,9 @@ void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSyst break; case AudioSystem::FOR_MEDIA: if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP && - config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE) { + config != AudioSystem::FORCE_WIRED_ACCESSORY && + config != AudioSystem::FORCE_ANALOG_DOCK && + config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE) { LOGW("setForceUse() invalid config %d for FOR_MEDIA", config); return; } @@ -372,7 +374,10 @@ void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSyst break; case AudioSystem::FOR_DOCK: if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK && - config != AudioSystem::FORCE_BT_DESK_DOCK && config != AudioSystem::FORCE_WIRED_ACCESSORY) { + config != AudioSystem::FORCE_BT_DESK_DOCK && + config != AudioSystem::FORCE_WIRED_ACCESSORY && + config != AudioSystem::FORCE_ANALOG_DOCK && + config != AudioSystem::FORCE_DIGITAL_DOCK) { LOGW("setForceUse() invalid config %d for FOR_DOCK", config); } forceVolumeReeval = true; @@ -1366,6 +1371,7 @@ status_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devi void AudioPolicyManagerBase::closeA2dpOutputs() { + LOGV("setDeviceConnectionState() closing A2DP and duplicated output!"); if (mDuplicatedOutput != 0) { @@ -1558,6 +1564,8 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, if (device) break; device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; if (device) break; + device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; + if (device) break; #ifdef WITH_A2DP // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP if (mPhoneState != AudioSystem::MODE_IN_CALL) { @@ -1617,6 +1625,12 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, if (device2 == 0) { device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET; } + if (device2 == 0) { + device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; + } + if (device2 == 0) { + device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET; + } #ifdef WITH_A2DP if (mA2dpOutput != 0) { if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) { @@ -1797,7 +1811,9 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP | AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | AudioSystem::DEVICE_OUT_WIRED_HEADSET | - AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && + AudioSystem::DEVICE_OUT_WIRED_HEADPHONE | + AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET | + AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) && (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) && streamDesc.mCanBeMuted) { volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index bee8872..f993093 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -103,7 +103,6 @@ class DockObserver extends UEventObserver { FileReader file = new FileReader(DOCK_STATE_PATH); int len = file.read(buffer, 0, 1024); mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim()); - } catch (FileNotFoundException e) { Slog.w(TAG, "This kernel does not have dock station support"); } catch (Exception e) { @@ -158,13 +157,17 @@ class DockObserver extends UEventObserver { { String whichSound = null; if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) { - if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) { + if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) || + (mPreviousDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || + (mPreviousDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) { whichSound = Settings.System.DESK_UNDOCK_SOUND; } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) { whichSound = Settings.System.CAR_UNDOCK_SOUND; } } else { - if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { + if ((mDockState == Intent.EXTRA_DOCK_STATE_DESK) || + (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || + (mDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) { whichSound = Settings.System.DESK_DOCK_SOUND; } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) { whichSound = Settings.System.CAR_DOCK_SOUND; diff --git a/services/java/com/android/server/HeadsetObserver.java b/services/java/com/android/server/HeadsetObserver.java deleted file mode 100644 index 6f0a91d..0000000 --- a/services/java/com/android/server/HeadsetObserver.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import android.app.ActivityManagerNative; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.UEventObserver; -import android.util.Slog; -import android.media.AudioManager; - -import java.io.FileReader; -import java.io.FileNotFoundException; - -/** - * <p>HeadsetObserver monitors for a wired headset. - */ -class HeadsetObserver extends UEventObserver { - private static final String TAG = HeadsetObserver.class.getSimpleName(); - private static final boolean LOG = true; - - private static final String HEADSET_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/h2w"; - private static final String HEADSET_STATE_PATH = "/sys/class/switch/h2w/state"; - private static final String HEADSET_NAME_PATH = "/sys/class/switch/h2w/name"; - - private static final int BIT_HEADSET = (1 << 0); - private static final int BIT_HEADSET_NO_MIC = (1 << 1); - private static final int SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC); - private static final int HEADSETS_WITH_MIC = BIT_HEADSET; - - private int mHeadsetState; - private int mPrevHeadsetState; - private String mHeadsetName; - - private final Context mContext; - private final WakeLock mWakeLock; // held while there is a pending route change - - public HeadsetObserver(Context context) { - mContext = context; - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "HeadsetObserver"); - mWakeLock.setReferenceCounted(false); - - startObserving(HEADSET_UEVENT_MATCH); - - init(); // set initial status - } - - @Override - public void onUEvent(UEventObserver.UEvent event) { - if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString()); - - try { - update(event.get("SWITCH_NAME"), Integer.parseInt(event.get("SWITCH_STATE"))); - } catch (NumberFormatException e) { - Slog.e(TAG, "Could not parse switch state from event " + event); - } - } - - private synchronized final void init() { - char[] buffer = new char[1024]; - - String newName = mHeadsetName; - int newState = mHeadsetState; - mPrevHeadsetState = mHeadsetState; - try { - FileReader file = new FileReader(HEADSET_STATE_PATH); - int len = file.read(buffer, 0, 1024); - newState = Integer.valueOf((new String(buffer, 0, len)).trim()); - - file = new FileReader(HEADSET_NAME_PATH); - len = file.read(buffer, 0, 1024); - newName = new String(buffer, 0, len).trim(); - - } catch (FileNotFoundException e) { - Slog.w(TAG, "This kernel does not have wired headset support"); - } catch (Exception e) { - Slog.e(TAG, "" , e); - } - - update(newName, newState); - } - - private synchronized final void update(String newName, int newState) { - // Retain only relevant bits - int headsetState = newState & SUPPORTED_HEADSETS; - int newOrOld = headsetState | mHeadsetState; - int delay = 0; - // reject all suspect transitions: only accept state changes from: - // - a: 0 heaset to 1 headset - // - b: 1 headset to 0 headset - if (mHeadsetState == headsetState || ((newOrOld & (newOrOld - 1)) != 0)) { - return; - } - - mHeadsetName = newName; - mPrevHeadsetState = mHeadsetState; - mHeadsetState = headsetState; - - if (headsetState == 0) { - 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, - mHeadsetState, - mPrevHeadsetState, - mHeadsetName), - delay); - } - - private synchronized final void sendIntents(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); - allHeadsets &= ~curHeadset; - } - } - } - - private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) { - if ((headsetState & headset) != (prevHeadsetState & headset)) { - // 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; - } - if ((headsetState & headset) != 0) { - state = 1; - } - intent.putExtra("state", state); - intent.putExtra("name", headsetName); - intent.putExtra("microphone", microphone); - - 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); - } - } - - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - sendIntents(msg.arg1, msg.arg2, (String)msg.obj); - mWakeLock.release(); - } - }; -} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 237ab80..54f7441 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -121,7 +121,7 @@ class ServerThread extends Thread { WindowManagerService wm = null; BluetoothService bluetooth = null; BluetoothA2dpService bluetoothA2dp = null; - HeadsetObserver headset = null; + WiredAccessoryObserver wiredAccessory = null; DockObserver dock = null; UsbObserver usb = null; UiModeManagerService uiMode = null; @@ -388,14 +388,6 @@ class ServerThread extends Thread { } try { - Slog.i(TAG, "Headset Observer"); - // Listen for wired headset changes - headset = new HeadsetObserver(context); - } catch (Throwable e) { - Slog.e(TAG, "Failure starting HeadsetObserver", e); - } - - try { Slog.i(TAG, "Dock Observer"); // Listen for dock station changes dock = new DockObserver(context, power); @@ -404,6 +396,14 @@ class ServerThread extends Thread { } try { + Slog.i(TAG, "Wired Accessory Observer"); + // Listen for wired headset changes + wiredAccessory = new WiredAccessoryObserver(context); + } catch (Throwable e) { + Slog.e(TAG, "Failure starting WiredAccessoryObserver", e); + } + + try { Slog.i(TAG, "USB Observer"); // Listen for USB changes usb = new UsbObserver(context); diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java new file mode 100644 index 0000000..ab92fdf --- /dev/null +++ b/services/java/com/android/server/WiredAccessoryObserver.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.app.ActivityManagerNative; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.Message; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.os.UEventObserver; +import android.util.Slog; +import android.media.AudioManager; +import android.util.Log; + +import java.io.FileReader; +import java.io.FileNotFoundException; + +/** + * <p>WiredAccessoryObserver monitors for a wired headset on the main board or dock. + */ +class WiredAccessoryObserver extends UEventObserver { + private static final String TAG = WiredAccessoryObserver.class.getSimpleName(); + private static final boolean LOG = true; + private static final int MAX_AUDIO_PORTS = 2; /* h2w & USB Audio */ + private static final String uEventInfo[][] = { {"DEVPATH=/devices/virtual/switch/h2w", + "/sys/class/switch/h2w/state", + "/sys/class/switch/h2w/name"}, + {"DEVPATH=/devices/virtual/switch/usb_audio", + "/sys/class/switch/usb_audio/state", + "/sys/class/switch/usb_audio/name"} }; + + private static final int BIT_HEADSET = (1 << 0); + private static final int BIT_HEADSET_NO_MIC = (1 << 1); + private static final int BIT_USB_HEADSET_ANLG = (1 << 2); + private static final int BIT_USB_HEADSET_DGTL = (1 << 3); + private static final int SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC| + BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL); + private static final int HEADSETS_WITH_MIC = BIT_HEADSET; + + private int mHeadsetState; + private int mPrevHeadsetState; + private String mHeadsetName; + private int switchState; + + private final Context mContext; + private final WakeLock mWakeLock; // held while there is a pending route change + + 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); + + // At any given time both headsets could be inserted + // one on the board and one on the dock + // observe two UEVENTs + for (int i = 0; i <= MAX_AUDIO_PORTS; i++) { + startObserving(uEventInfo[i][0]); + } + init(); // set initial status + } + + @Override + public void onUEvent(UEventObserver.UEvent event) { + if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString()); + + try { + if ((event.get("SWITCH_NAME")).equals("usb_audio")) { + if (Integer.parseInt(event.get("SWITCH_STATE")) == 1) { + switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| + BIT_USB_HEADSET_DGTL)) | + (Integer.parseInt(event.get("SWITCH_STATE")) << 2)); + } else if (Integer.parseInt(event.get("SWITCH_STATE")) == 2) { + switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| + BIT_USB_HEADSET_ANLG)) | + (Integer.parseInt(event.get("SWITCH_STATE")) << 3)); + } + else switchState = (mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC)); + } + else { + switchState = ((mHeadsetState & (BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL)) | + (Integer.parseInt(event.get("SWITCH_STATE")))); + } + update(event.get("SWITCH_NAME"), switchState); + } catch (NumberFormatException e) { + Slog.e(TAG, "Could not parse switch state from event " + event); + } + } + + private synchronized final void init() { + char[] buffer = new char[1024]; + + String newName = mHeadsetName; + int newState = mHeadsetState; + mPrevHeadsetState = mHeadsetState; + + for (int i = 0; i <= MAX_AUDIO_PORTS; i++) { + try { + FileReader file = new FileReader(uEventInfo[i][1]); + int len = file.read(buffer, 0, 1024); + newState = Integer.valueOf((new String(buffer, 0, len)).trim()); + + file = new FileReader(uEventInfo[i][2]); + len = file.read(buffer, 0, 1024); + newName = new String(buffer, 0, len).trim(); + + } catch (FileNotFoundException e) { + Slog.w(TAG, "This kernel does not have wired headset support"); + } catch (Exception e) { + Slog.e(TAG, "" , e); + } + + update(newName, newState); + } + } + + private synchronized final void update(String newName, int newState) { + // Retain only relevant bits + int headsetState = newState & SUPPORTED_HEADSETS; + int newOrOld = headsetState | mHeadsetState; + int delay = 0; + int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG; + int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL; + int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC); + boolean h2wStateChange = true; + boolean usbStateChange = true; + // reject all suspect transitions: only accept state changes from: + // - a: 0 heaset to 1 headset + // - b: 1 headset to 0 headset + Log.v(TAG, "newState = "+newState+", headsetState = "+headsetState+", mHeadsetState = "+mHeadsetState); + if (mHeadsetState == headsetState || ((h2w_headset & (h2w_headset - 1)) != 0)) { + Log.e(TAG, "unsetting h2w flag"); + h2wStateChange = false; + } + // - c: 0 usb headset to 1 usb headset + // - d: 1 usb headset to 0 usb headset + if ((usb_headset_anlg >> 2) == 1 && (usb_headset_dgtl >> 3) == 1) { + Log.e(TAG, "unsetting usb flag"); + usbStateChange = false; + } + if (!h2wStateChange && !usbStateChange) { + Log.e(TAG, "invalid transition, returning ..."); + return; + } + + mHeadsetName = newName; + mPrevHeadsetState = mHeadsetState; + mHeadsetState = headsetState; + + if (headsetState == 0) { + 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, + mHeadsetState, + mPrevHeadsetState, + mHeadsetName), + delay); + } + + private synchronized final void sendIntents(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); + allHeadsets &= ~curHeadset; + } + } + } + + private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) { + if ((headsetState & headset) != (prevHeadsetState & headset)) { + + int state = 0; + if ((headsetState & headset) != 0) { + state = 1; + } + if((headset == BIT_USB_HEADSET_ANLG) || (headset == BIT_USB_HEADSET_DGTL)) { + Intent intent; + + // Pack up the values and broadcast them to everyone + if (headset == BIT_USB_HEADSET_ANLG) { + intent = new Intent(Intent.ACTION_USB_ANLG_HEADSET_PLUG); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + intent.putExtra("state", state); + intent.putExtra("name", headsetName); + ActivityManagerNative.broadcastStickyIntent(intent, null); + } else if (headset == BIT_USB_HEADSET_DGTL) { + intent = new Intent(Intent.ACTION_USB_DGTL_HEADSET_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; + } + + intent.putExtra("state", state); + intent.putExtra("name", headsetName); + intent.putExtra("microphone", microphone); + + 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); + } + } + } + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + sendIntents(msg.arg1, msg.arg2, (String)msg.obj); + mWakeLock.release(); + } + }; +} |
