Merge lp:~karni/ubuntuone-android-files/sync-on-inexact-alarms into lp:ubuntuone-android-files

Proposed by Michał Karnicki
Status: Merged
Approved by: Chad Miller
Approved revision: 48
Merged at revision: 48
Proposed branch: lp:~karni/ubuntuone-android-files/sync-on-inexact-alarms
Merge into: lp:ubuntuone-android-files
Diff against target: 338 lines (+115/-61)
7 files modified
AndroidManifest.xml (+2/-2)
res/values/values.xml (+2/-12)
res/xml/prefs.xml (+2/-3)
src/com/ubuntuone/android/files/Preferences.java (+13/-7)
src/com/ubuntuone/android/files/UbuntuOneFiles.java (+85/-34)
src/com/ubuntuone/android/files/syncdaemon/SyncDaemon.java (+4/-2)
src/com/ubuntuone/android/files/util/DateUtilities.java (+7/-1)
To merge this branch: bzr merge lp:~karni/ubuntuone-android-files/sync-on-inexact-alarms
Reviewer Review Type Date Requested Status
Chad Miller (community) Approve
Review via email: mp+54524@code.launchpad.net

Description of the change

Instead of using custom sync intervals this uses Androids inexact alarms, which are aligned with alarms of other apps, waking up the device less often and possibly saving battery lifetime. The intervals introduced are: 15", 30", 1h, half day, day, and all are inexact alarms with mentioned advantages.

To post a comment you must log in.
Revision history for this message
Chad Miller (cmiller) wrote :

