mobile/android/base/background/BackgroundService.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.background;
michael@0 6
michael@0 7 import java.lang.reflect.InvocationTargetException;
michael@0 8 import java.lang.reflect.Method;
michael@0 9
michael@0 10 import org.mozilla.gecko.background.common.log.Logger;
michael@0 11
michael@0 12 import android.app.AlarmManager;
michael@0 13 import android.app.IntentService;
michael@0 14 import android.app.PendingIntent;
michael@0 15 import android.content.Context;
michael@0 16 import android.content.Intent;
michael@0 17 import android.net.ConnectivityManager;
michael@0 18 import android.net.NetworkInfo;
michael@0 19 import android.os.Build;
michael@0 20
michael@0 21 public abstract class BackgroundService extends IntentService {
michael@0 22 private static final String LOG_TAG = BackgroundService.class.getSimpleName();
michael@0 23
michael@0 24 protected BackgroundService() {
michael@0 25 super(LOG_TAG);
michael@0 26 }
michael@0 27
michael@0 28 protected BackgroundService(String threadName) {
michael@0 29 super(threadName);
michael@0 30 }
michael@0 31
michael@0 32 public static void runIntentInService(Context context, Intent intent, Class<? extends BackgroundService> serviceClass) {
michael@0 33 Intent service = new Intent(context, serviceClass);
michael@0 34 service.setAction(intent.getAction());
michael@0 35 service.putExtras(intent);
michael@0 36 context.startService(service);
michael@0 37 }
michael@0 38
michael@0 39 /**
michael@0 40 * Returns true if the OS will allow us to perform background
michael@0 41 * data operations. This logic varies by OS version.
michael@0 42 */
michael@0 43 @SuppressWarnings("deprecation")
michael@0 44 protected boolean backgroundDataIsEnabled() {
michael@0 45 ConnectivityManager connectivity = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
michael@0 46 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
michael@0 47 return connectivity.getBackgroundDataSetting();
michael@0 48 }
michael@0 49 NetworkInfo networkInfo = connectivity.getActiveNetworkInfo();
michael@0 50 if (networkInfo == null) {
michael@0 51 return false;
michael@0 52 }
michael@0 53 return networkInfo.isAvailable();
michael@0 54 }
michael@0 55
michael@0 56 protected AlarmManager getAlarmManager() {
michael@0 57 return getAlarmManager(this.getApplicationContext());
michael@0 58 }
michael@0 59
michael@0 60 protected static AlarmManager getAlarmManager(Context context) {
michael@0 61 return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
michael@0 62 }
michael@0 63
michael@0 64 protected void scheduleAlarm(long pollInterval, PendingIntent pendingIntent) {
michael@0 65 Logger.info(LOG_TAG, "Setting inexact repeating alarm for interval " + pollInterval);
michael@0 66 if (pollInterval <= 0) {
michael@0 67 throw new IllegalArgumentException("pollInterval " + pollInterval + " must be positive");
michael@0 68 }
michael@0 69 final AlarmManager alarm = getAlarmManager();
michael@0 70 final long firstEvent = System.currentTimeMillis();
michael@0 71 alarm.setInexactRepeating(AlarmManager.RTC, firstEvent, pollInterval, pendingIntent);
michael@0 72 }
michael@0 73
michael@0 74 protected void cancelAlarm(PendingIntent pendingIntent) {
michael@0 75 final AlarmManager alarm = getAlarmManager();
michael@0 76 alarm.cancel(pendingIntent);
michael@0 77 // For testing - allows us to see if the intent, and thus the alarm, has been cancelled.
michael@0 78 pendingIntent.cancel();
michael@0 79 }
michael@0 80
michael@0 81 /**
michael@0 82 * To avoid tight coupling to Fennec, we use reflection to find
michael@0 83 * <code>GeckoPreferences</code>, invoking the same code path that
michael@0 84 * <code>GeckoApp</code> uses on startup to send the <i>other</i>
michael@0 85 * notification to which we listen.
michael@0 86 *
michael@0 87 * Invoke this to handle one of the system intents to which we listen to
michael@0 88 * launch our service without the browser being opened.
michael@0 89 *
michael@0 90 * All of this is neatly wrapped in <code>try…catch</code>, so this code
michael@0 91 * will run safely without a Firefox build installed.
michael@0 92 */
michael@0 93 protected static void reflectContextToFennec(Context context, String className, String methodName) {
michael@0 94 // Ask the browser to tell us the current state of the preference.
michael@0 95 try {
michael@0 96 Class<?> geckoPreferences = Class.forName(className);
michael@0 97 Method broadcastSnippetsPref = geckoPreferences.getMethod(methodName, Context.class);
michael@0 98 broadcastSnippetsPref.invoke(null, context);
michael@0 99 return;
michael@0 100 } catch (ClassNotFoundException e) {
michael@0 101 Logger.error(LOG_TAG, "Class " + className + " not found!");
michael@0 102 return;
michael@0 103 } catch (NoSuchMethodException e) {
michael@0 104 Logger.error(LOG_TAG, "Method " + className + "/" + methodName + " not found!");
michael@0 105 return;
michael@0 106 } catch (IllegalArgumentException e) {
michael@0 107 Logger.error(LOG_TAG, "Got exception invoking " + methodName + ".");
michael@0 108 } catch (IllegalAccessException e) {
michael@0 109 Logger.error(LOG_TAG, "Got exception invoking " + methodName + ".");
michael@0 110 } catch (InvocationTargetException e) {
michael@0 111 Logger.error(LOG_TAG, "Got exception invoking " + methodName + ".");
michael@0 112 }
michael@0 113 }
michael@0 114 }

mercurial