/*
* ServeStream: A HTTP stream browser/player for Android
* Copyright 2013 William Seemann
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sourceforge.servestream.receiver;
import java.lang.reflect.Field;
import net.sourceforge.servestream.service.MediaPlaybackService;
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.net.NetworkInfo.State;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.util.Log;
public class ConnectivityReceiver extends BroadcastReceiver {
private static final String TAG = ConnectivityReceiver.class.getName();
private Context mContext = null;
private boolean mIsConnected = false;
final private WifiLock mWifiLock;
private int mNetworkRef = 0;
private boolean mLockingWifi;
private Object[] mLock = new Object[0];
public ConnectivityReceiver(Context context, boolean lockingWifi) {
mContext = context;
final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// prevent WIFI throttling when the screen is off
int lockType = WifiManager.WIFI_MODE_FULL;
try {
Field field = wm.getClass().getField("WIFI_MODE_FULL_HIGH_PERF");
lockType = (Integer) field.get(null);
} catch (Exception ex) {
}
mWifiLock = wm.createWifiLock(lockType, TAG);
final NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null) {
mIsConnected = (info.getState() == State.CONNECTED);
}
mLockingWifi = lockingWifi;
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(this, filter);
}
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
Log.d(TAG, "onReceived() called; noConnectivity? " + noConnectivity + "; isFailover? " + isFailover);
if (noConnectivity && !isFailover && mIsConnected) {
mIsConnected = false;
Intent i = new Intent(MediaPlaybackService.PAUSE_ACTION);
i.putExtra("from_connectivity_receiver", true);
context.sendBroadcast(i);
} else if (!mIsConnected) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo();
if (info != null && (mIsConnected = (info.getState() == State.CONNECTED))) {
Intent i = new Intent(MediaPlaybackService.TOGGLEPAUSE_ACTION);
i.putExtra("from_connectivity_receiver", true);
context.sendBroadcast(i);
}
}
}
}
/**
*
*/
public void cleanup() {
if (mWifiLock.isHeld()) {
mWifiLock.release();
}
mContext.unregisterReceiver(this);
}
/**
* Increase the number of things using the network. Acquire a Wi-Fi lock
* if necessary.
*/
public void incRef() {
synchronized (mLock) {
mNetworkRef += 1;
acquireWifiLockIfNecessaryLocked();
}
}
/**
* Decrease the number of things using the network. Release the Wi-Fi lock
* if necessary.
*/
public void decRef() {
synchronized (mLock) {
mNetworkRef -= 1;
releaseWifiLockIfNecessaryLocked();
}
}
/**
* @param mLockingWifi
*/
public void setWantWifiLock(boolean lockingWifi) {
synchronized (mLock) {
mLockingWifi = lockingWifi;
if (mLockingWifi) {
acquireWifiLockIfNecessaryLocked();
} else {
releaseWifiLockIfNecessaryLocked();
}
}
}
private void acquireWifiLockIfNecessaryLocked() {
if (mLockingWifi && mNetworkRef > 0 && !mWifiLock.isHeld()) {
mWifiLock.acquire();
}
}
private void releaseWifiLockIfNecessaryLocked() {
if (mNetworkRef == 0 && mWifiLock.isHeld()) {
mWifiLock.release();
}
}
/**
* @return whether we're connected to a network
*/
public boolean isConnected() {
return mIsConnected;
}
}