Android: Rework RunForegroundManager (again)
[maemo-rb.git] / android / src / org / rockbox / Helper / MediaButtonReceiver.java
blobe74ec5c8c22cdec93c7d646d523d75891a48b547
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Thomas Martitz
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 package org.rockbox.Helper;
24 import org.rockbox.RockboxFramebuffer;
25 import org.rockbox.RockboxService;
26 import android.content.BroadcastReceiver;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.media.AudioManager;
32 import android.view.KeyEvent;
34 public class MediaButtonReceiver
36 /* A note on the API being used. 2.2 introduces a new and sane API
37 * for handling multimedia button presses
38 * http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html
40 * the old API is flawed. It doesn't have management for
41 * concurrent media apps
43 * if multiple media apps are running
44 * probably all of them want to respond to media keys
46 * it's not clear which app wins, it depends on the
47 * priority set for the IntentFilter (see below)
49 * so this all might or might not work on < 2.2 */
51 IMultiMediaReceiver api;
53 public MediaButtonReceiver(Context c)
55 try {
56 api = new NewApi(c);
57 } catch (Throwable t) {
58 /* Throwable includes Exception and the expected
59 * NoClassDefFoundError */
60 api = new OldApi(c);
61 Logger.i("MediaButtonReceiver: Falling back to compatibility API");
65 public void register()
67 api.register();
70 public void unregister()
72 api.unregister();
75 /* helper class for the manifest */
76 public static class MediaReceiver extends BroadcastReceiver
78 private void startService(Context c, Intent baseIntent)
80 baseIntent.setClass(c, RockboxService.class);
81 c.startService(baseIntent);
83 @Override
84 public void onReceive(Context context, Intent intent)
86 if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()))
88 KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
89 if (key.getAction() == KeyEvent.ACTION_UP)
90 { /* pass the pressed key to Rockbox, starting it if needed */
91 RockboxService s = RockboxService.get_instance();
92 if (s == null || !s.isRockboxRunning())
93 startService(context, intent);
94 else if (RockboxFramebuffer.buttonHandler(key.getKeyCode(), false))
95 abortBroadcast();
101 private interface IMultiMediaReceiver
103 void register();
104 void unregister();
107 private static class NewApi
108 implements IMultiMediaReceiver, AudioManager.OnAudioFocusChangeListener
110 private AudioManager audio_manager;
111 private ComponentName receiver_name;
112 private boolean running = false;
114 NewApi(Context c)
116 audio_manager = (AudioManager)c.getSystemService(Context.AUDIO_SERVICE);
117 receiver_name = new ComponentName(c, MediaReceiver.class);
120 public void register()
122 try {
123 audio_manager.registerMediaButtonEventReceiver(receiver_name);
124 audio_manager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
125 running = true;
126 } catch (Exception e) {
127 // Nothing
128 e.printStackTrace();
132 public void unregister()
136 audio_manager.unregisterMediaButtonEventReceiver(receiver_name);
137 audio_manager.abandonAudioFocus(this);
138 running = false;
139 } catch (Exception e) {
140 // Nothing
141 e.printStackTrace();
145 public void onAudioFocusChange(int focusChange)
147 Logger.d("Audio focus" + ((focusChange>0)?"gained":"lost")+
148 ": "+ focusChange);
149 if (running)
150 { /* Play nice and stop for the the other app */
151 if (focusChange == AudioManager.AUDIOFOCUS_LOSS)
152 RockboxFramebuffer.buttonHandler(KeyEvent.KEYCODE_MEDIA_STOP, false);
158 private static class OldApi implements IMultiMediaReceiver
160 private static final IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
161 private MediaReceiver receiver;
162 private Context context;
163 OldApi(Context c)
165 filter.setPriority(1); /* 1 higher than the built-in media player */
166 receiver = new MediaReceiver();
167 context = c;
170 public void register()
172 context.registerReceiver(receiver, filter);
175 public void unregister()
177 context.unregisterReceiver(receiver);