summaryrefslogtreecommitdiffstats
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/.classpath7
-rw-r--r--android/.project33
-rw-r--r--android/AndroidManifest.xml18
-rw-r--r--android/README34
-rw-r--r--android/default.properties11
-rw-r--r--android/gen/org/rockbox/R.java22
-rw-r--r--android/res/drawable-hdpi/icon.pngbin0 -> 4147 bytes
-rw-r--r--android/res/drawable-ldpi/icon.pngbin0 -> 1723 bytes
-rw-r--r--android/res/drawable-mdpi/icon.pngbin0 -> 2574 bytes
-rw-r--r--android/res/layout/main.xml7
-rw-r--r--android/res/values/strings.xml5
-rw-r--r--android/src/org/rockbox/RockboxActivity.java148
-rw-r--r--android/src/org/rockbox/RockboxFramebuffer.java98
-rw-r--r--android/src/org/rockbox/RockboxPCM.java155
-rw-r--r--android/src/org/rockbox/RockboxTimer.java93
15 files changed, 631 insertions, 0 deletions
diff --git a/android/.classpath b/android/.classpath
new file mode 100644
index 0000000000..6efcbb739a
--- /dev/null
+++ b/android/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/android/.project b/android/.project
new file mode 100644
index 0000000000..7e8d136317
--- /dev/null
+++ b/android/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>Rockbox</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 0000000000..a22c393379
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.rockbox"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
+ <activity android:name=".RockboxActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+<uses-sdk android:minSdkVersion="4" />
+<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
+</manifest> \ No newline at end of file
diff --git a/android/README b/android/README
new file mode 100644
index 0000000000..e41bfa6c0c
--- /dev/null
+++ b/android/README
@@ -0,0 +1,34 @@
+This folder contains the java parts needed to build an Rockbox as an
+application for android.
+
+* Build instructions
+
+Until there's a script which does all the work the procedure is documented here.
+
+First, make sure you have the ANDROID_NDK_PATH environment variable set up,
+otherwise configure will fail to find the compiler.
+
+Use this as your build folder, using '../tools/configure' etc.
+ $ ../tools/configure
+ $ make
+
+After the build finished, you need to copy librockbox.so to libs/armeabi/.
+ $ cp librockbox.so libs/armeabi
+
+For the other files (codecs, themes), you execute 'make zip'. Then you copy the
+zip to libs/armeabi, using the name libmisc.so. This is needed, since there's no
+way to bundle stuff into apk's and have access to them from native code other
+than pretending it was a library.
+ $ make zip
+ $ cp rockbox.zip lib/armeabi/libmisc.so
+
+rockbox.zip..err, libmisc.so will be unpacked at runtime.
+
+To finish, you can follow this guide [1], or use eclipse. Simply install eclipse
+and the android plugins, then import this folder as a new Android project and run it.
+See [2] for a guide on how to set up eclipse for android development.
+
+
+
+[1]: http://asantoso.wordpress.com/2009/09/15/how-to-build-android-application-package-apk-from-the-command-line-using-the-sdk-tools-continuously-integrated-using-cruisecontrol/
+[2]: http://developer.android.com/sdk/installing.html
diff --git a/android/default.properties b/android/default.properties
new file mode 100644
index 0000000000..9d79b12c71
--- /dev/null
+++ b/android/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-4
diff --git a/android/gen/org/rockbox/R.java b/android/gen/org/rockbox/R.java
new file mode 100644
index 0000000000..38c177ef36
--- /dev/null
+++ b/android/gen/org/rockbox/R.java
@@ -0,0 +1,22 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package org.rockbox;
+
+public final class R {
+ public static final class attr {
+ }
+ public static final class drawable {
+ public static final int icon=0x7f020000;
+ }
+ public static final class layout {
+ public static final int main=0x7f030000;
+ }
+ public static final class string {
+ public static final int app_name=0x7f040000;
+ }
+}
diff --git a/android/res/drawable-hdpi/icon.png b/android/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000000..8074c4c571
--- /dev/null
+++ b/android/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/android/res/drawable-ldpi/icon.png b/android/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000000..1095584ec2
--- /dev/null
+++ b/android/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/android/res/drawable-mdpi/icon.png b/android/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000000..a07c69fa5a
--- /dev/null
+++ b/android/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/android/res/layout/main.xml b/android/res/layout/main.xml
new file mode 100644
index 0000000000..4361cfe8aa
--- /dev/null
+++ b/android/res/layout/main.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+</LinearLayout>
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
new file mode 100644
index 0000000000..6c3c8464fd
--- /dev/null
+++ b/android/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">Rockbox</string>
+</resources>
diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java
new file mode 100644
index 0000000000..791cad90ff
--- /dev/null
+++ b/android/src/org/rockbox/RockboxActivity.java
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+package org.rockbox;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import android.app.Activity;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
+
+public class RockboxActivity extends Activity {
+ /** Called when the activity is first created. */
+ public RockboxFramebuffer fb;
+ private Thread rb;
+ static final int BUFFER = 2048;
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ LOG("start rb");
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
+ ,WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ fb = new RockboxFramebuffer(this);
+ if (true) {
+ try
+ {
+ BufferedOutputStream dest = null;
+ BufferedInputStream is = null;
+ ZipEntry entry;
+ File file = new File("/data/data/org.rockbox/lib/libmisc.so");
+ /* use arbitary file to determine whether extracting is needed */
+ File file2 = new File("/data/data/org.rockbox/app_rockbox/rockbox/codecs/mpa.codec");
+ if (!file2.exists() || (file.lastModified() > file2.lastModified()))
+ {
+ ZipFile zipfile = new ZipFile(file);
+ Enumeration<? extends ZipEntry> e = zipfile.entries();
+ File folder;
+ while(e.hasMoreElements()) {
+ entry = (ZipEntry) e.nextElement();
+ LOG("Extracting: " +entry);
+ if (entry.isDirectory())
+ {
+ folder = new File(entry.getName());
+ LOG("mkdir "+ entry);
+ try {
+ folder.mkdirs();
+ } catch (SecurityException ex){
+ LOG(ex.getMessage());
+ }
+ continue;
+ }
+ is = new BufferedInputStream(zipfile.getInputStream(entry));
+ int count;
+ byte data[] = new byte[BUFFER];
+ folder = new File(new File(entry.getName()).getParent());
+ LOG("" + folder.getAbsolutePath());
+ if (!folder.exists())
+ folder.mkdirs();
+ FileOutputStream fos = new FileOutputStream(entry.getName());
+ dest = new BufferedOutputStream(fos, BUFFER);
+ while ((count = is.read(data, 0, BUFFER)) != -1) {
+ dest.write(data, 0, count);
+ }
+ dest.flush();
+ dest.close();
+ is.close();
+ }
+ }
+ } catch(Exception e) {
+ e.printStackTrace();
+ }}
+ Rect r = new Rect();
+ fb.getDrawingRect(r);
+ LOG(r.left + " " + r.top + " " + r.right + " " + r.bottom);
+ rb = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ main();
+ }
+ },"Rockbox thread");
+ System.loadLibrary("rockbox");
+ rb.setDaemon(false);
+ setContentView(fb);
+ }
+
+ private void LOG(CharSequence text)
+ {
+ Log.d("RockboxBootloader", (String) text);
+ }
+
+ public synchronized void onStart()
+ {
+ super.onStart();
+ if (!rb.isAlive())
+ rb.start();
+ }
+
+ public void onPause()
+ {
+ super.onPause();
+ }
+
+ public void onResume()
+ {
+ super.onResume();
+ switch (rb.getState()) {
+ case BLOCKED: LOG("BLOCKED"); break;
+ case RUNNABLE: LOG("RUNNABLE"); break;
+ case NEW: LOG("NEW"); break;
+ case TERMINATED: LOG("TERMINATED"); break;
+ case TIMED_WAITING: LOG("TIMED_WAITING"); break;
+ case WAITING: LOG("WAITING"); break;
+ }
+ }
+
+
+ private native void main();
+} \ No newline at end of file
diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java
new file mode 100644
index 0000000000..f947806bb4
--- /dev/null
+++ b/android/src/org/rockbox/RockboxFramebuffer.java
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+package org.rockbox;
+
+import java.nio.ByteBuffer;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.os.Handler;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class RockboxFramebuffer extends View
+{
+ private Bitmap btm;
+ private ByteBuffer native_buf;
+ private Handler update_handler;
+ private Runnable cb;
+
+
+ public RockboxFramebuffer(Context c)
+ {
+ super(c);
+ update_handler = new Handler();
+ cb = new Runnable() {
+ public void run()
+ {
+ btm.copyPixelsFromBuffer(native_buf);
+ invalidate();
+ }
+ };
+ btm = null;
+ }
+
+ public void onDraw(Canvas c)
+ {
+ if (btm != null)
+ c.drawBitmap(btm, 0.0f, 0.0f, null);
+ }
+
+ public void java_lcd_init(int lcd_width, int lcd_height, ByteBuffer native_fb)
+ {
+ btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565);
+ native_buf = native_fb;
+ }
+
+ public void java_lcd_update()
+ {
+ update_handler.post(cb);
+ }
+
+ private void LOG(CharSequence text)
+ {
+ Log.d("RockboxBootloader", (String) text);
+ }
+
+ public boolean onTouchEvent(MotionEvent me)
+ {
+ LOG("onTouchEvent");
+ switch (me.getAction())
+ {
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ touchHandler(0);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ case MotionEvent.ACTION_DOWN:
+ touchHandler(1);
+ break;
+
+ }
+ pixelHandler((int)me.getX(), (int)me.getY());
+ return true;
+ }
+
+ public native void pixelHandler(int x, int y);
+ public native void touchHandler(int down);
+}
diff --git a/android/src/org/rockbox/RockboxPCM.java b/android/src/org/rockbox/RockboxPCM.java
new file mode 100644
index 0000000000..f098df6991
--- /dev/null
+++ b/android/src/org/rockbox/RockboxPCM.java
@@ -0,0 +1,155 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+package org.rockbox;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.util.Log;
+
+public class RockboxPCM extends AudioTrack
+{
+ byte[] raw_data;
+
+ private void LOG(CharSequence text)
+ {
+ Log.d("RockboxBootloader", (String) text);
+ }
+
+ public RockboxPCM()
+ {
+ super(AudioManager.STREAM_MUSIC,
+ 44100,
+ /* should be CHANNEL_OUT_STEREO in 2.0 and above */
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ 24<<10,
+ AudioTrack.MODE_STREAM);
+ int buf_len = 24<<10;
+
+ raw_data = new byte[buf_len*2];
+ for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte) 0x00;
+ /* fill with silence */
+ write(raw_data, 0, raw_data.length);
+ if (getState() == AudioTrack.STATE_INITIALIZED)
+ {
+ if (setNotificationMarkerPosition(bytes2frames(buf_len*2)/4) != AudioTrack.SUCCESS)
+ LOG("setNotificationMarkerPosition Error");
+ setPlaybackPositionUpdateListener(new PCMListener(buf_len*2));
+ }
+ }
+
+
+
+ int bytes2frames(int bytes) {
+ /* 1 sample is 2 bytes, 2 samples are 1 frame */
+ return (bytes/4);
+ }
+
+ int frames2bytes(int frames) {
+ /* 1 frame is 2 samples, 1 sample is 2 bytes */
+ return (frames*4);
+ }
+
+ @SuppressWarnings("unused")
+ private void play_pause(boolean pause) {
+ LOG("play_pause()");
+ if (pause)
+ pause();
+ else
+ {
+ if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED)
+ {
+ for(int i = 0; i < raw_data.length; i++) raw_data[i] = (byte) 0x00;
+ LOG("Writing silence");
+ /* fill with silence */
+ write(raw_data, 0, raw_data.length);
+ }
+ play();
+ }
+ LOG("play_pause() return");
+ }
+
+ @SuppressWarnings("unused")
+ private void set_volume(int volume)
+ {
+ /* volume comes from 0..-990 from Rockbox */
+ /* TODO volume is in dB, but this code acts as if it were in %, convert? */
+ float fvolume;
+ /* special case min and max volume to not suffer from floating point accuracy */
+ if (volume == 0)
+ fvolume = 1.0f;
+ else if (volume == -990)
+ fvolume = 0.0f;
+ else
+ fvolume = (volume + 990)/990.0f;
+ setStereoVolume(fvolume, fvolume);
+ }
+
+ public native void pcmSamplesToByteArray(byte[] dest);
+
+ private class PCMListener implements OnPlaybackPositionUpdateListener {
+ int max_len;
+ byte[] buf;
+ public PCMListener(int len) {
+ max_len = len;
+ buf = new byte[len/2];
+ }
+ @Override
+ public void onMarkerReached(AudioTrack track) {
+ // push new data to the hardware
+ int result = 1;
+ pcmSamplesToByteArray(buf);
+ //LOG("Trying to write " + buf.length + " bytes");
+ result = track.write(buf, 0, buf.length);
+ if (result > 0)
+ {
+ //LOG(result + " bytes written");
+ track.setPlaybackPositionUpdateListener(this);
+ track.setNotificationMarkerPosition(bytes2frames(max_len)/4);
+ switch(track.getPlayState())
+ {
+ case AudioTrack.PLAYSTATE_PLAYING:
+ //LOG("State PLAYING");
+ break;
+ case AudioTrack.PLAYSTATE_PAUSED:
+ LOG("State PAUSED");
+ break;
+ case AudioTrack.PLAYSTATE_STOPPED:
+ LOG("State STOPPED");
+ break;
+ }
+ }
+ else
+ {
+ LOG("Error in onMarkerReached");
+ track.stop();
+ }
+ }
+
+ @Override
+ public void onPeriodicNotification(AudioTrack track) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+}
diff --git a/android/src/org/rockbox/RockboxTimer.java b/android/src/org/rockbox/RockboxTimer.java
new file mode 100644
index 0000000000..c7239b4ee6
--- /dev/null
+++ b/android/src/org/rockbox/RockboxTimer.java
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2010 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+package org.rockbox;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import android.util.Log;
+
+public class RockboxTimer extends Timer
+{
+ RockboxTimerTask task;
+ long interval;
+
+ private class RockboxTimerTask extends TimerTask {
+ private RockboxTimer t;
+ public RockboxTimerTask(RockboxTimer parent) {
+ super();
+ t = parent;
+ }
+
+ @Override
+ public void run() {
+ timerTask();
+ synchronized(t) {
+ t.notify();
+ }
+ }
+ }
+
+ public void pause()
+ {
+ cancel();
+ }
+ public void resume()
+ {
+ try {
+ schedule(task, 0, interval);
+ } catch (IllegalStateException e) {
+ /* not an error */
+ } catch (Exception e) {
+ LOG(e.toString());
+ }
+ }
+
+ public RockboxTimer(long period_inverval_in_ms)
+ {
+ super("tick timer", false);
+ task = new RockboxTimerTask(this);
+ schedule(task, 0, period_inverval_in_ms);
+ interval = period_inverval_in_ms;
+ }
+
+ private void LOG(CharSequence text)
+ {
+ Log.d("RockboxBootloader", (String) text);
+ }
+
+
+ /* methods called from native, keep them simple */
+ public void java_wait_for_interrupt()
+ {
+ synchronized(this) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ /* wakeup and return */
+ } catch (Exception e) {
+ LOG(e.toString());
+ }
+ }
+ }
+ public native void timerTask();
+}