Bug 845080 - Extract BackgroundService superclass. r=rnewman
☠☠ backed out by 80942ec06b47 ☠ ☠
authorChris Peterson <cpeterson@mozilla.com>
Tue, 26 Feb 2013 16:59:19 -0800
changeset 123157 6562cc879c537915cca41dd72668e9bc3075a695
parent 123156 7731263e33fe39665f59687974c9d8f82b757b2f
child 123158 c39c03b6a256d571e6ba8129e12f8925a8d2981c
push id1390
push userMs2ger@gmail.com
push dateThu, 28 Feb 2013 17:40:16 +0000
treeherderfx-team@c65d59d33aa8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs845080
milestone22.0a1
Bug 845080 - Extract BackgroundService superclass. r=rnewman
mobile/android/base/background/BackgroundService.java
mobile/android/base/background/announcements/AnnouncementsBroadcastService.java
mobile/android/base/background/announcements/AnnouncementsService.java
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/background/BackgroundService.java
@@ -0,0 +1,73 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.background;
+
+import org.mozilla.gecko.sync.Logger;
+
+import android.app.AlarmManager;
+import android.app.IntentService;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Build;
+
+public abstract class BackgroundService extends IntentService {
+  private static final String LOG_TAG = BackgroundService.class.getSimpleName();
+
+  protected BackgroundService() {
+    super(LOG_TAG);
+  }
+
+  protected BackgroundService(String threadName) {
+    super(threadName);
+  }
+
+  /**
+   * Returns true if the OS will allow us to perform background
+   * data operations. This logic varies by OS version.
+   */
+  protected boolean backgroundDataIsEnabled() {
+    ConnectivityManager connectivity = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+      return connectivity.getBackgroundDataSetting();
+    }
+    NetworkInfo networkInfo = connectivity.getActiveNetworkInfo();
+    if (networkInfo == null) {
+      return false;
+    }
+    return networkInfo.isAvailable();
+  }
+
+  protected static PendingIntent createPendingIntent(Context context, Class<? extends BroadcastReceiver> broadcastReceiverClass) {
+    final Intent service = new Intent(context, broadcastReceiverClass);
+    return PendingIntent.getBroadcast(context, 0, service, PendingIntent.FLAG_CANCEL_CURRENT);
+  }
+
+  protected AlarmManager getAlarmManager() {
+    return getAlarmManager(this.getApplicationContext());
+  }
+
+  protected static AlarmManager getAlarmManager(Context context) {
+    return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+  }
+
+  protected void scheduleAlarm(long pollInterval, PendingIntent pendingIntent) {
+    Logger.info(LOG_TAG, "Setting inexact repeating alarm for interval " + pollInterval);
+    if (pollInterval <= 0) {
+        throw new IllegalArgumentException("pollInterval " + pollInterval + " must be positive");
+    }
+    final AlarmManager alarm = getAlarmManager();
+    final long firstEvent = System.currentTimeMillis();
+    alarm.setInexactRepeating(AlarmManager.RTC, firstEvent, pollInterval, pendingIntent);
+  }
+
+  protected void cancelAlarm(PendingIntent pendingIntent) {
+    final AlarmManager alarm = getAlarmManager();
+    alarm.cancel(pendingIntent);
+  }
+}
--- a/mobile/android/base/background/announcements/AnnouncementsBroadcastService.java
+++ b/mobile/android/base/background/announcements/AnnouncementsBroadcastService.java
@@ -3,60 +3,52 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.background.announcements;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 import org.mozilla.gecko.background.BackgroundConstants;
+import org.mozilla.gecko.background.BackgroundService;
 import org.mozilla.gecko.sync.GlobalConstants;
 import org.mozilla.gecko.sync.Logger;
 
 import android.app.AlarmManager;
-import android.app.IntentService;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 
 /**
  * A service which listens to broadcast intents from the system and from the
  * browser, registering or unregistering the main
  * {@link AnnouncementsStartReceiver} with the {@link AlarmManager}.
  */
