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/notification.c | |
| parent | cae7560f32aa1067479580bf5abbfb3930a2a06b (diff) | |
| download | rockbox-d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3.zip rockbox-d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3.tar.gz rockbox-d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3.tar.bz2 rockbox-d833e78fac8d311b30e265d4df9c3cdd6eb6d1e3.tar.xz | |
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/notification.c')
| -rw-r--r-- | apps/hosted/android/notification.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/apps/hosted/android/notification.c b/apps/hosted/android/notification.c new file mode 100644 index 0000000..4432006 --- /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); +} |