Move media button registration into MediaButtonHandler; only register when media buttons are enabled

This commit is contained in:
Christopher Eby 2011-08-28 23:10:19 -05:00
parent fa63a36bbc
commit a4ea3089f6
3 changed files with 107 additions and 68 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
* Copyright (C) 2010, 2011 Christopher Eby <kreed@kreed.org>
*
* 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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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()