-public class AnnouncementsBroadcastService extends IntentService {
+public class AnnouncementsBroadcastService extends BackgroundService {
   private static final String WORKER_THREAD_NAME = "AnnouncementsBroadcastServiceWorker";
   private static final String LOG_TAG = "AnnounceBrSvc";
 
   public AnnouncementsBroadcastService() {
     super(WORKER_THREAD_NAME);
   }
 
   private void toggleAlarm(final Context context, boolean enabled) {
     Logger.info(LOG_TAG, (enabled ? "R" : "Unr") + "egistering announcements broadcast receiver...");
-    final AlarmManager alarm = getAlarmManager(context);
 
-    final Intent service = new Intent(context, AnnouncementsStartReceiver.class);
-    final PendingIntent pending = PendingIntent.getBroadcast(context, 0, service, PendingIntent.FLAG_CANCEL_CURRENT);
+    final PendingIntent pending = createPendingIntent(context, AnnouncementsStartReceiver.class);
 
     if (!enabled) {
-      alarm.cancel(pending);
+      cancelAlarm(pending);
       return;
     }
 
-    final long firstEvent = System.currentTimeMillis();
     final long pollInterval = getPollInterval(context);
-    Logger.info(LOG_TAG, "Setting inexact repeating alarm for interval " + pollInterval);
-    alarm.setInexactRepeating(AlarmManager.RTC, firstEvent, pollInterval, pending);
-  }
-
-  private static AlarmManager getAlarmManager(Context context) {
-    return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+    scheduleAlarm(pollInterval, pending);
   }
 
   /**
    * Record the last launch time of our version of Fennec.
    *
    * @param context
    *          the <code>Context</code> to use to gain access to
    *          <code>SharedPreferences</code>.
@@ -193,9 +185,9 @@ public class AnnouncementsBroadcastServi
       final SharedPreferences sharedPreferences = this.getSharedPreferences(AnnouncementsConstants.PREFS_BRANCH,
                                                                             BackgroundConstants.SHARED_PREFERENCES_MODE);
       final Editor editor = sharedPreferences.edit();
       editor.remove(AnnouncementsConstants.PREF_LAST_FETCH_LOCAL_TIME);
       editor.remove(AnnouncementsConstants.PREF_EARLIEST_NEXT_ANNOUNCE_FETCH);
       editor.commit();
     }
   }
-}
\ No newline at end of file
+}
--- a/mobile/android/base/background/announcements/AnnouncementsService.java
+++ b/mobile/android/base/background/announcements/AnnouncementsService.java
@@ -6,25 +6,21 @@ package org.mozilla.gecko.background.ann
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.URI;
 import java.util.List;
 import java.util.Locale;
 
 import org.mozilla.gecko.background.BackgroundConstants;
+import org.mozilla.gecko.background.BackgroundService;
 import org.mozilla.gecko.sync.Logger;
 
-import android.app.IntentService;
-import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.Build;
 import android.os.IBinder;
 
 /**
  * A Service to periodically check for new published announcements,
  * presenting them to the user if local conditions permit.
  *
  * We extend IntentService, rather than just Service, because this gives us
  * a worker thread to avoid main-thread networking.
@@ -47,17 +43,17 @@ import android.os.IBinder;
  * 0. Decide if message display should occur. This might involve
  *    user preference or other kinds of environmental factors.
  * 1. Use the AnnouncementPresenter to open the announcement.
  *
  * Future:
  * * Persisting of multiple announcements.
  * * Prioritization.
  */
-public class AnnouncementsService extends IntentService implements AnnouncementsFetchDelegate {
+public class AnnouncementsService extends BackgroundService implements AnnouncementsFetchDelegate {
   private static final String WORKER_THREAD_NAME = "AnnouncementsServiceWorker";
   private static final String LOG_TAG = "AnnounceService";
 
   public AnnouncementsService() {
     super(WORKER_THREAD_NAME);
     Logger.setThreadLogTag(AnnouncementsConstants.GLOBAL_LOG_TAG);
     Logger.debug(LOG_TAG, "Creating AnnouncementsService.");
   }
@@ -136,32 +132,16 @@ public class AnnouncementsService extend
     super.onDestroy();
   }
 
   @Override
   public IBinder onBind(Intent intent) {
     return null;
   }
 
-  /**
-   * Returns true if the OS will allow us to perform background
-   * data operations. This logic varies by OS version.
-   */
-  protected boolean backgroundDataIsEnabled() {
-    ConnectivityManager connectivity = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
-    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
-      return connectivity.getBackgroundDataSetting();
-    }
-    NetworkInfo networkInfo = connectivity.getActiveNetworkInfo();
-    if (networkInfo == null) {
-      return false;
-    }
-    return networkInfo.isAvailable();
-  }
-
   protected long getLastLaunch() {
     return getSharedPreferences().getLong(AnnouncementsConstants.PREF_LAST_LAUNCH, 0);
   }
 
   private SharedPreferences getSharedPreferences() {
     return this.getSharedPreferences(AnnouncementsConstants.PREFS_BRANCH, BackgroundConstants.SHARED_PREFERENCES_MODE);
   }