From 0cf2cc1607a0844e906042173815451cd9c2ff58 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Fri, 12 Nov 2010 21:04:13 +0000 Subject: Android: Change how detecting call state (introduced in r27746) works, from polling to event based. * For some reason, the polling methid is much more inefficient than I thought. According to htop it caused up to 15% CPU load on some phones (e.g. Galaxy S). The event based causes no CPU load. Rockbox' idle CPU load is now back to 0%, while it was previously dominated by polling the call state. * Also stop on outgoing calls (no need to explicitely pause for making a call anymore). * Factor out the detection mechanism to separate files. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28564 a1c6a512-1295-4272-9138-f99709370657 --- android/AndroidManifest.xml | 3 +- android/src/org/rockbox/RockboxTelephony.java | 97 +++++++++++++++++++++++++++ android/src/org/rockbox/RockboxTimer.java | 35 ++-------- 3 files changed, 103 insertions(+), 32 deletions(-) create mode 100644 android/src/org/rockbox/RockboxTelephony.java (limited to 'android') diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index e0fc106ca7..0eab90ff81 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -29,9 +29,10 @@ + - + diff --git a/android/src/org/rockbox/RockboxTelephony.java b/android/src/org/rockbox/RockboxTelephony.java new file mode 100644 index 0000000000..faaf0c36b7 --- /dev/null +++ b/android/src/org/rockbox/RockboxTelephony.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; + +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/RockboxTimer.java b/android/src/org/rockbox/RockboxTimer.java index 776902e45e..ff48b3f53a 100644 --- a/android/src/org/rockbox/RockboxTimer.java +++ b/android/src/org/rockbox/RockboxTimer.java @@ -25,57 +25,32 @@ import java.util.Timer; import java.util.TimerTask; import android.content.Context; -import android.telephony.TelephonyManager; import android.util.Log; public class RockboxTimer extends Timer -{ - RockboxTimerTask task; - long interval; - +{ private class RockboxTimerTask extends TimerTask { private RockboxTimer timer; - private TelephonyManager tm; - private int last_state; - public RockboxTimerTask(RockboxService s, RockboxTimer parent) + public RockboxTimerTask(RockboxTimer parent) { super(); timer = parent; - tm = (TelephonyManager)s.getSystemService(Context.TELEPHONY_SERVICE); - last_state = tm.getCallState(); } @Override public void run() { timerTask(); - int state = tm.getCallState(); - if (state != last_state) - { - switch (state) - { - case TelephonyManager.CALL_STATE_IDLE: - postCallHungUp(); - break; - case TelephonyManager.CALL_STATE_RINGING: - postCallIncoming(); - default: - break; - } - last_state = state; - } synchronized(timer) { timer.notify(); } } } - public RockboxTimer(RockboxService instance, long period_inverval_in_ms) + public RockboxTimer(Context c, long period_inverval_in_ms) { super("tick timer"); - task = new RockboxTimerTask(instance, this); - schedule(task, 0, period_inverval_in_ms); - interval = period_inverval_in_ms; + schedule(new RockboxTimerTask(this), 0, period_inverval_in_ms); } @SuppressWarnings("unused") @@ -98,6 +73,4 @@ public class RockboxTimer extends Timer } } public native void timerTask(); - private native void postCallIncoming(); - private native void postCallHungUp(); } -- cgit v1.2.3