Bug 1241810 - Restructure FeedService to always complete wakeful intent. r=mcomella

MozReview-Commit-ID: FyczEKtsTgv

--HG--
extra : rebase_source : 05f17f04bb64990f0fe298728e3d05139f64b9fd
This commit is contained in:
Sebastian Kaspari 2016-02-25 14:59:32 -08:00
Родитель a3d6713926
Коммит bd161ad881
8 изменённых файлов: 110 добавлений и 42 удалений

Просмотреть файл

@ -10,12 +10,14 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.Nullable;
import android.support.v4.net.ConnectivityManagerCompat;
import android.util.Log;
import com.keepsafe.switchboard.SwitchBoard;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.feeds.action.BaseAction;
import org.mozilla.gecko.feeds.action.CheckAction;
import org.mozilla.gecko.feeds.action.EnrollAction;
import org.mozilla.gecko.feeds.action.SetupAction;
@ -65,60 +67,68 @@ public class FeedService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
try {
if (!SwitchBoard.isInExperiment(this, Experiments.CONTENT_NOTIFICATIONS)) {
Log.d(LOGTAG, "Not in content notifications experiment. Skipping.");
return;
}
BaseAction action = createActionForIntent(intent);
if (action == null) {
Log.d(LOGTAG, "No action to process");
return;
}
if (action.requiresNetwork() && !isConnectedToUnmeteredNetwork()) {
// For now just skip if we are not connected or the network is metered. We do not want
// to use precious mobile traffic.
Log.d(LOGTAG, "Not connected to a network or network is metered. Skipping.");
return;
}
action.perform(intent);
storage.persistChanges();
} finally {
FeedAlarmReceiver.completeWakefulIntent(intent);
}
}
@Nullable
private BaseAction createActionForIntent(Intent intent) {
if (intent == null) {
return;
}
if (!SwitchBoard.isInExperiment(this, Experiments.CONTENT_NOTIFICATIONS)) {
Log.d(LOGTAG, "Not in content notifications experiment. Skipping.");
return;
}
if (!isConnectedToNetwork() || isActiveNetworkMetered()) {
// For now just skip if we are not connected or the network is metered. We do not want
// to use precious mobile traffic.
Log.d(LOGTAG, "Not connected to a network or network is metered. Skipping.");
return;
return null;
}
switch (intent.getAction()) {
case ACTION_SETUP:
new SetupAction(this).perform();
break;
return new SetupAction(this);
case ACTION_SUBSCRIBE:
new SubscribeAction(storage).perform(intent);
break;
return new SubscribeAction(storage);
case ACTION_CHECK:
new CheckAction(this, storage).perform();
break;
return new CheckAction(this, storage);
case ACTION_ENROLL:
new EnrollAction(this).perform();
break;
return new EnrollAction(this);
case ACTION_WITHDRAW:
new WithdrawAction(this, storage).perform();
break;
return new WithdrawAction(this, storage);
default:
Log.e(LOGTAG, "Unknown action: " + intent.getAction());
return null;
}
storage.persistChanges();
FeedAlarmReceiver.completeWakefulIntent(intent);
}
private boolean isConnectedToNetwork() {
private boolean isConnectedToUnmeteredNetwork() {
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
if (networkInfo == null || !networkInfo.isConnected()) {
return false;
}
private boolean isActiveNetworkMetered() {
return ConnectivityManagerCompat.isActiveNetworkMetered(
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE));
return !ConnectivityManagerCompat.isActiveNetworkMetered(manager);
}
}

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- 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.content.Intent;
/**
* Interface for actions run by FeedService.
*/
public interface BaseAction {
/**
* Perform this action.
*
* @param intent used to start the service.
*/
void perform(Intent intent);
/**
* Does this action require an active network connection?
*/
boolean requiresNetwork();
}

Просмотреть файл

