summaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/src/org/rockbox/Helper/MediaButtonReceiver.java17
-rw-r--r--android/src/org/rockbox/RockboxActivity.java31
-rw-r--r--android/src/org/rockbox/RockboxFramebuffer.java2
-rw-r--r--android/src/org/rockbox/RockboxService.java113
4 files changed, 69 insertions, 94 deletions
diff --git a/android/src/org/rockbox/Helper/MediaButtonReceiver.java b/android/src/org/rockbox/Helper/MediaButtonReceiver.java
index 3749cec32a..a57bdd4831 100644
--- a/android/src/org/rockbox/Helper/MediaButtonReceiver.java
+++ b/android/src/org/rockbox/Helper/MediaButtonReceiver.java
@@ -22,9 +22,8 @@
package org.rockbox.Helper;
import java.lang.reflect.Method;
-
+import org.rockbox.RockboxFramebuffer;
import org.rockbox.RockboxService;
-
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -73,7 +72,12 @@ public class MediaButtonReceiver
/* helper class for the manifest */
public static class MediaReceiver extends BroadcastReceiver
- {
+ {
+ private void startService(Context c, Intent baseIntent)
+ {
+ baseIntent.setClass(c, RockboxService.class);
+ c.startService(baseIntent);
+ }
@Override
public void onReceive(Context context, Intent intent)
{
@@ -81,8 +85,11 @@ public class MediaButtonReceiver
{
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))
+ { /* pass the pressed key to Rockbox, starting it if needed */
+ RockboxService s = RockboxService.get_instance();
+ if (s == null || !s.isRockboxRunning())
+ startService(context, intent);
+ else if (RockboxFramebuffer.buttonHandler(key.getKeyCode(), false))
abortBroadcast();
}
}
diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java
index 90c687f35a..65c7f92bbe 100644
--- a/android/src/org/rockbox/RockboxActivity.java
+++ b/android/src/org/rockbox/RockboxActivity.java
@@ -29,16 +29,12 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class RockboxActivity extends Activity
{
- private RockboxService rbservice;
-
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
@@ -79,9 +75,7 @@ public class RockboxActivity extends Activity
loadingdialog.setProgress(resultData.getInt("value", 0));
break;
case RockboxService.RESULT_SERVICE_RUNNING:
- rbservice = RockboxService.get_instance();
setServiceActivity(true);
- attachFramebuffer();
break;
case RockboxService.RESULT_ERROR_OCCURED:
Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG);
@@ -89,38 +83,21 @@ public class RockboxActivity extends Activity
}
}
});
+ setContentView(new RockboxFramebuffer(this));
startService(intent);
}
private void setServiceActivity(boolean set)
{
- if (rbservice != null)
- rbservice.set_activity(set ? this : null);
- }
-
- private void attachFramebuffer()
- {
- View rbFramebuffer = null;
- try {
- rbFramebuffer = rbservice.get_fb();
- setContentView(rbFramebuffer);
- } catch (IllegalStateException e) {
- /* we are already using the View,
- * need to remove it and re-attach it */
- ViewGroup g = (ViewGroup) rbFramebuffer.getParent();
- g.removeView(rbFramebuffer);
- setContentView(rbFramebuffer);
- } catch (NullPointerException e) {
- return;
- }
- rbFramebuffer.requestFocus();
+ RockboxService s = RockboxService.get_instance();
+ if (s != null)
+ s.set_activity(set ? this : null);
}
public void onResume()
{
super.onResume();
setVisible(true);
- attachFramebuffer();
}
/* this is also called when the backlight goes off,
diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java
index 037fd2db85..a17bc90ab6 100644
--- a/android/src/org/rockbox/RockboxFramebuffer.java
+++ b/android/src/org/rockbox/RockboxFramebuffer.java
@@ -148,7 +148,7 @@ public class RockboxFramebuffer extends SurfaceView
}
private native void touchHandler(boolean down, int x, int y);
- private native static boolean buttonHandler(int keycode, boolean state);
+ public native static boolean buttonHandler(int keycode, boolean state);
public native void surfaceCreated(SurfaceHolder holder);
public native void surfaceDestroyed(SurfaceHolder holder);
diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java
index 43d122a8cc..4f0caa7704 100644
--- a/android/src/org/rockbox/RockboxService.java
+++ b/android/src/org/rockbox/RockboxService.java
@@ -59,8 +59,7 @@ public class RockboxService extends Service
private static RockboxService instance = null;
/* locals needed for the c code and rockbox state */
- private RockboxFramebuffer fb = null;
- private volatile boolean rockbox_running;
+ private static volatile boolean rockbox_running;
private Activity current_activity = null;
private IntentFilter itf;
private BroadcastReceiver batt_monitor;
@@ -69,11 +68,9 @@ public class RockboxService extends Service
@SuppressWarnings("unused")
private int battery_level;
private ResultReceiver resultReceiver;
- final private Object lock = new Object();
public static final int RESULT_INVOKING_MAIN = 0;
public static final int RESULT_LIB_LOAD_PROGRESS = 1;
- public static final int RESULT_FB_INITIALIZED = 2;
public static final int RESULT_SERVICE_RUNNING = 3;
public static final int RESULT_ERROR_OCCURED = 4;
public static final int RESULT_LIB_LOADED = 5;
@@ -88,14 +85,15 @@ public class RockboxService extends Service
public static RockboxService get_instance()
{
+ /* don't call the construtor here, the instances are managed by
+ * android, so we can't just create a new one */
return instance;
}
- public RockboxFramebuffer get_fb()
+ public boolean isRockboxRunning()
{
- return fb;
+ return rockbox_running;
}
-
public Activity get_activity()
{
return current_activity;
@@ -108,71 +106,48 @@ public class RockboxService extends Service
private void do_start(Intent intent)
{
LOG("Start Service");
-
if (intent != null && intent.hasExtra("callback"))
resultReceiver = (ResultReceiver) intent.getParcelableExtra("callback");
- /* Display a notification about us starting.
- * We put an icon in the status bar. */
- if (fg_runner == null)
- { /* needs to be initialized before main() runs */
- try {
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
if (!rockbox_running)
- {
- synchronized(lock)
- {
- startservice();
- while(true) {
- try {
- lock.wait();
- } catch (InterruptedException e) {
- continue;
- }
- break;
- }
- fb = new RockboxFramebuffer(this);
- if (resultReceiver != null)
- resultReceiver.send(RESULT_FB_INITIALIZED, null);
- }
- }
+ startservice();
if (resultReceiver != null)
resultReceiver.send(RESULT_LIB_LOADED, null);
+
if (intent != null && intent.getAction() != null)
{
- Log.d("RockboxService", intent.getAction());
- if (intent.getAction().equals("org.rockbox.PlayPause"))
- {
- if (fb != null)
- fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null);
+ if (!rockbox_running)
+ { /* give it a bit of time so we can register button presses
+ * sleeping longer doesn't work here, apparently Android
+ * surpresses long sleeps during intent handling */
+ try {
+ Thread.sleep(50);
+ }
+ catch (InterruptedException e) { }
}
- else if (intent.getAction().equals("org.rockbox.Prev"))
+
+ if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON))
{
- if (fb != null)
- fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PREVIOUS, null);
+ KeyEvent kev = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+ RockboxFramebuffer.buttonHandler(kev.getKeyCode(), kev.getAction() == KeyEvent.ACTION_DOWN);
}
+ else if (intent.getAction().equals("org.rockbox.PlayPause"))
+ RockboxFramebuffer.buttonHandler(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, false);
+ else if (intent.getAction().equals("org.rockbox.Prev"))
+ RockboxFramebuffer.buttonHandler(KeyEvent.KEYCODE_MEDIA_PREVIOUS, false);
else if (intent.getAction().equals("org.rockbox.Next"))
- {
- if (fb != null)
- fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_NEXT, null);
- }
+ RockboxFramebuffer.buttonHandler(KeyEvent.KEYCODE_MEDIA_NEXT, false);
else if (intent.getAction().equals("org.rockbox.Stop"))
- {
- if (fb != null)
- fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_STOP, null);
- }
+ RockboxFramebuffer.buttonHandler(KeyEvent.KEYCODE_MEDIA_STOP, false);
}
/* (Re-)attach the media button receiver, in case it has been lost */
mMediaButtonReceiver.register();
-
if (resultReceiver != null)
resultReceiver.send(RESULT_SERVICE_RUNNING, null);
+
+ rockbox_running = true;
}
private void LOG(CharSequence text)
@@ -195,16 +170,23 @@ public class RockboxService extends Service
return 1; /* old API compatibility: 1 == START_STICKY */
}
- private void startservice()
+ private void startservice()
{
- final int BUFFER = 8*1024;
+ final Object lock = new Object();
Thread rb = new Thread(new Runnable()
{
public void run()
{
+ final int BUFFER = 8*1024;
String rockboxDirPath = "/data/data/org.rockbox/app_rockbox/rockbox";
File rockboxDir = new File(rockboxDirPath);
+ /* load library before unzipping which may take a while */
+ synchronized (lock) {
+ System.loadLibrary("rockbox");
+ lock.notify();
+ }
+
/* 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
@@ -268,13 +250,7 @@ public class RockboxService extends Service
}
}
}
-
- synchronized (lock) {
- System.loadLibrary("rockbox");
- lock.notify();
- }
- rockbox_running = true;
if (resultReceiver != null)
resultReceiver.send(RESULT_INVOKING_MAIN, null);
@@ -283,7 +259,20 @@ public class RockboxService extends Service
}
}, "Rockbox thread");
rb.setDaemon(false);
- rb.start();
+ /* wait at least until the library is loaded */
+ synchronized (lock)
+ {
+ rb.start();
+ while(true)
+ {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ continue;
+ }
+ break;
+ }
+ }
}
private native void main();
@@ -352,5 +341,7 @@ public class RockboxService extends Service
mMediaButtonReceiver = null;
/* Make sure our notification is gone. */
stopForeground();
+ instance = null;
+ rockbox_running = false;
}
}