diff options
author | Thomas Martitz <kugel@rockbox.org> | 2010-11-12 21:04:13 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2010-11-12 21:04:13 +0000 |
commit | 0cf2cc1607a0844e906042173815451cd9c2ff58 (patch) | |
tree | 77c555919d5c08f9a54f2b28cababe1d2d207f7e /android | |
parent | bb56bc4ba08bf6c6458a289ef4918dfaea30b238 (diff) | |
download | rockbox-0cf2cc1607a0844e906042173815451cd9c2ff58.tar.gz rockbox-0cf2cc1607a0844e906042173815451cd9c2ff58.zip |
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
Diffstat (limited to 'android')
-rw-r--r-- | android/AndroidManifest.xml | 3 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxTelephony.java | 97 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxTimer.java | 35 |
3 files changed, 103 insertions, 32 deletions
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 @@ | |||
29 | </intent-filter> | 29 | </intent-filter> |
30 | </receiver> | 30 | </receiver> |
31 | 31 | ||
32 | |||
32 | </application> | 33 | </application> |
33 | 34 | ||
34 | <uses-sdk android:minSdkVersion="4" /> | 35 | <uses-sdk android:minSdkVersion="4" /> |
35 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> | 36 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> |
36 | 37 | <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> | |
37 | </manifest> | 38 | </manifest> |
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | package org.rockbox; | ||
23 | |||
24 | import android.content.Context; | ||
25 | import android.os.Handler; | ||
26 | import android.telephony.PhoneStateListener; | ||
27 | import android.telephony.TelephonyManager; | ||
28 | |||
29 | public class RockboxTelephony | ||
30 | { | ||
31 | public RockboxTelephony(Context c) | ||
32 | { | ||
33 | final Handler handler = new Handler(c.getMainLooper()); | ||
34 | final TelephonyManager tm = (TelephonyManager) | ||
35 | c.getSystemService(Context.TELEPHONY_SERVICE); | ||
36 | handler.post(new Runnable() | ||
37 | { | ||
38 | @Override | ||
39 | public void run() | ||
40 | { /* need to instantiate from a thread that has a Looper */ | ||
41 | tm.listen(new RockboxCallStateListener(), PhoneStateListener.LISTEN_CALL_STATE); | ||
42 | } | ||
43 | }); | ||
44 | } | ||
45 | |||
46 | private class RockboxCallStateListener extends PhoneStateListener | ||
47 | { | ||
48 | private int last_state; | ||
49 | |||
50 | public RockboxCallStateListener() | ||
51 | { | ||
52 | super(); | ||
53 | /* set artificial initial state, | ||
54 | * we will get an initial event shortly after this, | ||
55 | * so to handle it correctly we need an invalid state set */ | ||
56 | last_state = TelephonyManager.CALL_STATE_IDLE - 10; | ||
57 | } | ||
58 | |||
59 | private void handleState(int state) | ||
60 | { | ||
61 | if (state == last_state) | ||
62 | return; | ||
63 | switch (state) | ||
64 | { | ||
65 | case TelephonyManager.CALL_STATE_IDLE: | ||
66 | postCallHungUp(); | ||
67 | break; | ||
68 | case TelephonyManager.CALL_STATE_RINGING: | ||
69 | postCallIncoming(); | ||
70 | break; | ||
71 | case TelephonyManager.CALL_STATE_OFFHOOK: | ||
72 | /* for incoming calls we handled at RINGING already, | ||
73 | * if the previous state was IDLE then | ||
74 | * this is an outgoing call | ||
75 | */ | ||
76 | if (last_state == TelephonyManager.CALL_STATE_IDLE) | ||
77 | { /* currently handled the same as incoming calls */ | ||
78 | postCallIncoming(); | ||
79 | } | ||
80 | break; | ||
81 | default: | ||
82 | return; | ||
83 | } | ||
84 | last_state = state; | ||
85 | |||
86 | } | ||
87 | |||
88 | @Override | ||
89 | public void onCallStateChanged(int state, String number) | ||
90 | { | ||
91 | super.onCallStateChanged(state, number); | ||
92 | handleState(state); | ||
93 | } | ||
94 | } | ||
95 | private native void postCallIncoming(); | ||
96 | private native void postCallHungUp(); | ||
97 | } | ||
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; | |||
25 | import java.util.TimerTask; | 25 | import java.util.TimerTask; |
26 | 26 | ||
27 | import android.content.Context; | 27 | import android.content.Context; |
28 | import android.telephony.TelephonyManager; | ||
29 | import android.util.Log; | 28 | import android.util.Log; |
30 | 29 | ||
31 | public class RockboxTimer extends Timer | 30 | public class RockboxTimer extends Timer |
32 | { | 31 | { |
33 | RockboxTimerTask task; | ||
34 | long interval; | ||
35 | |||
36 | private class RockboxTimerTask extends TimerTask { | 32 | private class RockboxTimerTask extends TimerTask { |
37 | private RockboxTimer timer; | 33 | private RockboxTimer timer; |
38 | private TelephonyManager tm; | 34 | public RockboxTimerTask(RockboxTimer parent) |
39 | private int last_state; | ||
40 | public RockboxTimerTask(RockboxService s, RockboxTimer parent) | ||
41 | { | 35 | { |
42 | super(); | 36 | super(); |
43 | timer = parent; | 37 | timer = parent; |
44 | tm = (TelephonyManager)s.getSystemService(Context.TELEPHONY_SERVICE); | ||
45 | last_state = tm.getCallState(); | ||
46 | } | 38 | } |
47 | 39 | ||
48 | @Override | 40 | @Override |
49 | public void run() | 41 | public void run() |
50 | { | 42 | { |
51 | timerTask(); | 43 | timerTask(); |
52 | int state = tm.getCallState(); | ||
53 | if (state != last_state) | ||
54 | { | ||
55 | switch (state) | ||
56 | { | ||
57 | case TelephonyManager.CALL_STATE_IDLE: | ||
58 | postCallHungUp(); | ||
59 | break; | ||
60 | case TelephonyManager.CALL_STATE_RINGING: | ||
61 | postCallIncoming(); | ||
62 | default: | ||
63 | break; | ||
64 | } | ||
65 | last_state = state; | ||
66 | } | ||
67 | synchronized(timer) { | 44 | synchronized(timer) { |
68 | timer.notify(); | 45 | timer.notify(); |
69 | } | 46 | } |
70 | } | 47 | } |
71 | } | 48 | } |
72 | 49 | ||
73 | public RockboxTimer(RockboxService instance, long period_inverval_in_ms) | 50 | public RockboxTimer(Context c, long period_inverval_in_ms) |
74 | { | 51 | { |
75 | super("tick timer"); | 52 | super("tick timer"); |
76 | task = new RockboxTimerTask(instance, this); | 53 | schedule(new RockboxTimerTask(this), 0, period_inverval_in_ms); |
77 | schedule(task, 0, period_inverval_in_ms); | ||
78 | interval = period_inverval_in_ms; | ||
79 | } | 54 | } |
80 | 55 | ||
81 | @SuppressWarnings("unused") | 56 | @SuppressWarnings("unused") |
@@ -98,6 +73,4 @@ public class RockboxTimer extends Timer | |||
98 | } | 73 | } |
99 | } | 74 | } |
100 | public native void timerTask(); | 75 | public native void timerTask(); |
101 | private native void postCallIncoming(); | ||
102 | private native void postCallHungUp(); | ||
103 | } | 76 | } |