diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/HeadsetObserver.java | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/services/java/com/android/server/HeadsetObserver.java b/services/java/com/android/server/HeadsetObserver.java index 9b0a2d4..bee3108 100644 --- a/services/java/com/android/server/HeadsetObserver.java +++ b/services/java/com/android/server/HeadsetObserver.java @@ -41,10 +41,16 @@ class HeadsetObserver extends UEventObserver { 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 BIT_TTY = (1 << 2); + private static final int BIT_FM_HEADSET = (1 << 3); + private static final int BIT_FM_SPEAKER = (1 << 4); + private int mHeadsetState; + private int mPrevHeadsetState; private String mHeadsetName; - private boolean mAudioRouteNeedsUpdate; - private AudioManager mAudioManager; + private boolean mPendingIntent; private final Context mContext; private final WakeLock mWakeLock; // held while there is a pending route change @@ -76,6 +82,7 @@ class HeadsetObserver extends UEventObserver { String newName = mHeadsetName; int newState = mHeadsetState; + mPrevHeadsetState = mHeadsetState; try { FileReader file = new FileReader(HEADSET_STATE_PATH); int len = file.read(buffer, 0, 1024); @@ -91,20 +98,25 @@ class HeadsetObserver extends UEventObserver { Log.e(TAG, "" , e); } - mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); update(newName, newState); } private synchronized final void update(String newName, int newState) { if (newName != mHeadsetName || newState != mHeadsetState) { - boolean isUnplug = (newState == 0 && mHeadsetState == 1); + boolean isUnplug = false; + if ( (mHeadsetState & BIT_HEADSET) > 0 || (mHeadsetState & BIT_HEADSET_NO_MIC) > 0) { + if ((newState & BIT_HEADSET) == 0 && (newState & BIT_HEADSET_NO_MIC) == 0) + isUnplug = true; + } mHeadsetName = newName; + mPrevHeadsetState = mHeadsetState; mHeadsetState = newState; - mAudioRouteNeedsUpdate = true; - - sendIntent(isUnplug); + mPendingIntent = true; if (isUnplug) { + 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. @@ -113,12 +125,13 @@ class HeadsetObserver extends UEventObserver { mWakeLock.acquire(); mHandler.sendEmptyMessageDelayed(0, 1000); } else { - updateAudioRoute(); + sendIntent(); + mPendingIntent = false; } } } - private synchronized final void sendIntent(boolean isUnplug) { + private synchronized final void sendIntent() { // Pack up the values and broadcast them to everyone Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -128,24 +141,15 @@ class HeadsetObserver extends UEventObserver { // TODO: Should we require a permission? ActivityManagerNative.broadcastStickyIntent(intent, null); - - if (isUnplug) { - intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY); - mContext.sendBroadcast(intent); - } - } - - private synchronized final void updateAudioRoute() { - if (mAudioRouteNeedsUpdate) { - mAudioManager.setWiredHeadsetOn(mHeadsetState == 1); - mAudioRouteNeedsUpdate = false; - } } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { - updateAudioRoute(); + if (mPendingIntent) { + sendIntent(); + mPendingIntent = false; + } mWakeLock.release(); } }; |