summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2011-03-11 15:45:38 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2011-03-11 15:45:38 +0000
commitcae7560f32aa1067479580bf5abbfb3930a2a06b (patch)
tree961ff0bfae1a70c50ba1cb2ba46fc51057ea186f
parent436411126739121244facf511ad2b4bdb0a697fd (diff)
downloadrockbox-cae7560f32aa1067479580bf5abbfb3930a2a06b.tar.gz
rockbox-cae7560f32aa1067479580bf5abbfb3930a2a06b.zip
Android: future-proof the RunForegroundManager code to Honeycomb
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29562 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--android/src/org/rockbox/Helper/RunForegroundManager.java149
1 files changed, 62 insertions, 87 deletions
diff --git a/android/src/org/rockbox/Helper/RunForegroundManager.java b/android/src/org/rockbox/Helper/RunForegroundManager.java
index 6ecb16a408..67e1ef4f8f 100644
--- a/android/src/org/rockbox/Helper/RunForegroundManager.java
+++ b/android/src/org/rockbox/Helper/RunForegroundManager.java
@@ -16,12 +16,8 @@ import android.widget.RemoteViews;
16 16
17public class RunForegroundManager 17public class RunForegroundManager
18{ 18{
19 /* all below is heavily based on the examples found on
20 * http://developer.android.com/reference/android/app/Service.html#setForeground(boolean)
21 */
22 private Notification mNotification; 19 private Notification mNotification;
23 private NotificationManager mNM; 20 private NotificationManager mNM;
24 private IRunForeground api;
25 private Service mCurrentService; 21 private Service mCurrentService;
26 private Intent mWidgetUpdate; 22 private Intent mWidgetUpdate;
27 23
@@ -42,12 +38,7 @@ public class RunForegroundManager
42 mNotification.flags |= Notification.FLAG_ONGOING_EVENT; 38 mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
43 mNotification.contentIntent = PendingIntent.getActivity(service, 0, intent, 0); 39 mNotification.contentIntent = PendingIntent.getActivity(service, 0, intent, 0);
44 40
45 try { 41 initForegroundCompat();
46 api = new newForegroundApi(R.string.notification, mNotification);
47 } catch (NoSuchMethodException e) {
48 /* Fall back on the old API */
49 api = new oldForegroundApi();
50 }
51 } 42 }
52 43
53 private void LOG(CharSequence text) 44 private void LOG(CharSequence text)
@@ -62,27 +53,12 @@ public class RunForegroundManager
62 53
63 public void startForeground() 54 public void startForeground()
64 { 55 {
65 /* 56 startForegroundCompat(R.string.notification, mNotification);
66 * Send the notification.
67 * We use a layout id because it is a unique number.
68 * We use it later to cancel.
69 */
70 mNM.notify(R.string.notification, mNotification);
71 /*
72 * this call makes the service run as foreground, which
73 * provides enough cpu time to do music decoding in the
74 * background
75 */
76 api.startForeground();
77 } 57 }
78 58
79 public void stopForeground() 59 public void stopForeground()
80 { 60 {
81 /* Note to cancel BEFORE changing the 61 stopForegroundCompat(R.string.notification);
82 * foreground state, since we could be killed at that point.
83 */
84 mNM.cancel(R.string.notification);
85 api.stopForeground();
86 mWidgetUpdate = null; 62 mWidgetUpdate = null;
87 } 63 }
88 64
@@ -118,74 +94,73 @@ public class RunForegroundManager
118 mCurrentService.sendBroadcast(widgetUpdate); 94 mCurrentService.sendBroadcast(widgetUpdate);
119 } 95 }
120 96
121 private interface IRunForeground 97 /* Loosely based on http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification) */
122 { 98 private static final Class<?>[] mSetForegroundSignature = new Class[] {boolean.class};
123 void startForeground(); 99 private static final Class<?>[] mStartForegroundSignature = new Class[] {int.class, Notification.class};
124 void stopForeground(); 100 private static final Class<?>[] mStopForegroundSignature = new Class[] {boolean.class};
125 }
126 101
127 private class newForegroundApi implements IRunForeground 102 private Method mSetForeground;
128 { 103 private Method mStartForeground;
129 Class<?>[] mStartForegroundSignature = 104 private Method mStopForeground;
130 new Class[] { int.class, Notification.class };
131 Class<?>[] mStopForegroundSignature =
132 new Class[] { boolean.class };
133 private Method mStartForeground;
134 private Method mStopForeground;
135 private Object[] mStartForegroundArgs = new Object[2];
136 private Object[] mStopForegroundArgs = new Object[1];
137
138 newForegroundApi(int id, Notification notification)
139 throws SecurityException, NoSuchMethodException
140 {
141 /*
142 * Get the new API through reflection
143 */
144 mStartForeground = Service.class.getMethod("startForeground",
145 mStartForegroundSignature);
146 mStopForeground = Service.class.getMethod("stopForeground",
147 mStopForegroundSignature);
148 mStartForegroundArgs[0] = id;
149 mStartForegroundArgs[1] = notification;
150 mStopForegroundArgs[0] = Boolean.TRUE;
151 }
152 105
153 public void startForeground() 106 private void initForegroundCompat() {
154 { 107 Class<?> serviceClass = mCurrentService.getClass();
108 try {
109 mStartForeground = serviceClass.getMethod("startForeground", mStartForegroundSignature);
110 mStopForeground = serviceClass.getMethod("stopForeground", mStopForegroundSignature);
111 } catch (NoSuchMethodException e) {
112 // Running on an older platform.
113 mStartForeground = mStopForeground = null;
155 try { 114 try {
156 mStartForeground.invoke(mCurrentService, mStartForegroundArgs); 115 mSetForeground = serviceClass.getMethod("setForeground", mSetForegroundSignature);
157 } catch (InvocationTargetException e) { 116 } catch (NoSuchMethodException e2) {
158 /* Should not happen. */ 117 throw new IllegalStateException("OS doesn't have Service.startForeground nor Service.setForeground!", e2);
159 LOG("Unable to invoke startForeground", e);
160 } catch (IllegalAccessException e) {
161 /* Should not happen. */
162 LOG("Unable to invoke startForeground", e);
163 } 118 }
164 } 119 }
120 }
165 121
166 public void stopForeground() 122 private void invokeMethod(Method method, Object[] args) {
167 { 123 try {
168 try { 124 method.invoke(mCurrentService, args);
169 mStopForeground.invoke(mCurrentService, mStopForegroundArgs); 125 } catch (Exception e) {
170 } catch (InvocationTargetException e) { 126 // Should not happen.
171 /* Should not happen. */ 127 Log.w("Rockbox", "Unable to invoke method", e);
172 LOG("Unable to invoke stopForeground", e);
173 } catch (IllegalAccessException e) {
174 /* Should not happen. */
175 LOG("Unable to invoke stopForeground", e);
176 }
177 } 128 }
178 } 129 }
179 130
180 private class oldForegroundApi implements IRunForeground 131 /**
181 { 132 * This is a wrapper around the new startForeground method, using the older
182 public void startForeground() 133 * APIs if it is not available.
183 { 134 */
184 mCurrentService.setForeground(false); 135 private void startForegroundCompat(int id, Notification notification) {
136 // If we have the new startForeground API, then use it.
137 if (mStartForeground != null) {
138 Object[] startForeGroundArgs = new Object[] {Integer.valueOf(id), notification};
139 invokeMethod(mStartForeground, startForeGroundArgs);
140 } else {
141 // Fall back on the old API.
142 Object[] setForegroundArgs = new Object[] {Boolean.TRUE};
143 invokeMethod(mSetForeground, setForegroundArgs);
144 mNM.notify(id, notification);
145 }
146 }
147
148 /**
149 * This is a wrapper around the new stopForeground method, using the older
150 * APIs if it is not available.
151 */
152 private void stopForegroundCompat(int id) {
153 // If we have the new stopForeground API, then use it.
154 if (mStopForeground != null) {
155 Object[] stopForegroundArgs = new Object[] {Boolean.TRUE};
156 invokeMethod(mStopForeground, stopForegroundArgs);
157 } else {
158 // Fall back on the old API. Note to cancel BEFORE changing the
159 // foreground state, since we could be killed at that point.
160 mNM.cancel(id);
161
162 Object[] setForegroundArgs = new Object[] {Boolean.FALSE};
163 invokeMethod(mSetForeground, setForegroundArgs);
185 } 164 }
186 public void stopForeground()
187 {
188 mCurrentService.setForeground(false);
189 }
190 } 165 }
191} 166}