summaryrefslogtreecommitdiff
path: root/android/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'android/src/org')
-rw-r--r--android/src/org/rockbox/RockboxActivity.java45
-rw-r--r--android/src/org/rockbox/RockboxFramebuffer.java101
-rw-r--r--android/src/org/rockbox/RockboxService.java45
3 files changed, 94 insertions, 97 deletions
diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java
index 76535687f9..f3f0d2151c 100644
--- a/android/src/org/rockbox/RockboxActivity.java
+++ b/android/src/org/rockbox/RockboxActivity.java
@@ -66,10 +66,9 @@ public class RockboxActivity extends Activity
66 protected void onReceiveResult(final int resultCode, final Bundle resultData) 66 protected void onReceiveResult(final int resultCode, final Bundle resultData)
67 { 67 {
68 switch (resultCode) { 68 switch (resultCode) {
69 case RockboxService.RESULT_LIB_LOADED: 69 case RockboxService.RESULT_INVOKING_MAIN:
70 rbservice = RockboxService.get_instance();
71 if (loadingdialog != null) 70 if (loadingdialog != null)
72 loadingdialog.setIndeterminate(true); 71 loadingdialog.dismiss();
73 break; 72 break;
74 case RockboxService.RESULT_LIB_LOAD_PROGRESS: 73 case RockboxService.RESULT_LIB_LOAD_PROGRESS:
75 if (loadingdialog == null) 74 if (loadingdialog == null)
@@ -79,10 +78,10 @@ public class RockboxActivity extends Activity
79 loadingdialog.setMax(resultData.getInt("max", 100)); 78 loadingdialog.setMax(resultData.getInt("max", 100));
80 loadingdialog.setProgress(resultData.getInt("value", 0)); 79 loadingdialog.setProgress(resultData.getInt("value", 0));
81 break; 80 break;
82 case RockboxService.RESULT_FB_INITIALIZED: 81 case RockboxService.RESULT_SERVICE_RUNNING:
82 rbservice = RockboxService.get_instance();
83 setServiceActivity(true);
83 attachFramebuffer(); 84 attachFramebuffer();
84 if (loadingdialog != null)
85 loadingdialog.dismiss();
86 break; 85 break;
87 case RockboxService.RESULT_ERROR_OCCURED: 86 case RockboxService.RESULT_ERROR_OCCURED:
88 Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG); 87 Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG);
@@ -93,17 +92,17 @@ public class RockboxActivity extends Activity
93 startService(intent); 92 startService(intent);
94 } 93 }
95 94
96 private boolean isRockboxRunning() 95 private void setServiceActivity(boolean set)
97 { 96 {
98 if (rbservice == null) 97 if (rbservice != null)
99 rbservice = RockboxService.get_instance(); 98 rbservice.set_activity(this);
100 return (rbservice!= null && rbservice.isRockboxRunning() == true);
101 } 99 }
102 100
103 private void attachFramebuffer() 101 private void attachFramebuffer()
104 { 102 {
105 View rbFramebuffer = rbservice.get_fb(); 103 View rbFramebuffer = null;
106 try { 104 try {
105 rbFramebuffer = rbservice.get_fb();
107 setContentView(rbFramebuffer); 106 setContentView(rbFramebuffer);
108 } catch (IllegalStateException e) { 107 } catch (IllegalStateException e) {
109 /* we are already using the View, 108 /* we are already using the View,
@@ -111,17 +110,17 @@ public class RockboxActivity extends Activity
111 ViewGroup g = (ViewGroup) rbFramebuffer.getParent(); 110 ViewGroup g = (ViewGroup) rbFramebuffer.getParent();
112 g.removeView(rbFramebuffer); 111 g.removeView(rbFramebuffer);
113 setContentView(rbFramebuffer); 112 setContentView(rbFramebuffer);
114 } finally { 113 } catch (NullPointerException e) {
115 rbFramebuffer.requestFocus(); 114 return;
116 rbservice.set_activity(this);
117 } 115 }
116 rbFramebuffer.requestFocus();
118 } 117 }
119 118
120 public void onResume() 119 public void onResume()
121 { 120 {
122 super.onResume(); 121 super.onResume();
123 if (isRockboxRunning()) 122 setVisible(true);
124 attachFramebuffer(); 123 attachFramebuffer();
125 } 124 }
126 125
127 /* this is also called when the backlight goes off, 126 /* this is also called when the backlight goes off,
@@ -131,27 +130,23 @@ public class RockboxActivity extends Activity
131 protected void onPause() 130 protected void onPause()
132 { 131 {
133 super.onPause(); 132 super.onPause();
134 if (rbservice != null) 133 /* this will cause the framebuffer's Surface to be destroyed, enabling
135 { 134 * us to disable drawing */
136 rbservice.set_activity(null); 135 setVisible(false);
137 rbservice.get_fb().dispatchWindowVisibilityChanged(View.INVISIBLE);
138 }
139 } 136 }
140 137
141 @Override 138 @Override
142 protected void onStop() 139 protected void onStop()
143 { 140 {
144 super.onStop(); 141 super.onStop();
145 if (rbservice != null) 142 setServiceActivity(false);
146 rbservice.set_activity(null);
147 } 143 }
148 144
149 @Override 145 @Override
150 protected void onDestroy() 146 protected void onDestroy()
151 { 147 {
152 super.onDestroy(); 148 super.onDestroy();
153 if (rbservice != null) 149 setServiceActivity(false);
154 rbservice.set_activity(null);
155 } 150 }
156 151
157 private void LOG(CharSequence text) 152 private void LOG(CharSequence text)
diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java
index 05d2b11184..037fd2db85 100644
--- a/android/src/org/rockbox/RockboxFramebuffer.java
+++ b/android/src/org/rockbox/RockboxFramebuffer.java
@@ -23,8 +23,6 @@ package org.rockbox;
23 23
24import java.nio.ByteBuffer; 24import java.nio.ByteBuffer;
25 25
26import org.rockbox.Helper.MediaButtonReceiver;
27
28import android.content.Context; 26import android.content.Context;
29import android.graphics.Bitmap; 27import android.graphics.Bitmap;
30import android.graphics.Canvas; 28import android.graphics.Canvas;
@@ -33,45 +31,72 @@ import android.util.DisplayMetrics;
33import android.util.Log; 31import android.util.Log;
34import android.view.KeyEvent; 32import android.view.KeyEvent;
35import android.view.MotionEvent; 33import android.view.MotionEvent;
36import android.view.View; 34import android.view.SurfaceHolder;
35import android.view.SurfaceView;
37import android.view.ViewConfiguration; 36import android.view.ViewConfiguration;
38 37
39public class RockboxFramebuffer extends View 38public class RockboxFramebuffer extends SurfaceView
39 implements SurfaceHolder.Callback
40{ 40{
41 private Bitmap btm;
42 private Rect rect;
43 private ByteBuffer native_buf;
44 private MediaButtonReceiver media_monitor;
45 private final DisplayMetrics metrics; 41 private final DisplayMetrics metrics;
46 private final ViewConfiguration view_config; 42 private final ViewConfiguration view_config;
43 private ByteBuffer native_buf;
44 private Bitmap btm;
47 45
48 public RockboxFramebuffer(Context c, int lcd_width, 46 /* first stage init; needs to run from a thread that has a Looper
49 int lcd_height, ByteBuffer native_fb) 47 * setup stuff that needs a Context */
48 public RockboxFramebuffer(Context c)
50 { 49 {
51 super(c); 50 super(c);
51
52 metrics = c.getResources().getDisplayMetrics();
53 view_config = ViewConfiguration.get(c);
54 getHolder().addCallback(this);
52 /* Needed so we can catch KeyEvents */ 55 /* Needed so we can catch KeyEvents */
53 setFocusable(true); 56 setFocusable(true);
54 setFocusableInTouchMode(true); 57 setFocusableInTouchMode(true);
55 setClickable(true); 58 setClickable(true);
59 /* don't draw until native is ready (2nd stage) */
60 setEnabled(false);
61 }
62
63 /* second stage init; called from Rockbox with information about the
64 * display framebuffer */
65 @SuppressWarnings("unused")
66 private void java_lcd_init(int lcd_width, int lcd_height, ByteBuffer native_fb)
67 {
56 btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565); 68 btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565);
57 rect = new Rect();
58 native_buf = native_fb; 69 native_buf = native_fb;
59 media_monitor = new MediaButtonReceiver(c); 70 setEnabled(true);
60 media_monitor.register();
61 /* the service needs to know the about us */
62 ((RockboxService)c).set_fb(this);
63
64 metrics = c.getResources().getDisplayMetrics();
65 view_config = ViewConfiguration.get(c);
66 } 71 }
67 72
68 public void onDraw(Canvas c) 73 @SuppressWarnings("unused")
74 private void java_lcd_update()
75 {
76 SurfaceHolder holder = getHolder();
77 Canvas c = holder.lockCanvas(null);
78 btm.copyPixelsFromBuffer(native_buf);
79 synchronized (holder)
80 { /* draw */
81 c.drawBitmap(btm, 0.0f, 0.0f, null);
82 }
83 holder.unlockCanvasAndPost(c);
84 }
85
86 @SuppressWarnings("unused")
87 private void java_lcd_update_rect(int x, int y, int width, int height)
69 { 88 {
70 /* can't copy a partial buffer :( */ 89 SurfaceHolder holder = getHolder();
90 Rect dirty = new Rect(x, y, x+width, y+height);
91 Canvas c = holder.lockCanvas(dirty);
92 /* can't copy a partial buffer,
93 * but it doesn't make a noticeable difference anyway */
71 btm.copyPixelsFromBuffer(native_buf); 94 btm.copyPixelsFromBuffer(native_buf);
72 c.getClipBounds(rect); 95 synchronized (holder)
73 c.drawBitmap(btm, rect, rect, null); 96 { /* draw */
74 post_update_done(); 97 c.drawBitmap(btm, dirty, dirty, null);
98 }
99 holder.unlockCanvasAndPost(c);
75 } 100 }
76 101
77 @SuppressWarnings("unused") 102 @SuppressWarnings("unused")
@@ -109,28 +134,6 @@ public class RockboxFramebuffer extends View
109 { 134 {
110 return buttonHandler(keyCode, false); 135 return buttonHandler(keyCode, false);
111 } 136 }
112
113 public void destroy()
114 {
115 set_lcd_active(0);
116 media_monitor.unregister();
117 }
118
119 @Override
120 protected void onWindowVisibilityChanged(int visibility)
121 {
122 super.onWindowVisibilityChanged(visibility);
123
124 switch (visibility) {
125 case VISIBLE:
126 set_lcd_active(1);
127 break;
128 case GONE:
129 case INVISIBLE:
130 set_lcd_active(0);
131 break;
132 }
133 }
134 137
135 @SuppressWarnings("unused") 138 @SuppressWarnings("unused")
136 private int getDpi() 139 private int getDpi()
@@ -144,8 +147,12 @@ public class RockboxFramebuffer extends View
144 return view_config.getScaledTouchSlop(); 147 return view_config.getScaledTouchSlop();
145 } 148 }
146 149
147 private native void post_update_done();
148 private native void set_lcd_active(int active);
149 private native void touchHandler(boolean down, int x, int y); 150 private native void touchHandler(boolean down, int x, int y);
150 private native static boolean buttonHandler(int keycode, boolean state); 151 private native static boolean buttonHandler(int keycode, boolean state);
152
153 public native void surfaceCreated(SurfaceHolder holder);
154 public native void surfaceDestroyed(SurfaceHolder holder);
155 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
156 {
157 }
151} 158}
diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java
index de90999783..4f5df62280 100644
--- a/android/src/org/rockbox/RockboxService.java
+++ b/android/src/org/rockbox/RockboxService.java
@@ -31,6 +31,7 @@ import java.util.TimerTask;
31import java.util.zip.ZipEntry; 31import java.util.zip.ZipEntry;
32import java.util.zip.ZipFile; 32import java.util.zip.ZipFile;
33 33
34import org.rockbox.Helper.MediaButtonReceiver;
34import org.rockbox.Helper.RunForegroundManager; 35import org.rockbox.Helper.RunForegroundManager;
35 36
36import android.app.Activity; 37import android.app.Activity;
@@ -59,20 +60,21 @@ public class RockboxService extends Service
59 60
60 /* locals needed for the c code and rockbox state */ 61 /* locals needed for the c code and rockbox state */
61 private RockboxFramebuffer fb = null; 62 private RockboxFramebuffer fb = null;
62 private boolean mRockboxRunning = false; 63 private volatile boolean rockbox_running;
63 private volatile boolean rbLibLoaded;
64 private Activity current_activity = null; 64 private Activity current_activity = null;
65 private IntentFilter itf; 65 private IntentFilter itf;
66 private BroadcastReceiver batt_monitor; 66 private BroadcastReceiver batt_monitor;
67 private RunForegroundManager fg_runner; 67 private RunForegroundManager fg_runner;
68 private MediaButtonReceiver mMediaButtonReceiver;
68 @SuppressWarnings("unused") 69 @SuppressWarnings("unused")
69 private int battery_level; 70 private int battery_level;
70 private ResultReceiver resultReceiver; 71 private ResultReceiver resultReceiver;
71 72
72 public static final int RESULT_LIB_LOADED = 0; 73 public static final int RESULT_INVOKING_MAIN = 0;
73 public static final int RESULT_LIB_LOAD_PROGRESS = 1; 74 public static final int RESULT_LIB_LOAD_PROGRESS = 1;
74 public static final int RESULT_FB_INITIALIZED = 2; 75 public static final int RESULT_FB_INITIALIZED = 2;
75 public static final int RESULT_ERROR_OCCURED = 3; 76 public static final int RESULT_SERVICE_RUNNING = 3;
77 public static final int RESULT_ERROR_OCCURED = 4;
76 78
77 @Override 79 @Override
78 public void onCreate() 80 public void onCreate()
@@ -89,14 +91,6 @@ public class RockboxService extends Service
89 { 91 {
90 return fb; 92 return fb;
91 } 93 }
92 /* framebuffer is initialised by the native code(!) so this is needed */
93 public void set_fb(RockboxFramebuffer newfb)
94 {
95 fb = newfb;
96 mRockboxRunning = true;
97 if (resultReceiver != null)
98 resultReceiver.send(RESULT_FB_INITIALIZED, null);
99 }
100 94
101 public Activity get_activity() 95 public Activity get_activity()
102 { 96 {
@@ -113,7 +107,7 @@ public class RockboxService extends Service
113 107
114 if (intent != null && intent.hasExtra("callback")) 108 if (intent != null && intent.hasExtra("callback"))
115 resultReceiver = (ResultReceiver) intent.getParcelableExtra("callback"); 109 resultReceiver = (ResultReceiver) intent.getParcelableExtra("callback");
116 if (!rbLibLoaded) 110 if (!rockbox_running)
117 startservice(); 111 startservice();
118 112
119 if (intent != null && intent.getAction() != null) 113 if (intent != null && intent.getAction() != null)
@@ -151,6 +145,8 @@ public class RockboxService extends Service
151 e.printStackTrace(); 145 e.printStackTrace();
152 } 146 }
153 } 147 }
148 if (resultReceiver != null)
149 resultReceiver.send(RESULT_SERVICE_RUNNING, null);
154 } 150 }
155 151
156 private void LOG(CharSequence text) 152 private void LOG(CharSequence text)
@@ -176,6 +172,11 @@ public class RockboxService extends Service
176 private void startservice() 172 private void startservice()
177 { 173 {
178 final int BUFFER = 8*1024; 174 final int BUFFER = 8*1024;
175 fb = new RockboxFramebuffer(this);
176 if (resultReceiver != null)
177 resultReceiver.send(RESULT_FB_INITIALIZED, null);
178 mMediaButtonReceiver = new MediaButtonReceiver(this);
179 mMediaButtonReceiver.register();
179 Thread rb = new Thread(new Runnable() 180 Thread rb = new Thread(new Runnable()
180 { 181 {
181 public void run() 182 public void run()
@@ -247,10 +248,11 @@ public class RockboxService extends Service
247 } 248 }
248 } 249 }
249 250
250 System.loadLibrary("rockbox"); 251 System.loadLibrary("rockbox");
251 rbLibLoaded = true; 252
253 rockbox_running = true;
252 if (resultReceiver != null) 254 if (resultReceiver != null)
253 resultReceiver.send(RESULT_LIB_LOADED, null); 255 resultReceiver.send(RESULT_INVOKING_MAIN, null);
254 256
255 main(); 257 main();
256 throw new IllegalStateException("native main() returned!"); 258 throw new IllegalStateException("native main() returned!");
@@ -259,15 +261,8 @@ public class RockboxService extends Service
259 rb.setDaemon(false); 261 rb.setDaemon(false);
260 rb.start(); 262 rb.start();
261 } 263 }
264
262 private native void main(); 265 private native void main();
263
264 /* returns true once rockbox is up and running.
265 * This is considered done once the framebuffer is initialised
266 */
267 public boolean isRockboxRunning()
268 {
269 return mRockboxRunning;
270 }
271 266
272 @Override 267 @Override
273 public IBinder onBind(Intent intent) 268 public IBinder onBind(Intent intent)
@@ -329,7 +324,7 @@ public class RockboxService extends Service
329 public void onDestroy() 324 public void onDestroy()
330 { 325 {
331 super.onDestroy(); 326 super.onDestroy();
332 fb.destroy(); 327 mMediaButtonReceiver.unregister();
333 /* Make sure our notification is gone. */ 328 /* Make sure our notification is gone. */
334 stopForeground(); 329 stopForeground();
335 } 330 }