Haven't tested, but this looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'AndroidManifest.xml'
2--- AndroidManifest.xml 2011-03-11 01:48:05 +0000
3+++ AndroidManifest.xml 2011-03-23 13:41:29 +0000
4@@ -2,8 +2,8 @@
5 <manifest
6 xmlns:android="http://schemas.android.com/apk/res/android"
7 package="com.ubuntuone.android.files"
8- android:versionCode="47"
9- android:versionName="1.1.47" >
10+ android:versionCode="48"
11+ android:versionName="1.1.48" >
12
13 <uses-sdk
14 android:minSdkVersion="6"
15
16=== modified file 'res/values/values.xml'
17--- res/values/values.xml 2011-03-08 00:40:29 +0000
18+++ res/values/values.xml 2011-03-23 13:41:29 +0000
19@@ -1,23 +1,13 @@
20 <?xml version="1.0" encoding="utf-8"?>
21 <resources>
22 <string-array name="sync_frequency_entries">
23- <item>5 minutes</item>
24+ <item>15 minutes</item>
25 <item>30 minutes</item>
26 <item>1 hour</item>
27- <item>3 hours</item>
28- <item>6 hours</item>
29+ <item>12 hours</item>
30 <item>daily</item>
31 <item>manual (off)</item>
32 </string-array>
33- <string-array name="sync_frequency_values">
34- <item>5</item>
35- <item>30</item>
36- <item>60</item>
37- <item>180</item>
38- <item>360</item>
39- <item>1440</item>
40- <item>-1</item>
41- </string-array>
42
43 <string-array name="transfer_limit_entries">
44 <item>unlimited</item>
45
46=== modified file 'res/xml/prefs.xml'
47--- res/xml/prefs.xml 2011-03-06 03:36:02 +0000
48+++ res/xml/prefs.xml 2011-03-23 13:41:29 +0000
49@@ -54,11 +54,10 @@
50 <ListPreference
51 android:key="sync_policy_frequency"
52 android:persistent="true"
53- android:defaultValue="60"
54+ android:defaultValue="3600000"
55 android:title="@string/sync_frequency_title"
56 android:summary="@string/sync_frequency_summary"
57- android:entries="@array/sync_frequency_entries"
58- android:entryValues="@array/sync_frequency_values" />
59+ android:entries="@array/sync_frequency_entries" />
60
61 </PreferenceScreen>
62
63
64=== modified file 'src/com/ubuntuone/android/files/Preferences.java'
65--- src/com/ubuntuone/android/files/Preferences.java 2011-03-11 01:48:05 +0000
66+++ src/com/ubuntuone/android/files/Preferences.java 2011-03-23 13:41:29 +0000
67@@ -22,6 +22,7 @@
68
69 package com.ubuntuone.android.files;
70
71+import android.app.AlarmManager;
72 import android.app.AlertDialog;
73 import android.content.Context;
74 import android.content.DialogInterface;
75@@ -209,13 +210,18 @@
76
77 ListPreference syncFrequency =
78 (ListPreference) findPreference(Options.SYNC_POLICY_FREQUENCY);
79+ syncFrequency.setEntryValues(new String[] {
80+ String.valueOf(AlarmManager.INTERVAL_FIFTEEN_MINUTES),
81+ String.valueOf(AlarmManager.INTERVAL_HALF_HOUR),
82+ String.valueOf(AlarmManager.INTERVAL_HOUR),
83+ String.valueOf(AlarmManager.INTERVAL_HALF_DAY),
84+ String.valueOf(AlarmManager.INTERVAL_DAY),
85+ String.valueOf(-1)
86+ });
87 syncFrequency.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
88-
89 public boolean onPreferenceChange(Preference preference, Object newValue) {
90- Log.i(TAG, "periodic sync set to interval: " + newValue.toString());
91- //getString(Preferences.Options.SYNC_POLICY_FREQUENCY, "-1"));
92- UbuntuOneFiles.registerSyncAlarm(getApplicationContext(),
93- Integer.valueOf(newValue.toString()));
94+ UbuntuOneFiles.registerSyncAlarm(getApplicationContext(),
95+ Long.valueOf(newValue.toString()));
96 return true;
97 }
98 });
99@@ -565,8 +571,8 @@
100 editor.commit();
101 }
102
103- public static Integer getSyncInterval() {
104- return Integer.valueOf(Preferences.getString(
105+ public static Long getSyncInterval() {
106+ return Long.valueOf(Preferences.getString(
107 Preferences.Options.SYNC_POLICY_FREQUENCY,
108 String.valueOf(SyncDaemon.SYNC_TRIGGER_INTERVAL_DEFAULT)));
109 }
110
111=== modified file 'src/com/ubuntuone/android/files/UbuntuOneFiles.java'
112--- src/com/ubuntuone/android/files/UbuntuOneFiles.java 2011-03-10 00:00:57 +0000
113+++ src/com/ubuntuone/android/files/UbuntuOneFiles.java 2011-03-23 13:41:29 +0000
114@@ -37,7 +37,6 @@
115 import android.os.Handler;
116 import android.os.Message;
117 import android.os.PowerManager;
118-import android.os.Handler.Callback;
119 import android.os.PowerManager.WakeLock;
120 import android.preference.PreferenceManager;
121
122@@ -48,9 +47,9 @@
123 import com.ubuntuone.android.files.syncdaemon.MsgArgs;
124 import com.ubuntuone.android.files.syncdaemon.QueueManager;
125 import com.ubuntuone.android.files.syncdaemon.SyncDaemon;
126-import com.ubuntuone.android.files.syncdaemon.VolumeManager;
127 import com.ubuntuone.android.files.syncdaemon.states.Node;
128 import com.ubuntuone.android.files.syncdaemon.states.StateManager;
129+import com.ubuntuone.android.files.util.DateUtilities;
130 import com.ubuntuone.android.files.util.Util;
131 import com.ubuntuone.android.files.util.OAuthUtilities.OAuthClient;
132 import com.ubuntuone.android.util.log.Log;
133@@ -66,8 +65,6 @@
134
135 private EventQueue mEventQueue;
136
137- private VolumeManager mVolumeManager;
138-
139 private StateManager mStateManager;
140
141 private Handler mHandler;
142@@ -156,13 +153,13 @@
143
144 // --- event handling ------------------------------------------------------
145
146- Handler.Callback mHandlerCallback = new Callback() {
147+ Handler.Callback mHandlerCallback = new Handler.Callback() {
148 public boolean handleMessage(Message msg) {
149 boolean inForeground = sForegroundActivity != null
150 && sForegroundActivity.get() != null;
151 switch (msg.what) {
152 case R.string.SYS_BOOT_COMPLETED:
153- registerSyncAlarm(sApplicationInstance, 0);
154+ registerSyncAlarm(sApplicationInstance, 0L);
155 sApplicationInstance.releaseLocks();
156 break;
157 case R.string.SYS_HANDSHAKE_TIMEOUT:
158@@ -283,56 +280,110 @@
159 }
160
161 // --- sync alarm ----------------------------------------------------------
162-
163+
164+ /**
165+ * Registers sync alarm if:<br />
166+ * - the tokens are in place<br />
167+ * - sync is not disabled<br />
168+ * - alarm is registered, but needs to be rescheduled
169+ *
170+ * @param context
171+ * the context
172+ * @param reschedule
173+ * true in case an already registered inexact alarm should be
174+ * rescheduled. We use this to further increase battery life and
175+ * limit unnecessary sync requests.
176+ */
177 public static void maybeRegisterSyncAlarm(Context context, boolean reschedule) {
178 if (!hasValidTokens()) {
179- Log.i(TAG, "not registering sync alarm, no tokens");
180- return;
181- }
182-
183- Integer syncInterval = Preferences.getSyncInterval();
184- if (syncInterval == -1) {
185- Log.d(TAG, "sync disabled, not scheduling");
186- return;
187- }
188-
189- // Set up sync intent, and it's pending intent.
190+ Log.w(TAG, "*** not scheduling sync, no tokens ***");
191+ return;
192+ }
193+
194+ Long syncInterval = Preferences.getSyncInterval();
195+ if (syncInterval == -1L) {
196+ Log.i(TAG, "*** not scheduling sync, disabled ***");
197+ return;
198+ }
199+
200+ // Set up sync intent, and it's pending intent (no-create check)
201 Intent syncIntent = new Intent(SyncDaemon.ACTION_SCHEDULED_SYNC);
202 PendingIntent pendingIntent = PendingIntent.getService(context, 0,
203 syncIntent, PendingIntent.FLAG_NO_CREATE);
204
205 if (pendingIntent == null || reschedule) {
206 if (!reschedule)
207- Log.i(TAG, "*** alarm not scheduled, registering ***");
208+ Log.i(TAG, "*** sync not scheduled, registering ***");
209 else
210- Log.i(TAG, "*** re-scheduling alarm ***");
211- registerSyncAlarm(context, 0);
212+ Log.i(TAG, "*** sync already scheduled, re-scheduling ***");
213+ registerSyncAlarm(context, 0L);
214 }
215 }
216-
217- public static void registerSyncAlarm(Context context, Integer syncInterval) {
218- if (syncInterval == 0)
219+
220+ /**
221+ * Cancels any previously registered alarm to sync and registers a new,
222+ * inexact alarm to sync. Inexact alarms are aligned by Android, so this
223+ * should give us some battery life improvement.
224+ *
225+ * Only Preferences -> Sync policy -> Frequency should call this directly.
226+ *
227+ * @param context
228+ * the context
229+ * @param syncInterval
230+ * can be either 0, in which case syncInterval value will be
231+ * pulled from the Preferences, or any of inexact alarm values.
232+ * It can also be -1L, which means sync is turned off.
233+ */
234+ public static void registerSyncAlarm(Context context, Long syncInterval) {
235+ if (syncInterval == 0L)
236 syncInterval = Preferences.getSyncInterval();
237+ long inexactInterval = -1L;
238
239- // Convert to miliseconds, given minutes.
240- Log.d(TAG, "sync interval, minutes: " + syncInterval);
241- syncInterval *= 60*1000;
242+ // Doh! switch does not support cases of type long
243+ if (syncInterval == AlarmManager.INTERVAL_FIFTEEN_MINUTES) {
244+ Log.i(TAG, "sync interval set to fifteen minutes");
245+ inexactInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
246+ syncInterval = DateUtilities.MILLIS_IN_15_MINUTES;
247+ } else if (syncInterval == AlarmManager.INTERVAL_HALF_HOUR) {
248+ Log.i(TAG, "sync interval set to half hour");
249+ inexactInterval = AlarmManager.INTERVAL_HALF_HOUR;
250+ syncInterval = DateUtilities.MILLIS_IN_HALF_HOUR;
251+ } else if (syncInterval == AlarmManager.INTERVAL_HOUR) {
252+ Log.i(TAG, "sync interval set to hour");
253+ inexactInterval = AlarmManager.INTERVAL_HOUR;
254+ syncInterval = DateUtilities.MILLIS_IN_HOUR;
255+ } else if (syncInterval == AlarmManager.INTERVAL_HALF_DAY) {
256+ Log.i(TAG, "sync interval set to half day");
257+ inexactInterval = AlarmManager.INTERVAL_HALF_DAY;
258+ syncInterval = DateUtilities.MILLIS_IN_HALF_DAY;
259+ } else if (syncInterval == AlarmManager.INTERVAL_DAY) {
260+ Log.i(TAG, "sync interval set to day");
261+ inexactInterval = AlarmManager.INTERVAL_DAY;
262+ syncInterval = DateUtilities.MILLIS_IN_DAY;
263+ } else if (syncInterval == -1L) {
264+ Log.i(TAG, "sync interval set to -1 (sync off)");
265+ inexactInterval = syncInterval = -1L;
266+ // We don't return here, since in such case the previous alarm
267+ // should be canceled, which follows.
268+ } else {
269+ Log.e(TAG, "no such sync interval: " + inexactInterval);
270+ return;
271+ }
272
273 // Set up sync intent, and it's pending intent.
274 Intent syncIntent = new Intent(SyncDaemon.ACTION_SCHEDULED_SYNC);
275 PendingIntent pendingIntent = PendingIntent.getService(context, 0,
276 syncIntent, 0);
277
278- // Schedule the sync operation.
279- AlarmManager am = (AlarmManager) context
280+ // Cancel previous alarm and schedule new sync inexact alarm.
281+ final AlarmManager am = (AlarmManager) context
282 .getSystemService(Service.ALARM_SERVICE);
283- // Cancel the previous alarm first.
284 am.cancel(pendingIntent);
285
286- if (syncInterval > 0) {
287- am.setRepeating(AlarmManager.RTC_WAKEUP,
288- System.currentTimeMillis() + syncInterval,
289- syncInterval,
290+ if (syncInterval != -1L) {
291+ am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
292+ System.currentTimeMillis() + syncInterval,
293+ inexactInterval,
294 pendingIntent);
295 }
296 }
297
298=== modified file 'src/com/ubuntuone/android/files/syncdaemon/SyncDaemon.java'
299--- src/com/ubuntuone/android/files/syncdaemon/SyncDaemon.java 2011-03-11 01:15:18 +0000
300+++ src/com/ubuntuone/android/files/syncdaemon/SyncDaemon.java 2011-03-23 13:41:29 +0000
301@@ -25,6 +25,7 @@
302 import java.util.Arrays;
303 import java.util.Map;
304
305+import android.app.AlarmManager;
306 import android.app.Notification;
307 import android.app.NotificationManager;
308 import android.app.PendingIntent;
309@@ -89,8 +90,9 @@
310
311 private final int IDLE_TIMEOUT_MS = 90*1000; // miliseconds
312
313- /** Unused, this *should* pull a defaultValue from prefs, in minutes. */
314- public final static long SYNC_TRIGGER_INTERVAL_DEFAULT = 30;
315+ /** Unused, this *should* pull a defaultValue from prefs. */
316+ public final static long SYNC_TRIGGER_INTERVAL_DEFAULT =
317+ AlarmManager.INTERVAL_HOUR;
318
319
320 /**
321
322=== modified file 'src/com/ubuntuone/android/files/util/DateUtilities.java'
323--- src/com/ubuntuone/android/files/util/DateUtilities.java 2010-12-21 16:16:54 +0000
324+++ src/com/ubuntuone/android/files/util/DateUtilities.java 2011-03-23 13:41:29 +0000
325@@ -33,7 +33,13 @@
326 */
327 public class DateUtilities {
328
329- private static int MILLIS_IN_SECOND = 1000;
330+ public static final Long MILLIS_IN_SECOND = 1000L;
331+ public static final Long MILLIS_IN_MINUTE = 60*MILLIS_IN_SECOND;
332+ public static final Long MILLIS_IN_15_MINUTES = 15*MILLIS_IN_MINUTE;
333+ public static final Long MILLIS_IN_HALF_HOUR = 2*MILLIS_IN_15_MINUTES;
334+ public static final Long MILLIS_IN_HOUR = 2*MILLIS_IN_HALF_HOUR;
335+ public static final Long MILLIS_IN_HALF_DAY = 12*MILLIS_IN_HOUR;
336+ public static final Long MILLIS_IN_DAY = 2*MILLIS_IN_HALF_DAY;
337
338 private static Format dateFormatter = new SimpleDateFormat("MMM dd");
339

Subscribers

People subscribed via source and target branches

to status/vote changes: