diff options
Diffstat (limited to 'android/src/org')
-rw-r--r-- | android/src/org/rockbox/RockboxActivity.java | 45 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxFramebuffer.java | 101 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxService.java | 45 |
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 | ||
24 | import java.nio.ByteBuffer; | 24 | import java.nio.ByteBuffer; |
25 | 25 | ||
26 | import org.rockbox.Helper.MediaButtonReceiver; | ||
27 | |||
28 | import android.content.Context; | 26 | import android.content.Context; |
29 | import android.graphics.Bitmap; | 27 | import android.graphics.Bitmap; |
30 | import android.graphics.Canvas; | 28 | import android.graphics.Canvas; |
@@ -33,45 +31,72 @@ import android.util.DisplayMetrics; | |||
33 | import android.util.Log; | 31 | import android.util.Log; |
34 | import android.view.KeyEvent; | 32 | import android.view.KeyEvent; |
35 | import android.view.MotionEvent; | 33 | import android.view.MotionEvent; |
36 | import android.view.View; | 34 | import android.view.SurfaceHolder; |
35 | import android.view.SurfaceView; | ||
37 | import android.view.ViewConfiguration; | 36 | import android.view.ViewConfiguration; |
38 | 37 | ||
39 | public class RockboxFramebuffer extends View | 38 | public 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; | |||
31 | import java.util.zip.ZipEntry; | 31 | import java.util.zip.ZipEntry; |
32 | import java.util.zip.ZipFile; | 32 | import java.util.zip.ZipFile; |
33 | 33 | ||
34 | import org.rockbox.Helper.MediaButtonReceiver; | ||
34 | import org.rockbox.Helper.RunForegroundManager; | 35 | import org.rockbox.Helper.RunForegroundManager; |
35 | 36 | ||
36 | import android.app.Activity; | 37 | import 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 | } |