/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2015, Telestax Inc and individual contributors
* by the @authors tag.
*
* This program is free software: you can redistribute it and/or modify
* under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
* For questions related to commercial use licensing, please contact sales@telestax.com.
*
*/
package org.restcomm.android.sdk.SignalingClient.JainSipClient;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.util.Log;
import org.restcomm.android.sdk.RCDeviceListener;
import org.restcomm.android.sdk.util.RCLogger;
/**
* JainSipNotificationManager listens for Android connectivity changes and notifies NotificationManagerListener (typically JainSipClient)
*/
class JainSipNotificationManager extends BroadcastReceiver {
// Define JainSipNotificationManager events
public interface NotificationManagerListener {
void onConnectivityChange(ConnectivityChange connectivityChange);
}
enum NetworkStatus {
NetworkStatusNone,
NetworkStatusWiFi,
NetworkStatusCellular,
NetworkStatusEthernet,
}
public enum ConnectivityChange {
OFFLINE,
OFFLINE_TO_WIFI,
OFFLINE_TO_CELLULAR_DATA,
OFFLINE_TO_ETHERNET,
HANDOVER_TO_CELLULAR_DATA,
HANDOVER_TO_WIFI,
HANDOVER_TO_ETHERNET,
}
Context androidContext;
NotificationManagerListener listener;
static final String TAG = "NotificationManager";
NetworkStatus networksStatus;
JainSipNotificationManager(Context androidContext, Handler handler, NotificationManagerListener listener)
{
this.androidContext = androidContext;
this.listener = listener;
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
// initialize current connectivity status
networksStatus = checkConnectivity(androidContext);
// register for connectivity related events
androidContext.registerReceiver(this, filter, null, handler);
}
public void close()
{
// unregister from events
androidContext.unregisterReceiver(this);
}
@Override
public void onReceive(Context context, Intent intent)
{
RCLogger.d(TAG, "BroadcastReceiver:onReceive()");
ConnectivityChange connectivityChange = ConnectivityChange.OFFLINE;
// retrieve new connectivity status
NetworkStatus newConnectivityStatus = checkConnectivity(context);
/*
try {
Thread.sleep(4000);
}
catch (InterruptedException e) {
}
*/
if (newConnectivityStatus == networksStatus) {
RCLogger.w(TAG, "Connectivity change, but remained the same: " + newConnectivityStatus);
return;
}
if (newConnectivityStatus == NetworkStatus.NetworkStatusNone) {
//RCLogger.w(TAG, "Connectivity event; lost connectivity from: " + networksStatus);
connectivityChange = ConnectivityChange.OFFLINE;
}
RCLogger.w(TAG, "Connectivity change from: " + networksStatus + " to: " + newConnectivityStatus);
// old state wifi and new state cellular or the reverse; need to shutdown and restart network facilities
if (networksStatus != NetworkStatus.NetworkStatusNone &&
newConnectivityStatus == NetworkStatus.NetworkStatusCellular) {
connectivityChange = ConnectivityChange.HANDOVER_TO_CELLULAR_DATA;
}
if (networksStatus != NetworkStatus.NetworkStatusNone &&
newConnectivityStatus == NetworkStatus.NetworkStatusWiFi) {
connectivityChange = ConnectivityChange.HANDOVER_TO_WIFI;
}
if (networksStatus != NetworkStatus.NetworkStatusNone &&
newConnectivityStatus == NetworkStatus.NetworkStatusEthernet) {
connectivityChange = ConnectivityChange.HANDOVER_TO_ETHERNET;
}
if (networksStatus == NetworkStatus.NetworkStatusNone &&
newConnectivityStatus == NetworkStatus.NetworkStatusWiFi) {
connectivityChange = ConnectivityChange.OFFLINE_TO_WIFI;
}
if (networksStatus == NetworkStatus.NetworkStatusNone &&
newConnectivityStatus == NetworkStatus.NetworkStatusCellular) {
connectivityChange = ConnectivityChange.OFFLINE_TO_CELLULAR_DATA;
}
if (networksStatus == NetworkStatus.NetworkStatusNone &&
newConnectivityStatus == NetworkStatus.NetworkStatusEthernet) {
connectivityChange = ConnectivityChange.OFFLINE_TO_ETHERNET;
}
// update current connectivity status
networksStatus = newConnectivityStatus;
// notify listener of the change
listener.onConnectivityChange(connectivityChange);
}
static public NetworkStatus checkConnectivity(Context context)
{
RCLogger.d(TAG, "checkConnectivity()");
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
if (activeNetwork != null) {
if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI && activeNetwork.isConnected()) {
RCLogger.w(TAG, "Connectivity status: WIFI");
return NetworkStatus.NetworkStatusWiFi;
}
if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE && activeNetwork.isConnected()) {
RCLogger.w(TAG, "Connectivity status: CELLULAR DATA");
return NetworkStatus.NetworkStatusCellular;
}
if (activeNetwork.getType() == ConnectivityManager.TYPE_ETHERNET && activeNetwork.isConnected()) {
RCLogger.w(TAG, "Connectivity status: ETHERNET");
return NetworkStatus.NetworkStatusEthernet;
}
}
RCLogger.w(TAG, "Connectivity status: NONE");
return NetworkStatus.NetworkStatusNone;
}
// convert from NetworkStatus -> ConnectivityStatus
static public RCDeviceListener.RCConnectivityStatus networkStatus2ConnectivityStatus(NetworkStatus networkStatus)
{
if (networkStatus == NetworkStatus.NetworkStatusNone) {
return RCDeviceListener.RCConnectivityStatus.RCConnectivityStatusNone;
}
else if (networkStatus == NetworkStatus.NetworkStatusWiFi) {
return RCDeviceListener.RCConnectivityStatus.RCConnectivityStatusWiFi;
}
else if (networkStatus == NetworkStatus.NetworkStatusCellular) {
return RCDeviceListener.RCConnectivityStatus.RCConnectivityStatusCellular;
}
else {
return RCDeviceListener.RCConnectivityStatus.RCConnectivityStatusEthernet;
}
}
boolean haveConnectivity()
{
if (networksStatus != NetworkStatus.NetworkStatusNone) {
return true;
}
else {
return false;
}
}
NetworkStatus getNetworkStatus()
{
return networksStatus;
}
}