From a4ea3089f6eb2a8f365e389268ab18760c7c2226 Mon Sep 17 00:00:00 2001 From: Christopher Eby Date: Sun, 28 Aug 2011 23:10:19 -0500 Subject: [PATCH] Move media button registration into MediaButtonHandler; only register when media buttons are enabled --- src/org/kreed/vanilla/MediaButtonHandler.java | 109 ++++++++++++++---- src/org/kreed/vanilla/PlaybackActivity.java | 5 +- src/org/kreed/vanilla/PlaybackService.java | 61 +++------- 3 files changed, 107 insertions(+), 68 deletions(-) diff --git a/src/org/kreed/vanilla/MediaButtonHandler.java b/src/org/kreed/vanilla/MediaButtonHandler.java index d2b50815..5f8a4094 100644 --- a/src/org/kreed/vanilla/MediaButtonHandler.java +++ b/src/org/kreed/vanilla/MediaButtonHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Christopher Eby + * Copyright (C) 2010, 2011 Christopher Eby * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,13 +22,19 @@ package org.kreed.vanilla; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.media.AudioManager; import android.os.Handler; import android.os.Message; import android.preference.PreferenceManager; import android.telephony.TelephonyManager; +import android.util.Log; import android.view.KeyEvent; /** @@ -54,21 +60,30 @@ public class MediaButtonHandler implements Handler.Callback { * Whether the headset controls should be used. 1 for yes, 0 for no, -1 for * uninitialized. */ - private byte mUseControls = -1; + private static int mUseControls = -1; /** * Whether the phone is currently in a call. 1 for yes, 0 for no, -1 for * uninitialized. */ - private byte mInCall = -1; + private int mInCall = -1; + + private static AudioManager mAudioManager; + private static Method mRegisterMediaButtonEventReceiver; + private static Method mUnregisterMediaButtonEventReceiver; + public static ComponentName mButtonReceiver; /** * Retrieve the MediaButtonHandler singleton, creating it if necessary. + * Returns null if headset controls are not enabled. */ public static MediaButtonHandler getInstance() { - if (mInstance == null) - mInstance = new MediaButtonHandler(); - return mInstance; + if (useHeadsetControls()) { + if (mInstance == null) + mInstance = new MediaButtonHandler(); + return mInstance; + } + return null; } /** @@ -77,29 +92,44 @@ public class MediaButtonHandler implements Handler.Callback { private MediaButtonHandler() { mHandler = new Handler(this); + + Context context = ContextApplication.getContext(); + + mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); + mButtonReceiver = new ComponentName(context.getPackageName(), MediaButtonReceiver.class.getName()); + try { + mRegisterMediaButtonEventReceiver = AudioManager.class.getMethod("registerMediaButtonEventReceiver", ComponentName.class); + mUnregisterMediaButtonEventReceiver = AudioManager.class.getMethod("unregisterMediaButtonEventReceiver", ComponentName.class); + } catch (NoSuchMethodException nsme) { + // Older Android; just use receiver priority + } + } + + private static void loadPreference() + { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ContextApplication.getContext()); + mUseControls = settings.getBoolean("media_button", true) ? 1 : 0; + } + + public static void reloadPreference() + { + loadPreference(); + if (useHeadsetControls()) { + getInstance().registerMediaButton(); + } else { + unregisterMediaButton(); + } } /** * Return whether headset controls should be used, loading the preference * if necessary. */ - public boolean useHeadsetControls() - { - if (mUseControls == -1) { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ContextApplication.getContext()); - mUseControls = (byte)(settings.getBoolean("media_button", true) ? 1 : 0); - } - return mUseControls == 1; - } - - /** - * Set the cached value for the headset controls preference. - * - * @param value True if controls should be used, false otherwise. - */ - public void setUseHeadsetControls(boolean value) + public static boolean useHeadsetControls() { - mUseControls = (byte)(value ? 1 : 0); + if (mUseControls == -1) + loadPreference(); + return mUseControls == 1; } /** @@ -122,7 +152,7 @@ public class MediaButtonHandler implements Handler.Callback { */ public void setInCall(boolean value) { - mInCall = (byte)(value ? 1 : 0); + mInCall = value ? 1 : 0; } /** @@ -210,4 +240,37 @@ public class MediaButtonHandler implements Handler.Callback { return true; } + + /** + * Request focus on the media buttons from AudioManager. + */ + public void registerMediaButton() + { + assert(mUseControls == 1); + if (mRegisterMediaButtonEventReceiver != null) { + try { + mRegisterMediaButtonEventReceiver.invoke(mAudioManager, mButtonReceiver); + } catch (InvocationTargetException e) { + Log.w("VanillaMusic", e); + } catch (IllegalAccessException e) { + Log.w("VanillaMusic", e); + } + } + } + + /** + * Unregister the media buttons from AudioManager. + */ + public static void unregisterMediaButton() + { + if (mUnregisterMediaButtonEventReceiver != null) { + try { + mUnregisterMediaButtonEventReceiver.invoke(mAudioManager, mButtonReceiver); + } catch (InvocationTargetException e) { + Log.w("VanillaMusic", e); + } catch (IllegalAccessException e) { + Log.w("VanillaMusic", e); + } + } + } } diff --git a/src/org/kreed/vanilla/PlaybackActivity.java b/src/org/kreed/vanilla/PlaybackActivity.java index b318087b..78a56c84 100644 --- a/src/org/kreed/vanilla/PlaybackActivity.java +++ b/src/org/kreed/vanilla/PlaybackActivity.java @@ -85,7 +85,10 @@ public class PlaybackActivity extends Activity implements Handler.Callback, View if (ContextApplication.hasService()) { PlaybackService service = ContextApplication.getService(); service.userActionTriggered(); - service.registerMediaButton(); + + MediaButtonHandler buttons = MediaButtonHandler.getInstance(); + if (buttons != null) + buttons.setInCall(false); } } diff --git a/src/org/kreed/vanilla/PlaybackService.java b/src/org/kreed/vanilla/PlaybackService.java index 911a41dd..466b7810 100644 --- a/src/org/kreed/vanilla/PlaybackService.java +++ b/src/org/kreed/vanilla/PlaybackService.java @@ -32,7 +32,6 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.Service; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -167,7 +166,6 @@ public final class PlaybackService extends Service implements Handler.Callback, private PowerManager.WakeLock mWakeLock; private Notification mNotification; private SharedPreferences mSettings; - private AudioManager mAudioManager; private NotificationManager mNotificationManager; SongTimeline mTimeline; @@ -176,7 +174,6 @@ public final class PlaybackService extends Service implements Handler.Callback, boolean mPlayingBeforeCall; private int mPendingSeek; public Receiver mReceiver; - public ComponentName mButtonReceiver; public InCallListener mCallListener; private boolean mLoaded; /** @@ -191,8 +188,6 @@ public final class PlaybackService extends Service implements Handler.Callback, private static Method mStartForeground; private static Method mStopForeground; - private static Method mRegisterMediaButtonEventReceiver; - private static Method mUnregisterMediaButtonEventReceiver; static { try { @@ -200,11 +195,6 @@ public final class PlaybackService extends Service implements Handler.Callback, mStopForeground = Service.class.getMethod("stopForeground", boolean.class); } catch (NoSuchMethodException e) { } - try { - mRegisterMediaButtonEventReceiver = AudioManager.class.getMethod("registerMediaButtonEventReceiver", ComponentName.class); - mUnregisterMediaButtonEventReceiver = AudioManager.class.getMethod("unregisterMediaButtonEventReceiver", ComponentName.class); - } catch (NoSuchMethodException nsme) { - } } @Override @@ -223,9 +213,6 @@ public final class PlaybackService extends Service implements Handler.Callback, ContextApplication.setService(this); - mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); - mButtonReceiver = new ComponentName(getPackageName(), MediaButtonReceiver.class.getName()); - mLooper = thread.getLooper(); mHandler = new Handler(mLooper, this); mHandler.sendEmptyMessage(CREATE); @@ -241,22 +228,6 @@ public final class PlaybackService extends Service implements Handler.Callback, Toast.makeText(this, R.string.starting, Toast.LENGTH_SHORT).show(); } - /** - * Request focus on the media buttons from AudioManager. - */ - public void registerMediaButton() - { - if (mRegisterMediaButtonEventReceiver != null) { - try { - mRegisterMediaButtonEventReceiver.invoke(mAudioManager, mButtonReceiver); - } catch (InvocationTargetException e) { - Log.w("VanillaMusic", e); - } catch (IllegalAccessException e) { - Log.w("VanillaMusic", e); - } - } - } - @Override public void onStart(Intent intent, int flags) { @@ -302,7 +273,9 @@ public final class PlaybackService extends Service implements Handler.Callback, } userActionTriggered(); - registerMediaButton(); + MediaButtonHandler buttons = MediaButtonHandler.getInstance(); + if (buttons != null) + buttons.registerMediaButton(); } } @@ -323,15 +296,7 @@ public final class PlaybackService extends Service implements Handler.Callback, mLooper.quit(); - if (mUnregisterMediaButtonEventReceiver != null) { - try { - mUnregisterMediaButtonEventReceiver.invoke(mAudioManager, mButtonReceiver); - } catch (InvocationTargetException e) { - Log.w("VanillaMusic", e); - } catch (IllegalAccessException e) { - Log.w("VanillaMusic", e); - } - } + MediaButtonHandler.unregisterMediaButton(); try { unregisterReceiver(mReceiver); @@ -445,7 +410,7 @@ public final class PlaybackService extends Service implements Handler.Callback, } } } else if ("media_button".equals(key)) { - MediaButtonHandler.getInstance().setUseHeadsetControls(settings.getBoolean("media_button", true)); + MediaButtonHandler.reloadPreference(); } else if ("use_idle_timeout".equals(key) || "idle_timeout".equals(key)) { mIdleTimeout = settings.getBoolean("use_idle_timeout", false) ? settings.getInt("idle_timeout", 3600) : 0; userActionTriggered(); @@ -751,8 +716,11 @@ public final class PlaybackService extends Service implements Handler.Callback, { switch (state) { case TelephonyManager.CALL_STATE_RINGING: - case TelephonyManager.CALL_STATE_OFFHOOK: - MediaButtonHandler.getInstance().setInCall(true); + case TelephonyManager.CALL_STATE_OFFHOOK: { + MediaButtonHandler buttons = MediaButtonHandler.getInstance(); + if (buttons != null) + buttons.setInCall(true); + if (!mPlayingBeforeCall) { synchronized (mStateLock) { if (mPlayingBeforeCall = (mState & FLAG_PLAYING) != 0) @@ -760,8 +728,12 @@ public final class PlaybackService extends Service implements Handler.Callback, } } break; - case TelephonyManager.CALL_STATE_IDLE: - MediaButtonHandler.getInstance().setInCall(false); + } + case TelephonyManager.CALL_STATE_IDLE: { + MediaButtonHandler buttons = MediaButtonHandler.getInstance(); + if (buttons != null) + buttons.setInCall(false); + if (mPlayingBeforeCall) { setFlag(FLAG_PLAYING); mPlayingBeforeCall = false; @@ -769,6 +741,7 @@ public final class PlaybackService extends Service implements Handler.Callback, break; } } + } }; public void onMediaChange()