Bug 1241810 - Add SetupAction for setting up various alarms to start FeedService. r=mcomella draft
authorSebastian Kaspari <s.kaspari@gmail.com>
Wed, 24 Feb 2016 15:29:01 -0800
changeset 343931 3fa62d56c34af3ffcc24e67f31ab3f71a5412384
parent 343930 eb197ba31b16ad1a1319d3a6978176bd6326c35a
child 343932 1dbd295f975eff15ba374de793c4d13e6203bcb1
push id13713
push users.kaspari@gmail.com
push dateWed, 23 Mar 2016 15:10:41 +0000
reviewersmcomella
bugs1241810
milestone48.0a1
Bug 1241810 - Add SetupAction for setting up various alarms to start FeedService. r=mcomella MozReview-Commit-ID: GT6pLuUUEyY
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/java/org/mozilla/gecko/feeds/FeedAlarmReceiver.java
mobile/android/base/java/org/mozilla/gecko/feeds/FeedService.java
mobile/android/base/java/org/mozilla/gecko/feeds/action/SetupAction.java
mobile/android/base/moz.build
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -353,16 +353,20 @@
             android:name="org.mozilla.gecko.dlc.DownloadContentService">
         </service>
 
         <service
             android:exported="false"
             android:name="org.mozilla.gecko.feeds.FeedService">
         </service>
 
+        <receiver
+            android:name="org.mozilla.gecko.feeds.FeedAlarmReceiver"
+            android:exported="false" />
+
         <service
           android:name="org.mozilla.gecko.telemetry.TelemetryUploadService"
           android:exported="false"/>
 
 #include ../services/manifests/FxAccountAndroidManifest_services.xml.in
 
         <service
             android:name="org.mozilla.gecko.tabqueue.TabReceivedService"
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/FeedAlarmReceiver.java
@@ -0,0 +1,31 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * 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.feeds;
+
+import android.content.Context;
+import android.content.Intent;
+import android.support.v4.content.WakefulBroadcastReceiver;
+import android.util.Log;
+
+/**
+ * Broadcast receiver that will receive broadcasts from the AlarmManager and start the FeedService
+ * with the given action.
+ */
+public class FeedAlarmReceiver extends WakefulBroadcastReceiver {
+    private static final String LOGTAG = "FeedCheckAction";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final String action = intent.getAction();
+
+        Log.d(LOGTAG, "Received alarm with action: " + action);
+
+        final Intent serviceIntent = new Intent(context, FeedService.class);
+        serviceIntent.setAction(action);
+
+        startWakefulService(context, serviceIntent);
+    }
+}
--- a/mobile/android/base/java/org/mozilla/gecko/feeds/FeedService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/FeedService.java
@@ -10,27 +10,29 @@ import android.content.Context;
 import android.content.Intent;
 import android.util.Log;
 
 import com.keepsafe.switchboard.SwitchBoard;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.feeds.action.CheckAction;
 import org.mozilla.gecko.feeds.action.EnrollAction;