@ -32,7 +32,7 @@ import java.util.List;
/**
* CheckAction: Check if feeds we subscribed to have new content available.
*/
public class CheckAction {
public class CheckAction implements BaseAction {
private static final String LOGTAG = "FeedCheckAction";
private Context context;
@ -43,7 +43,8 @@ public class CheckAction {
this.storage = storage;
}
public void perform() {
@Override
public void perform(Intent intent) {
final List<FeedSubscription> subscriptions = storage.getSubscriptions();
Log.d(LOGTAG, "Checking feeds for updates (" + subscriptions.size() + " feeds) ..");
@ -145,4 +146,9 @@ public class CheckAction {
subscription.getLastModified()
);
}
@Override
public boolean requiresNetwork() {
return true;
}
}

Просмотреть файл

@ -6,6 +6,7 @@
package org.mozilla.gecko.feeds.action;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;
@ -21,7 +22,7 @@ import org.mozilla.gecko.feeds.knownsites.KnownSiteMedium;
/**
* EnrollAction: Search for bookmarks of known sites we can subscribe to.
*/
public class EnrollAction {
public class EnrollAction implements BaseAction {
private static final String LOGTAG = "FeedEnrollAction";
private static final KnownSite[] knownSites = {
@ -35,7 +36,8 @@ public class EnrollAction {
this.context = context;
}
public void perform() {
@Override
public void perform(Intent intent) {
Log.i(LOGTAG, "Searching for bookmarks to enroll in updates");
BrowserDB db = GeckoProfile.get(context).getDB();
@ -45,6 +47,11 @@ public class EnrollAction {
}
}
@Override
public boolean requiresNetwork() {
return false;
}
private void searchFor(BrowserDB db, KnownSite knownSite) {
Cursor cursor = db.getBookmarksForPartialUrl(context.getContentResolver(), "://" + knownSite.getURLSearchString() + "/");
if (cursor == null) {

Просмотреть файл

@ -18,7 +18,7 @@ import org.mozilla.gecko.feeds.FeedService;
/**
* SetupAction: Set up alarms to run various actions every now and then.
*/
public class SetupAction {
public class SetupAction implements BaseAction {
private static final String LOGTAG = "FeedSetupAction";
private Context context;
@ -27,13 +27,19 @@ public class SetupAction {
this.context = context;
}
public void perform() {
@Override
public void perform(Intent intent) {
final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
cancelPreviousAlarms(alarmManager);
scheduleAlarms(alarmManager);
}
@Override
public boolean requiresNetwork() {
return false;
}
private void cancelPreviousAlarms(AlarmManager alarmManager) {
final PendingIntent withdrawIntent = getWithdrawPendingIntent();
alarmManager.cancel(withdrawIntent);

Просмотреть файл

@ -18,7 +18,7 @@ import java.util.UUID;
/**
* SubscribeAction: Try to fetch a feed and create a subscription if successful.
*/
public class SubscribeAction {
public class SubscribeAction implements BaseAction {
private static final String LOGTAG = "FeedSubscribeAction";
public static final String EXTRA_GUID = "guid";
@ -30,6 +30,7 @@ public class SubscribeAction {
this.storage = storage;
}
@Override
public void perform(Intent intent) {
Log.d(LOGTAG, "Subscribing to feed..");
@ -47,6 +48,11 @@ public class SubscribeAction {
subscribe(guid, feedUrl);
}
@Override
public boolean requiresNetwork() {
return true;
}
private void subscribe(String guid, String feedUrl) {
FeedFetcher.FeedResponse response = FeedFetcher.fetchAndParseFeed(feedUrl);
if (response == null) {

Просмотреть файл

@ -6,6 +6,7 @@
package org.mozilla.gecko.feeds.action;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import org.mozilla.gecko.GeckoProfile;
@ -18,7 +19,7 @@ import java.util.List;
/**
* WithdrawAction: Look for feeds to unsubscribe from.
*/
public class WithdrawAction {
public class WithdrawAction implements BaseAction {
private static final String LOGTAG = "FeedWithdrawAction";
private Context context;
@ -29,7 +30,8 @@ public class WithdrawAction {
this.storage = storage;
}
public void perform() {
@Override
public void perform(Intent intent) {
BrowserDB db = GeckoProfile.get(context).getDB();
List<FeedSubscription> subscriptions = storage.getSubscriptions();
@ -43,6 +45,11 @@ public class WithdrawAction {
}
}
@Override
public boolean requiresNetwork() {
return false;
}
private void unsubscribe(FeedSubscription subscription) {
Log.d(LOGTAG, "Unsubscribing from: (" + subscription.getBookmarkGUID() + ") " + subscription.getFeedUrl());

Просмотреть файл

@ -273,6 +273,7 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
'favicons/LoadFaviconTask.java',
'favicons/OnFaviconLoadedListener.java',
'favicons/RemoteFavicon.java',
'feeds/action/BaseAction.java',
'feeds/action/CheckAction.java',
'feeds/action/EnrollAction.java',
'feeds/action/SetupAction.java',