From 7ccc78d08417c90ed373c01262fcdfed6aec03dc Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Fri, 5 Nov 2010 23:39:56 +0000 Subject: Android port: replace waiting hack in AndroidActivity with a ResultReceiver, added bonus is unzip progress feedback git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28506 a1c6a512-1295-4272-9138-f99709370657 --- android/src/org/rockbox/RockboxActivity.java | 85 +++++++++++----------------- android/src/org/rockbox/RockboxService.java | 28 +++++++-- 2 files changed, 58 insertions(+), 55 deletions(-) (limited to 'android') diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java index 2e13a034c7..15576f4adb 100644 --- a/android/src/org/rockbox/RockboxActivity.java +++ b/android/src/org/rockbox/RockboxActivity.java @@ -26,6 +26,7 @@ import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; +import android.os.ResultReceiver; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -36,79 +37,61 @@ public class RockboxActivity extends Activity { private ProgressDialog loadingdialog; private RockboxService rbservice; + /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN - ,WindowManager.LayoutParams.FLAG_FULLSCREEN); - final Activity thisActivity = this; - final Intent intent = new Intent(this, RockboxService.class); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + /* prepare a please wait dialog in case we need * to wait for unzipping libmisc.so */ loadingdialog = new ProgressDialog(this); loadingdialog.setMessage("Rockbox is loading. Please wait..."); - loadingdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + loadingdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + loadingdialog.setIndeterminate(true); loadingdialog.setCancelable(false); - startService(intent); - rbservice = RockboxService.get_instance(); - /* Now it gets a bit tricky: - * The service is started in the same thread as we are now, - * but the service also initializes the framebuffer - * Unfortunately, this happens *after* any of the default - * startup methods of an activity, so we need to poll for it - * - * In order to get the fb, we need to let the Service start up - * run, we can wait in a separate thread for fb to get ready - * This thread waits for the fb to become ready */ - new Thread(new Runnable() - { - public void run() + loadingdialog.show(); + + Intent intent = new Intent(this, RockboxService.class); + intent.putExtra("callback", new ResultReceiver(null) { + @Override + protected void onReceiveResult(final int resultCode, final Bundle resultData) { - int i = 0; - try { - while (true) - { - Thread.sleep(250); - if (isRockboxRunning()) - break; - /* if it's still null show the please wait dialog - * but not before 0.5s are over */ - if (!loadingdialog.isShowing() && i > 0) - { - runOnUiThread(new Runnable() - { - public void run() - { - loadingdialog.show(); - } - }); - } - else - i++ ; - } - } catch (InterruptedException e) { - } - /* drawing needs to happen in ui thread */ - runOnUiThread(new Runnable() + runOnUiThread(new Runnable() { public void run() { - loadingdialog.dismiss(); - if (rbservice.get_fb() == null) - throw new IllegalStateException("FB NULL"); - attachFramebuffer(); + switch (resultCode) { + case RockboxService.RESULT_LIB_LOADED: + rbservice = RockboxService.get_instance(); + loadingdialog.setIndeterminate(true); + break; + case RockboxService.RESULT_LIB_LOAD_PROGRESS: + loadingdialog.setIndeterminate(false); + loadingdialog.setMax(resultData.getInt("max", 100)); + loadingdialog.setProgress(resultData.getInt("value", 0)); + break; + case RockboxService.RESULT_FB_INITIALIZED: + attachFramebuffer(); + loadingdialog.dismiss(); + break; + } + } }); } - }).start(); + }); + startService(intent); } + private boolean isRockboxRunning() { if (rbservice == null) - rbservice = RockboxService.get_instance(); + rbservice = RockboxService.get_instance(); return (rbservice!= null && rbservice.isRockboxRunning() == true); } diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java index 8989271b9f..a441a7dec4 100644 --- a/android/src/org/rockbox/RockboxService.java +++ b/android/src/org/rockbox/RockboxService.java @@ -21,8 +21,6 @@ package org.rockbox; -import org.rockbox.Helper.RunForegroundManager; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -35,13 +33,17 @@ import java.util.TimerTask; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.rockbox.Helper.RunForegroundManager; + import android.app.Activity; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Bundle; import android.os.IBinder; +import android.os.ResultReceiver; import android.util.Log; /* This class is used as the main glue between java and c. @@ -65,12 +67,16 @@ public class RockboxService extends Service private RunForegroundManager fg_runner; @SuppressWarnings("unused") private int battery_level; + private ResultReceiver resultReceiver; + + public static final int RESULT_LIB_LOADED = 0; + public static final int RESULT_LIB_LOAD_PROGRESS = 1; + public static final int RESULT_FB_INITIALIZED = 2; @Override public void onCreate() { instance = this; - startservice(); } public static RockboxService get_instance() @@ -87,6 +93,8 @@ public class RockboxService extends Service { fb = newfb; mRockboxRunning = true; + if (resultReceiver != null) + resultReceiver.send(RESULT_FB_INITIALIZED, null); } public Activity get_activity() @@ -97,11 +105,14 @@ public class RockboxService extends Service { current_activity = a; } - private void do_start(Intent intent) { LOG("Start Service"); + + if (intent.hasExtra("callback")) + resultReceiver = (ResultReceiver) intent.getParcelableExtra("callback"); + startservice(); /* Display a notification about us starting. * We put an icon in the status bar. */ @@ -140,6 +151,7 @@ public class RockboxService extends Service public void run() { LOG("main"); + Bundle progressData = new Bundle(); /* 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 @@ -160,6 +172,7 @@ public class RockboxService extends Service ZipFile zipfile = new ZipFile(file); Enumeration e = zipfile.entries(); File folder; + progressData.putInt("max", zipfile.size()); while(e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); @@ -190,6 +203,10 @@ public class RockboxService extends Service dest.flush(); dest.close(); is.close(); + if (resultReceiver != null) { + progressData.putInt("value", progressData.getInt("value", 0) + 1); + resultReceiver.send(RESULT_LIB_LOAD_PROGRESS, progressData); + } } } } catch(FileNotFoundException e) { @@ -201,7 +218,10 @@ public class RockboxService extends Service } System.loadLibrary("rockbox"); + if (resultReceiver != null) + resultReceiver.send(RESULT_LIB_LOADED, null); main(); + throw new IllegalStateException("native main() returned!"); } },"Rockbox thread"); rb.setDaemon(false); -- cgit v1.2.3