/* * Kontalk Android client * Copyright (C) 2017 Kontalk Devteam <devteam@kontalk.org> * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kontalk.service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import org.kontalk.Kontalk; import org.kontalk.Log; import org.kontalk.service.msgcenter.AndroidAdaptiveServerPingManager; import org.kontalk.service.msgcenter.MessageCenterService; import org.kontalk.util.Preferences; /** * Receives changes of the network state to start/stop the message service. * @author Daniele Ricci * @version 1.0 */ public class NetworkStateReceiver extends BroadcastReceiver { private static final String TAG = Kontalk.TAG; private static final int ACTION_START = 1; private static final int ACTION_STOP = 2; private static final int ACTION_TEST = 3; @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); int serviceAction = 0; final ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); // background data setting has changed if (ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED.equals(action)) { // if background data gets deactivated, just stop the service now if (!cm.getBackgroundDataSetting()) { Log.w(TAG, "background data disabled!"); serviceAction = ACTION_STOP; } else { Log.w(TAG, "background data enabled!"); // start message center serviceAction = ACTION_START; // notify ping manager that connection type has changed AndroidAdaptiveServerPingManager.onConnected(); } } // connectivity status has changed else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { // TODO handle FAILOVER_CONNECTION final NetworkInfo info = cm.getActiveNetworkInfo(); if (info != null) { Log.w(TAG, "network state changed!"); if (info.getType() == ConnectivityManager.TYPE_MOBILE && !shouldReconnect(context)) { Log.w(TAG, "throttling on mobile network"); return; } switch (info.getState()) { case CONNECTED: // test connection or reconnect serviceAction = ACTION_TEST; // notify ping manager that connection type has changed AndroidAdaptiveServerPingManager.onConnected(); break; case SUSPENDED: Log.v(TAG, "suspending network traffic"); break; default: serviceAction = ACTION_STOP; break; } } else { // no network info available serviceAction = ACTION_STOP; } } switch (serviceAction) { case ACTION_START: // start message center MessageCenterService.start(context); break; case ACTION_STOP: // stop message center MessageCenterService.stop(context); break; case ACTION_TEST: // connection test MessageCenterService.test(context); break; } } private boolean shouldReconnect(Context context) { // check if some activity is holding to the message center // or there is a pending push notification if (((Kontalk) context.getApplicationContext()).hasReference() || Preferences.getLastPushNotification() < 0) return true; long lastConnect = Preferences.getLastConnection(); // no last connection registered if (lastConnect < 0) return true; long now = System.currentTimeMillis(); long diff = Preferences.getWakeupTimeMillis(context, MessageCenterService.MIN_WAKEUP_TIME); return (now - lastConnect) >= diff; } }