From 33de9cdaefd8684e3411486612e68c0c2bd6be3d Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Mon, 18 Jul 2011 21:02:47 +0000 Subject: Android: Refactor some of the glue code. * Cleanup RockboxService.java by moving the battery and headphone monitors to separate classes and detaching their instances * Move those monitors and RockboxTelephony.java into a new monitors subdirectory * Call those monitors all the same from native code by creating the objects there git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30160 a1c6a512-1295-4272-9138-f99709370657 --- android/android.make | 5 +- android/src/org/rockbox/RockboxService.java | 81 ------------------ android/src/org/rockbox/RockboxTelephony.java | 97 ---------------------- .../src/org/rockbox/monitors/BatteryMonitor.java | 74 +++++++++++++++++ .../src/org/rockbox/monitors/HeadphoneMonitor.java | 60 +++++++++++++ .../src/org/rockbox/monitors/TelephonyMonitor.java | 97 ++++++++++++++++++++++ firmware/target/hosted/android/button-android.c | 32 +++---- firmware/target/hosted/android/powermgmt-android.c | 24 +++--- firmware/target/hosted/android/telephony-android.c | 16 ++-- 9 files changed, 271 insertions(+), 215 deletions(-) delete mode 100644 android/src/org/rockbox/RockboxTelephony.java create mode 100644 android/src/org/rockbox/monitors/BatteryMonitor.java create mode 100644 android/src/org/rockbox/monitors/HeadphoneMonitor.java create mode 100644 android/src/org/rockbox/monitors/TelephonyMonitor.java diff --git a/android/android.make b/android/android.make index f319bb9..e4fd369 100644 --- a/android/android.make +++ b/android/android.make @@ -39,9 +39,10 @@ MANIFEST_SRC := $(ANDROID_DIR)/AndroidManifest.xml R_JAVA := $(BUILDDIR)/gen/$(PACKAGE_PATH)/R.java R_OBJ := $(BUILDDIR)/bin/$(PACKAGE_PATH)/R.class -JAVA_SRC := $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/Helper/*.java) -JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/*.java) +JAVA_SRC := $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/*.java) +JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/Helper/*.java) JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/widgets/*.java) +JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/monitors/*.java) JAVA_OBJ := $(call java2class,$(subst $(ANDROID)/src/$(PACKAGE_PATH),$(ANDROID)/bin/$(PACKAGE_PATH),$(JAVA_SRC))) diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java index 49abb52..20b8d0c 100644 --- a/android/src/org/rockbox/RockboxService.java +++ b/android/src/org/rockbox/RockboxService.java @@ -27,20 +27,13 @@ import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.util.Enumeration; -import java.util.Timer; -import java.util.TimerTask; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; - import org.rockbox.Helper.MediaButtonReceiver; 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.Environment; import android.os.IBinder; @@ -63,17 +56,9 @@ public class RockboxService extends Service /* locals needed for the c code and rockbox state */ private static volatile boolean rockbox_running; private Activity current_activity = null; - private IntentFilter itf; - private IntentFilter ifh; - private BroadcastReceiver batt_monitor; - private BroadcastReceiver headphone_monitor; - private BroadcastReceiver noisy_monitor; private RunForegroundManager fg_runner; private MediaButtonReceiver mMediaButtonReceiver; - private int battery_level; - private int headphone_state; private ResultReceiver resultReceiver; - private RockboxService rbservice; public static final int RESULT_INVOKING_MAIN = 0; public static final int RESULT_LIB_LOAD_PROGRESS = 1; @@ -314,72 +299,6 @@ public class RockboxService extends Service return null; } - - private void initBatteryMonitor() - { - itf = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - batt_monitor = new BroadcastReceiver() - { - @Override - public void onReceive(Context context, Intent intent) - { - /* we get literally spammed with battery statuses - * if we don't delay the re-attaching - */ - TimerTask tk = new TimerTask() - { - public void run() - { - registerReceiver(batt_monitor, itf); - } - }; - Timer t = new Timer(); - context.unregisterReceiver(this); - int rawlevel = intent.getIntExtra("level", -1); - int scale = intent.getIntExtra("scale", -1); - if (rawlevel >= 0 && scale > 0) - battery_level = (rawlevel * 100) / scale; - else - battery_level = -1; - /* query every 30s should be sufficient */ - t.schedule(tk, 30000); - } - }; - registerReceiver(batt_monitor, itf); - } - - - private void initHeadphoneMonitor() - { - ifh = new IntentFilter(Intent.ACTION_HEADSET_PLUG); - headphone_monitor = new BroadcastReceiver() - { - @Override - public void onReceive(Context context, Intent intent) - { - int state = intent.getIntExtra("state", -1); - LOG("headphone state:" + state); - headphone_state = state; - } - }; - registerReceiver(headphone_monitor, ifh); - noisy_monitor = new BroadcastReceiver() - { - @Override - public void onReceive(Context context, Intent intent) - { - LOG("audio becoming noisy"); - headphone_state = 0; - } - }; - rbservice = RockboxService.get_instance(); - /* We're relying on internal API's here, - this can break in the future! */ - rbservice.registerReceiver(noisy_monitor, - new IntentFilter("android.media.AUDIO_BECOMING_NOISY")); - } - - void startForeground() { fg_runner.startForeground(); diff --git a/android/src/org/rockbox/RockboxTelephony.java b/android/src/org/rockbox/RockboxTelephony.java deleted file mode 100644 index faaf0c3..0000000 --- a/android/src/org/rockbox/RockboxTelephony.java +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * 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.content.Context; -import android.os.Handler; -import android.telephony.PhoneStateListener; -import android.telephony.TelephonyManager; - -public class RockboxTelephony -{ - public RockboxTelephony(Context c) - { - final Handler handler = new Handler(c.getMainLooper()); - final TelephonyManager tm = (TelephonyManager) - c.getSystemService(Context.TELEPHONY_SERVICE); - handler.post(new Runnable() - { - @Override - public void run() - { /* need to instantiate from a thread that has a Looper */ - tm.listen(new RockboxCallStateListener(), PhoneStateListener.LISTEN_CALL_STATE); - } - }); - } - - private class RockboxCallStateListener extends PhoneStateListener - { - private int last_state; - - public RockboxCallStateListener() - { - super(); - /* set artificial initial state, - * we will get an initial event shortly after this, - * so to handle it correctly we need an invalid state set */ - last_state = TelephonyManager.CALL_STATE_IDLE - 10; - } - - private void handleState(int state) - { - if (state == last_state) - return; - switch (state) - { - case TelephonyManager.CALL_STATE_IDLE: - postCallHungUp(); - break; - case TelephonyManager.CALL_STATE_RINGING: - postCallIncoming(); - break; - case TelephonyManager.CALL_STATE_OFFHOOK: - /* for incoming calls we handled at RINGING already, - * if the previous state was IDLE then - * this is an outgoing call - */ - if (last_state == TelephonyManager.CALL_STATE_IDLE) - { /* currently handled the same as incoming calls */ - postCallIncoming(); - } - break; - default: - return; - } - last_state = state; - - } - - @Override - public void onCallStateChanged(int state, String number) - { - super.onCallStateChanged(state, number); - handleState(state); - } - } - private native void postCallIncoming(); - private native void postCallHungUp(); -} diff --git a/android/src/org/rockbox/monitors/BatteryMonitor.java b/android/src/org/rockbox/monitors/BatteryMonitor.java new file mode 100644 index 0000000..0896a58 --- /dev/null +++ b/android/src/org/rockbox/monitors/BatteryMonitor.java @@ -0,0 +1,74 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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.monitors; + +import java.util.Timer; +import java.util.TimerTask; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +public class BatteryMonitor extends BroadcastReceiver +{ + private final IntentFilter mBattFilter; + private final Context mContext; + @SuppressWarnings("unused") + private int mBattLevel; /* read by native code */ + + /* + * We get literally spammed with battery status updates + * Therefore we actually unregister after each onReceive() and + * setup a timer to re-register in 30s */ + public BatteryMonitor(Context c) + { + mBattFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + mContext = c; + Timer t = new Timer(); + TimerTask task = new TimerTask() + { + public void run() + { + attach(); + } + }; + t.schedule(task, 5000, 30000); + attach(); + } + + @Override + public void onReceive(Context arg0, Intent intent) + { + int rawlevel = intent.getIntExtra("level", -1); + int scale = intent.getIntExtra("scale", -1); + if (rawlevel >= 0 && scale > 0) + mBattLevel = (rawlevel * 100) / scale; + else + mBattLevel = -1; + mContext.unregisterReceiver(this); + } + + void attach() + { + mContext.registerReceiver(this, mBattFilter); + } +} diff --git a/android/src/org/rockbox/monitors/HeadphoneMonitor.java b/android/src/org/rockbox/monitors/HeadphoneMonitor.java new file mode 100644 index 0000000..99d2f7a --- /dev/null +++ b/android/src/org/rockbox/monitors/HeadphoneMonitor.java @@ -0,0 +1,60 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 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.monitors; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +public class HeadphoneMonitor extends BroadcastReceiver +{ + @SuppressWarnings("unused") + private int mHpState; /* read by native code */ + + public HeadphoneMonitor(Context c) + { + IntentFilter hpFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG); + /* caution: hidden API; might break */ + IntentFilter noisyFilter = new IntentFilter("android.media.AUDIO_BECOMING_NOISY"); + + c.registerReceiver(this, hpFilter); + c.registerReceiver(new NoisyMonitor(), noisyFilter); + } + + @Override + public void onReceive(Context arg0, Intent intent) + { + int state = intent.getIntExtra("state", -1); + mHpState = state; + } + + /* audio becoming noise acts as headphones extracted */ + private class NoisyMonitor extends BroadcastReceiver + { + @Override + public void onReceive(Context arg0, Intent arg1) + { + mHpState = 0; + } + } +} diff --git a/android/src/org/rockbox/monitors/TelephonyMonitor.java b/android/src/org/rockbox/monitors/TelephonyMonitor.java new file mode 100644 index 0000000..6881f24 --- /dev/null +++ b/android/src/org/rockbox/monitors/TelephonyMonitor.java @@ -0,0 +1,97 @@ +/*************************************************************************** + * __________ __ ___. + * 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.monitors; + +import android.content.Context; +import android.os.Handler; +import android.telephony.PhoneStateListener; +import android.telephony.TelephonyManager; + +public class TelephonyMonitor +{ + public TelephonyMonitor(Context c) + { + final Handler handler = new Handler(c.getMainLooper()); + final TelephonyManager tm = (TelephonyManager) + c.getSystemService(Context.TELEPHONY_SERVICE); + handler.post(new Runnable() + { + @Override + public void run() + { /* need to instantiate from a thread that has a Looper */ + tm.listen(new RockboxCallStateListener(), PhoneStateListener.LISTEN_CALL_STATE); + } + }); + } + + private class RockboxCallStateListener extends PhoneStateListener + { + private int last_state; + + public RockboxCallStateListener() + { + super(); + /* set artificial initial state, + * we will get an initial event shortly after this, + * so to handle it correctly we need an invalid state set */ + last_state = TelephonyManager.CALL_STATE_IDLE - 10; + } + + private void handleState(int state) + { + if (state == last_state) + return; + switch (state) + { + case TelephonyManager.CALL_STATE_IDLE: + postCallHungUp(); + break; + case TelephonyManager.CALL_STATE_RINGING: + postCallIncoming(); + break; + case TelephonyManager.CALL_STATE_OFFHOOK: + /* for incoming calls we handled at RINGING already, + * if the previous state was IDLE then + * this is an outgoing call + */ + if (last_state == TelephonyManager.CALL_STATE_IDLE) + { /* currently handled the same as incoming calls */ + postCallIncoming(); + } + break; + default: + return; + } + last_state = state; + + } + + @Override + public void onCallStateChanged(int state, String number) + { + super.onCallStateChanged(state, number); + handleState(state); + } + } + private native void postCallIncoming(); + private native void postCallHungUp(); +} diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c index dfc5bd0..c913a3d 100644 --- a/firmware/target/hosted/android/button-android.c +++ b/firmware/target/hosted/android/button-android.c @@ -34,7 +34,8 @@ extern JNIEnv *env_ptr; extern jclass RockboxService_class; extern jobject RockboxService_instance; -static jfieldID _headphone_state; +static jobject HeadphoneMonitor_instance; +static jfieldID headphone_state; static int last_y, last_x; static int last_btns; @@ -114,20 +115,18 @@ Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jclass class, void button_init_device(void) { - jmethodID initHeadphoneMonitor = (*env_ptr)->GetMethodID(env_ptr, - RockboxService_class, - "initHeadphoneMonitor", - "()V"); - /* start the monitor */ - (*env_ptr)->CallVoidMethod(env_ptr, - RockboxService_instance, - initHeadphoneMonitor); - - /* cache the headphone state field id */ - _headphone_state = (*env_ptr)->GetFieldID(env_ptr, - RockboxService_class, - "headphone_state", - "I"); + JNIEnv e = *env_ptr; + jclass class = e->FindClass(env_ptr, "org/rockbox/monitors/HeadphoneMonitor"); + jmethodID constructor = e->GetMethodID(env_ptr, class, + "", + "(Landroid/content/Context;)V"); + HeadphoneMonitor_instance = e->NewObject(env_ptr, class, + constructor, + RockboxService_instance); + /* cache the battery level field id */ + headphone_state = (*env_ptr)->GetFieldID(env_ptr, + class, + "mHpState", "I"); } int button_read_device(int *data) @@ -150,7 +149,8 @@ int button_read_device(int *data) /* Tell if anything is in the jack. */ bool headphones_inserted(void) { - int state = (*env_ptr)->GetIntField(env_ptr, RockboxService_instance, _headphone_state); + int state = (*env_ptr)->GetIntField(env_ptr, HeadphoneMonitor_instance, + headphone_state); /* 0 is disconnected, 1 and 2 are connected */ return (state == 0) ? false : true; } diff --git a/firmware/target/hosted/android/powermgmt-android.c b/firmware/target/hosted/android/powermgmt-android.c index d23fece..dcbd7a6 100644 --- a/firmware/target/hosted/android/powermgmt-android.c +++ b/firmware/target/hosted/android/powermgmt-android.c @@ -29,28 +29,28 @@ extern jclass RockboxService_class; extern jobject RockboxService_instance; static jfieldID _battery_level; +static jobject BatteryMonitor_instance; void powermgmt_init_target(void) { - jmethodID initBatteryMonitor = (*env_ptr)->GetMethodID(env_ptr, - RockboxService_class, - "initBatteryMonitor", - "()V"); - /* start the monitor */ - (*env_ptr)->CallVoidMethod(env_ptr, - RockboxService_instance, - initBatteryMonitor); + JNIEnv e = *env_ptr; + jclass class = e->FindClass(env_ptr, "org/rockbox/monitors/BatteryMonitor"); + jmethodID constructor = e->GetMethodID(env_ptr, class, + "", + "(Landroid/content/Context;)V"); + BatteryMonitor_instance = e->NewObject(env_ptr, class, + constructor, + RockboxService_instance); /* cache the battery level field id */ _battery_level = (*env_ptr)->GetFieldID(env_ptr, - RockboxService_class, - "battery_level", - "I"); + class, + "mBattLevel", "I"); } int battery_level(void) { - return (*env_ptr)->GetIntField(env_ptr, RockboxService_instance, _battery_level); + return (*env_ptr)->GetIntField(env_ptr, BatteryMonitor_instance, _battery_level); } int battery_time(void) diff --git a/firmware/target/hosted/android/telephony-android.c b/firmware/target/hosted/android/telephony-android.c index 64ad436..df89a56 100644 --- a/firmware/target/hosted/android/telephony-android.c +++ b/firmware/target/hosted/android/telephony-android.c @@ -30,15 +30,17 @@ extern jobject RockboxService_instance; void telephony_init_device(void) { JNIEnv e = *env_ptr; - jclass class = e->FindClass(env_ptr, "org/rockbox/RockboxTelephony"); - jmethodID constructor = e->GetMethodID(env_ptr, class, "", "(Landroid/content/Context;)V"); - - e->NewObject(env_ptr, class, constructor, RockboxService_instance); + jclass class = e->FindClass(env_ptr, "org/rockbox/monitors/TelephonyMonitor"); + jmethodID constructor = e->GetMethodID(env_ptr, class, + "", + "(Landroid/content/Context;)V"); + e->NewObject(env_ptr, class, + constructor, + RockboxService_instance); } - JNIEXPORT void JNICALL -Java_org_rockbox_RockboxTelephony_postCallIncoming(JNIEnv *env, jobject this) +Java_org_rockbox_monitors_TelephonyMonitor_postCallIncoming(JNIEnv *env, jobject this) { (void)env; (void)this; @@ -46,7 +48,7 @@ Java_org_rockbox_RockboxTelephony_postCallIncoming(JNIEnv *env, jobject this) } JNIEXPORT void JNICALL -Java_org_rockbox_RockboxTelephony_postCallHungUp(JNIEnv *env, jobject this) +Java_org_rockbox_monitors_TelephonyMonitor_postCallHungUp(JNIEnv *env, jobject this) { (void)env; (void)this; -- cgit v1.1