diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2011-03-11 15:45:44 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2011-03-11 15:45:44 +0000 |
commit | d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3 (patch) | |
tree | ad47c2b842a55a919eb3089657ec9fba3f25864b /apps/hosted/android | |
parent | cae7560f32aa1067479580bf5abbfb3930a2a06b (diff) | |
download | rockbox-d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3.tar.gz rockbox-d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3.zip |
RaaA: move Android apps-code to separate dir under apps/hosted
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29563 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/hosted/android')
-rw-r--r-- | apps/hosted/android/keyboard.c | 119 | ||||
-rw-r--r-- | apps/hosted/android/notification.c | 147 | ||||
-rw-r--r-- | apps/hosted/android/notification.h | 27 | ||||
-rw-r--r-- | apps/hosted/android/yesno.c | 121 |
4 files changed, 414 insertions, 0 deletions
diff --git a/apps/hosted/android/keyboard.c b/apps/hosted/android/keyboard.c new file mode 100644 index 0000000000..9407d970fd --- /dev/null +++ b/apps/hosted/android/keyboard.c @@ -0,0 +1,119 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Jonathan Gordon + * + * 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. + * + ****************************************************************************/ +#include "config.h" + +#if (CONFIG_PLATFORM&PLATFORM_ANDROID) +#include <jni.h> +#include <stdbool.h> +#include "string-extra.h" +#include "kernel.h" +#include "lang.h" + +extern JNIEnv *env_ptr; +static jclass RockboxKeyboardInput_class; +static jobject RockboxKeyboardInput_instance; +static jmethodID kbd_inputfunc; +static struct semaphore kbd_wakeup; +static bool accepted; +static jstring new_string; + +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxKeyboardInput_put_1result(JNIEnv *env, jobject this, + jboolean _accepted, + jstring _new_string) +{ + (void)env;(void)this; + + accepted = (bool)_accepted; + if (accepted) + { + new_string = _new_string; + (*env)->NewGlobalRef(env, new_string); /* prevet GC'ing */ + } + semaphore_release(&kbd_wakeup); +} + +static void kdb_init(void) +{ + JNIEnv e = *env_ptr; + static jmethodID kbd_is_usable; + if (RockboxKeyboardInput_class == NULL) + { + semaphore_init(&kbd_wakeup, 1, 0); + /* get the class and its constructor */ + RockboxKeyboardInput_class = e->FindClass(env_ptr, + "org/rockbox/RockboxKeyboardInput"); + jmethodID constructor = e->GetMethodID(env_ptr, + RockboxKeyboardInput_class, + "<init>", "()V"); + RockboxKeyboardInput_instance = e->NewObject(env_ptr, + RockboxKeyboardInput_class, + constructor); + kbd_inputfunc = e->GetMethodID(env_ptr, RockboxKeyboardInput_class, + "kbd_input", + "(Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;)V"); + kbd_is_usable = e->GetMethodID(env_ptr, RockboxKeyboardInput_class, + "is_usable", "()Z"); + } + + /* need to get it every time incase the activity died/restarted */ + while (!e->CallBooleanMethod(env_ptr, RockboxKeyboardInput_instance, + kbd_is_usable)) + sleep(HZ/10); +} + +int kbd_input(char* text, int buflen) +{ + JNIEnv e = *env_ptr; + jstring str = e->NewStringUTF(env_ptr, text); + jstring ok_text = e->NewStringUTF(env_ptr, str(LANG_KBD_OK)); + jstring cancel_text = e->NewStringUTF(env_ptr, str(LANG_KBD_CANCEL)); + const char *utf8_string; + kdb_init(); + + e->CallVoidMethod(env_ptr, RockboxKeyboardInput_instance,kbd_inputfunc, + str, ok_text, cancel_text); + + semaphore_wait(&kbd_wakeup, TIMEOUT_BLOCK); + + if (accepted) + { + utf8_string = e->GetStringUTFChars(env_ptr, new_string, 0); + strlcpy(text, utf8_string, buflen); + e->ReleaseStringUTFChars(env_ptr, new_string, utf8_string); + e->DeleteGlobalRef(env_ptr, new_string); + } + e->DeleteLocalRef(env_ptr, str); + e->DeleteLocalRef(env_ptr, ok_text); + e->DeleteLocalRef(env_ptr, cancel_text); + + return !accepted; /* return 0 on success */ +} + +int load_kbd(unsigned char* filename) +{ + (void)filename; + return 1; +} + +#endif diff --git a/apps/hosted/android/notification.c b/apps/hosted/android/notification.c new file mode 100644 index 0000000000..443200698c --- /dev/null +++ b/apps/hosted/android/notification.c @@ -0,0 +1,147 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ + +#include <jni.h> +#include <stdio.h> +#include <sys/mman.h> +#include "notification.h" +#include "appevents.h" +#include "metadata.h" +#include "albumart.h" +#include "misc.h" +#include "thread.h" +#include "debug.h" + +extern JNIEnv *env_ptr; +extern jclass RockboxService_class; +extern jobject RockboxService_instance; + +static jmethodID updateNotification, finishNotification; +static jobject NotificationManager_instance; +static jstring title, artist, album, albumart; + +/* completely arbitrary dimensions. neded for find_albumart() */ +static const struct dim dim = { .width = 200, .height = 200 }; +#define NZV(a) (a && a[0]) + +/* + * notify about track change, and show track info */ +static void track_changed_callback(void *param) +{ + struct mp3entry* id3 = (struct mp3entry*)param; + JNIEnv e = *env_ptr; + if (id3) + { + /* passing NULL to DeleteLocalRef() is OK */ + e->DeleteLocalRef(env_ptr, title); + e->DeleteLocalRef(env_ptr, artist); + e->DeleteLocalRef(env_ptr, album); + e->DeleteLocalRef(env_ptr, albumart); + + char buf[200]; + const char * ptitle = id3->title; + if (!ptitle && *id3->path) + { /* pass the filename as title if id3 info isn't available */ + ptitle = strip_extension(buf, sizeof(buf), strrchr(id3->path,'/') + 1); + } + + title = e->NewStringUTF(env_ptr, ptitle ?: ""); + artist = e->NewStringUTF(env_ptr, id3->artist ?: ""); + album = e->NewStringUTF(env_ptr, id3->album ?: ""); + + albumart = NULL; + if (id3->embed_albumart && id3->albumart.type == AA_TYPE_JPG) + { /* extract albumart to a temporary file using mmap() */ + snprintf(buf, sizeof(buf), "/sdcard/rockbox/.temp_albumart_%d.jpg", + thread_self()); + int dst_fd = creat(buf, 0666); + if (dst_fd >= 0) + { + int src_fd = open(id3->path, O_RDONLY); + off_t o_pos = id3->albumart.pos; + off_t pa_pos = o_pos & ~(sysconf(_SC_PAGE_SIZE) - 1); + if (src_fd >= 0) + { /* align to page boundary */ + int pos_diff = o_pos - pa_pos; + unsigned char* p = mmap(NULL, id3->albumart.size + pos_diff, + PROT_READ, MAP_SHARED, src_fd, pa_pos); + if (p != MAP_FAILED) + { + write(dst_fd, p + pos_diff, id3->albumart.size); + munmap(p, id3->albumart.size + pos_diff); + albumart = e->NewStringUTF(env_ptr, buf); + } + close(src_fd); + } + close(dst_fd); + } + } + else if (find_albumart(id3, buf, sizeof(buf), &dim)) + { + albumart = e->NewStringUTF(env_ptr, buf); + } + + e->CallVoidMethod(env_ptr, NotificationManager_instance, + updateNotification, title, artist, album, albumart); + } +} + +/* + * notify about track finishing */ +static void track_finished_callback(void *param) +{ + (void)param; + JNIEnv e = *env_ptr; + e->CallVoidMethod(env_ptr, NotificationManager_instance, + finishNotification); + + /* delete temporary albumart file */ + char buf[MAX_PATH]; + snprintf(buf, sizeof(buf), "/sdcard/rockbox/.temp_albumart_%d.jpg", + thread_self()); + unlink(buf); +} + +void notification_init(void) +{ + JNIEnv e = *env_ptr; + jfieldID nNM = e->GetFieldID(env_ptr, RockboxService_class, + "fg_runner", "Lorg/rockbox/Helper/RunForegroundManager;"); + NotificationManager_instance = e->GetObjectField(env_ptr, + RockboxService_instance, nNM); + if (NotificationManager_instance == NULL) + { + DEBUGF("Failed to get RunForegroundManager instance. Performance will be bad"); + return; + } + + jclass class = e->GetObjectClass(env_ptr, NotificationManager_instance); + updateNotification = e->GetMethodID(env_ptr, class, "updateNotification", + "(Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;)V"); + finishNotification = e->GetMethodID(env_ptr, class, "finishNotification", + "()V"); + + add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback); + add_event(PLAYBACK_EVENT_TRACK_FINISH, false, track_finished_callback); +} diff --git a/apps/hosted/android/notification.h b/apps/hosted/android/notification.h new file mode 100644 index 0000000000..d182c7f8e7 --- /dev/null +++ b/apps/hosted/android/notification.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ + +#ifndef __NOTIFICATION_H__ +#define __NOTIFICATION_H__ + +void notification_init(void); + +#endif diff --git a/apps/hosted/android/yesno.c b/apps/hosted/android/yesno.c new file mode 100644 index 0000000000..a1de64e3f9 --- /dev/null +++ b/apps/hosted/android/yesno.c @@ -0,0 +1,121 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Jonathan Gordon + * + * 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. + * + ****************************************************************************/ +#include "config.h" + +#if (CONFIG_PLATFORM&PLATFORM_ANDROID) +#include <jni.h> +#include <stdbool.h> +#include <stdio.h> +#include "yesno.h" +#include "settings.h" +#include "lang.h" +#include "kernel.h" + +extern JNIEnv *env_ptr; +static jclass RockboxYesno_class = NULL; +static jobject RockboxYesno_instance = NULL; +static jmethodID yesno_func; +static struct semaphore yesno_done; +static bool ret; + +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxYesno_put_1result(JNIEnv *env, jobject this, jboolean result) +{ + (void)env; + (void)this; + ret = (bool)result; + semaphore_release(&yesno_done); +} + +static void yesno_init(void) +{ + JNIEnv e = *env_ptr; + static jmethodID yesno_is_usable; + if (RockboxYesno_class == NULL) + { + semaphore_init(&yesno_done, 1, 0); + /* get the class and its constructor */ + RockboxYesno_class = e->FindClass(env_ptr, + "org/rockbox/RockboxYesno"); + jmethodID constructor = e->GetMethodID(env_ptr, + RockboxYesno_class, + "<init>", "()V"); + RockboxYesno_instance = e->NewObject(env_ptr, + RockboxYesno_class, + constructor); + yesno_func = e->GetMethodID(env_ptr, RockboxYesno_class, + "yesno_display", + "(Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;)V"); + yesno_is_usable = e->GetMethodID(env_ptr, RockboxYesno_class, + "is_usable", "()Z"); + } + /* need to get it every time incase the activity died/restarted */ + while (!e->CallBooleanMethod(env_ptr, RockboxYesno_instance, + yesno_is_usable)) + sleep(HZ/10); +} + +jstring build_message(const struct text_message *message) +{ + char msg[1024] = ""; + JNIEnv e = *env_ptr; + int i; + for(i=0; i<message->nb_lines; i++) + { + char* text = P2STR((unsigned char *)message->message_lines[i]); + if (i>0) + strlcat(msg, "\n", 1024); + strlcat(msg, text, 1024); + } + /* make sure the questions end in a ?, for some reason they dont! */ + if (!strrchr(msg, '?')) + strlcat(msg, "?", 1024); + return e->NewStringUTF(env_ptr, msg); +} + +enum yesno_res gui_syncyesno_run(const struct text_message * main_message, + const struct text_message * yes_message, + const struct text_message * no_message) +{ + (void)yes_message; + (void)no_message; + yesno_init(); + + JNIEnv e = *env_ptr; + jstring message = build_message(main_message); + jstring yes = (*env_ptr)->NewStringUTF(env_ptr, str(LANG_SET_BOOL_YES)); + jstring no = (*env_ptr)->NewStringUTF(env_ptr, str(LANG_SET_BOOL_NO)); + + e->CallVoidMethod(env_ptr, RockboxYesno_instance, yesno_func, + message, yes, no); + + semaphore_wait(&yesno_done, TIMEOUT_BLOCK); + + e->DeleteLocalRef(env_ptr, message); + e->DeleteLocalRef(env_ptr, yes); + e->DeleteLocalRef(env_ptr, no); + + return ret ? YESNO_YES : YESNO_NO; +} + +#endif |