+import org.mozilla.gecko.feeds.action.SetupAction;
 import org.mozilla.gecko.feeds.action.SubscribeAction;
 import org.mozilla.gecko.feeds.action.WithdrawAction;
 import org.mozilla.gecko.feeds.subscriptions.SubscriptionStorage;
 import org.mozilla.gecko.util.Experiments;
 
 /**
  * Background service for subscribing to and checking website feeds to notify the user about updates.
  */
 public class FeedService extends IntentService {
     private static final String LOGTAG = "GeckoFeedService";
 
+    public static final String ACTION_SETUP = AppConstants.ANDROID_PACKAGE_NAME + ".FEEDS.SETUP";
     public static final String ACTION_SUBSCRIBE = AppConstants.ANDROID_PACKAGE_NAME + ".FEEDS.SUBSCRIBE";
     public static final String ACTION_CHECK = AppConstants.ANDROID_PACKAGE_NAME + ".FEEDS.CHECK";
     public static final String ACTION_ENROLL = AppConstants.ANDROID_PACKAGE_NAME + ".FEEDS.ENROLL";
     public static final String ACTION_WITHDRAW = AppConstants.ANDROID_PACKAGE_NAME + ".FEEDS.WITHDRAW";
 
     public static void subscribe(Context context, String guid, String feedUrl) {
         Intent intent = new Intent(context, FeedService.class);
         intent.setAction(ACTION_SUBSCRIBE);
@@ -59,16 +61,20 @@ public class FeedService extends IntentS
         }
 
         if (!SwitchBoard.isInExperiment(this, Experiments.CONTENT_NOTIFICATIONS)) {
             Log.d(LOGTAG, "Not in content notifications experiment. Skipping.");
             return;
         }
 
         switch (intent.getAction()) {
+            case ACTION_SETUP:
+                new SetupAction(this).perform();
+                break;
+
             case ACTION_SUBSCRIBE:
                 new SubscribeAction(storage).perform(intent);
                 break;
 
             case ACTION_CHECK:
                 new CheckAction(this, storage).perform();
                 break;
 
@@ -80,10 +86,12 @@ public class FeedService extends IntentS
                 new WithdrawAction(this, storage).perform();
                 break;
 
             default:
                 Log.e(LOGTAG, "Unknown action: " + intent.getAction());
         }
 
         storage.persistChanges();
+
+        FeedAlarmReceiver.completeWakefulIntent(intent);
     }
 }
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/action/SetupAction.java
@@ -0,0 +1,91 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * 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.feeds.action;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.util.Log;
+
+import org.mozilla.gecko.feeds.FeedAlarmReceiver;
+import org.mozilla.gecko.feeds.FeedService;
+
+/**
+ * SetupAction: Set up alarms to run various actions every now and then.
+ */
+public class SetupAction {
+    private static final String LOGTAG = "FeedSetupAction";
+
+    private Context context;
+
+    public SetupAction(Context context) {
+        this.context = context;
+    }
+
+    public void perform() {
+        final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+        cancelPreviousAlarms(alarmManager);
+        scheduleAlarms(alarmManager);
+    }
+
+    private void cancelPreviousAlarms(AlarmManager alarmManager) {
+        final PendingIntent withdrawIntent = getWithdrawPendingIntent();
+        alarmManager.cancel(withdrawIntent);
+
+        final PendingIntent enrollIntent = getEnrollPendingIntent();
+        alarmManager.cancel(enrollIntent);
+
+        final PendingIntent checkIntent = getCheckPendingIntent();
+        alarmManager.cancel(checkIntent);
+
+        Log.d(LOGTAG, "Cancelled previous alarms");
+    }
+
+    private void scheduleAlarms(AlarmManager alarmManager) {
+        alarmManager.setInexactRepeating(
+                AlarmManager.ELAPSED_REALTIME,
+                SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_FIFTEEN_MINUTES,
+                AlarmManager.INTERVAL_DAY,
+                getWithdrawPendingIntent());
+
+        alarmManager.setInexactRepeating(
+                AlarmManager.ELAPSED_REALTIME,
+                SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
+                AlarmManager.INTERVAL_DAY,
+                getEnrollPendingIntent()
+        );
+
+        alarmManager.setInexactRepeating(
+                AlarmManager.ELAPSED_REALTIME,
+                SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HOUR,
+                AlarmManager.INTERVAL_HALF_DAY,
+                getCheckPendingIntent()
+        );
+
+        Log.d(LOGTAG, "Scheduled alarms");
+    }
+
+    private PendingIntent getWithdrawPendingIntent() {
+        Intent intent = new Intent(context, FeedAlarmReceiver.class);
+        intent.setAction(FeedService.ACTION_WITHDRAW);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    private PendingIntent getEnrollPendingIntent() {
+        Intent intent = new Intent(context, FeedAlarmReceiver.class);
+        intent.setAction(FeedService.ACTION_ENROLL);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    private PendingIntent getCheckPendingIntent() {
+        Intent intent = new Intent(context, FeedAlarmReceiver.class);
+        intent.setAction(FeedService.ACTION_CHECK);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -270,18 +270,20 @@ gbjar.sources += ['java/org/mozilla/geck
     'favicons/decoders/IconDirectoryEntry.java',
     'favicons/decoders/LoadFaviconResult.java',
     'favicons/Favicons.java',
     'favicons/LoadFaviconTask.java',
     'favicons/OnFaviconLoadedListener.java',
     'favicons/RemoteFavicon.java',
     'feeds/action/CheckAction.java',
     'feeds/action/EnrollAction.java',
+    'feeds/action/SetupAction.java',
     'feeds/action/SubscribeAction.java',
     'feeds/action/WithdrawAction.java',
+    'feeds/FeedAlarmReceiver.java',
     'feeds/FeedFetcher.java',
     'feeds/FeedService.java',
     'feeds/knownsites/KnownSite.java',
     'feeds/knownsites/KnownSiteBlogger.java',
     'feeds/knownsites/KnownSiteMedium.java',
     'feeds/parser/Feed.java',
     'feeds/parser/Item.java',
     'feeds/parser/SimpleFeedParser.java',