summaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-10-31 15:32:57 +0000
committerThomas Martitz <kugel@rockbox.org>2010-10-31 15:32:57 +0000
commit49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc (patch)
treeb185e604dcea64865389f5b149e754ba8ffd3f75 /android
parentdbe2ac1ec6f4ed88f267d2a4df024b6dc42a87ff (diff)
downloadrockbox-49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc.tar.gz
rockbox-49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc.tar.bz2
rockbox-49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc.zip
Add support multimedia keys/buttons to the core, and adapt Rockbox on android for it (multimedia buttons are found on wired headsets and the lock screen in cyanogenmod).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28421 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'android')
-rw-r--r--android/AndroidManifest.xml11
-rw-r--r--android/src/org/rockbox/Helper/MediaButtonReceiver.java164
-rw-r--r--android/src/org/rockbox/RockboxFramebuffer.java11
-rw-r--r--android/src/org/rockbox/RockboxService.java2
4 files changed, 188 insertions, 0 deletions
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index c52d83fd2c..06a13ddb40 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -16,10 +16,21 @@
</intent-filter>
</activity>
<service android:name=".RockboxService"/>
+ <receiver android:name=".Helper.MediaButtonReceiver$MediaReceiver"
+ android:enabled="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MEDIA_BUTTON" />
+ </intent-filter>
+ </receiver>
<activity android:name="KeyboardActivity"></activity>
<activity android:name="YesnoActivity"></activity>
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
+
+
+
+
</manifest>
diff --git a/android/src/org/rockbox/Helper/MediaButtonReceiver.java b/android/src/org/rockbox/Helper/MediaButtonReceiver.java
new file mode 100644
index 0000000000..3749cec32a
--- /dev/null
+++ b/android/src/org/rockbox/Helper/MediaButtonReceiver.java
@@ -0,0 +1,164 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+package org.rockbox.Helper;
+
+import java.lang.reflect.Method;
+
+import org.rockbox.RockboxService;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.view.KeyEvent;
+
+public class MediaButtonReceiver
+{
+ /* A note on the API being used. 2.2 introduces a new and sane API
+ * for handling multimedia button presses
+ * http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html
+ *
+ * the old API is flawed. It doesn't have management for
+ * concurrent media apps
+ *
+ * if multiple media apps are running
+ * probably all of them want to respond to media keys
+ *
+ * it's not clear which app wins, it depends on the
+ * priority set for the IntentFilter (see below)
+ *
+ * so this all might or might not work on < 2.2 */
+
+ IMultiMediaReceiver api;
+
+ public MediaButtonReceiver(Context c)
+ {
+ try {
+ api = new NewApi(c);
+ } catch (Exception e) {
+ api = new OldApi(c);
+ }
+ }
+
+ public void register()
+ {
+ api.register();
+ }
+
+ public void unregister()
+ {
+ api.register();
+ }
+
+ /* helper class for the manifest */
+ public static class MediaReceiver extends BroadcastReceiver
+ {
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()))
+ {
+ KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+ if (key.getAction() == KeyEvent.ACTION_UP)
+ { /* pass the pressed key to Rockbox */
+ if (RockboxService.get_instance().get_fb().dispatchKeyEvent(key))
+ abortBroadcast();
+ }
+ }
+ }
+ }
+
+ private interface IMultiMediaReceiver
+ {
+ void register();
+ void unregister();
+ }
+
+ private static class NewApi implements IMultiMediaReceiver
+ {
+ private Method register_method;
+ private Method unregister_method;
+ private AudioManager audio_manager;
+ private ComponentName receiver_name;
+ /* the constructor gets the methods through reflection so that
+ * this compiles on pre-2.2 devices */
+ NewApi(Context c) throws SecurityException, NoSuchMethodException
+ {
+ register_method = AudioManager.class.getMethod(
+ "registerMediaButtonEventReceiver",
+ new Class[] { ComponentName.class } );
+ unregister_method = AudioManager.class.getMethod(
+ "unregisterMediaButtonEventReceiver",
+ new Class[] { ComponentName.class } );
+
+ audio_manager = (AudioManager)c.getSystemService(Context.AUDIO_SERVICE);
+ receiver_name = new ComponentName(c, MediaReceiver.class);
+ }
+ public void register()
+ {
+ try {
+ register_method.invoke(audio_manager, receiver_name);
+ } catch (Exception e) {
+ // Nothing
+ e.printStackTrace();
+ }
+ }
+
+ public void unregister()
+ {
+ try
+ {
+ unregister_method.invoke(audio_manager, receiver_name);
+ } catch (Exception e) {
+ // Nothing
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ private static class OldApi implements IMultiMediaReceiver
+ {
+ private static final IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
+ private MediaReceiver receiver;
+ private Context context;
+ OldApi(Context c)
+ {
+ filter.setPriority(1); /* 1 higher than the built-in media player */
+ receiver = new MediaReceiver();
+ context = c;
+ }
+
+ public void register()
+ {
+ context.registerReceiver(receiver, filter);
+ }
+
+ public void unregister()
+ {
+ context.unregisterReceiver(receiver);
+ }
+
+ }
+}
diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java
index 0daeffe265..84974d627a 100644
--- a/android/src/org/rockbox/RockboxFramebuffer.java
+++ b/android/src/org/rockbox/RockboxFramebuffer.java
@@ -23,6 +23,8 @@ package org.rockbox;
import java.nio.ByteBuffer;
+import org.rockbox.Helper.MediaButtonReceiver;
+
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -35,6 +37,7 @@ public class RockboxFramebuffer extends View
{
private Bitmap btm;
private ByteBuffer native_buf;
+ private MediaButtonReceiver media_monitor;
public RockboxFramebuffer(Context c, int lcd_width,
int lcd_height, ByteBuffer native_fb)
@@ -47,6 +50,8 @@ public class RockboxFramebuffer extends View
btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565);
native_buf = native_fb;
requestFocus();
+ media_monitor = new MediaButtonReceiver(c);
+ media_monitor.register();
/* the service needs to know the about us */
((RockboxService)c).set_fb(this);
}
@@ -122,6 +127,12 @@ public class RockboxFramebuffer extends View
set_lcd_active(1);
}
+ public void destroy()
+ {
+ suspend();
+ media_monitor.unregister();
+ }
+
public native void set_lcd_active(int active);
public native void touchHandler(boolean down, int x, int y);
public native boolean buttonHandler(int keycode, boolean state);
diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java
index b841bc5d7f..8989271b9f 100644
--- a/android/src/org/rockbox/RockboxService.java
+++ b/android/src/org/rockbox/RockboxService.java
@@ -139,6 +139,7 @@ public class RockboxService extends Service
{
public void run()
{
+ LOG("main");
/* the following block unzips libmisc.so, which contains the files
* we ship, such as themes. It's needed to put it into a .so file
* because there's no other way to ship files and have access
@@ -276,6 +277,7 @@ public class RockboxService extends Service
public void onDestroy()
{
super.onDestroy();
+ fb.destroy();
/* Make sure our notification is gone. */
stopForeground();
}