13bf66744d61d18c66d46f2608de0467ad3df0268Mopria/*
23bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 The Android Open Source Project
33bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Copyright (C) 2016 Mopria Alliance, Inc.
43bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
53bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Licensed under the Apache License, Version 2.0 (the "License");
63bf66744d61d18c66d46f2608de0467ad3df0268Mopria * you may not use this file except in compliance with the License.
73bf66744d61d18c66d46f2608de0467ad3df0268Mopria * You may obtain a copy of the License at
83bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
93bf66744d61d18c66d46f2608de0467ad3df0268Mopria *      http://www.apache.org/licenses/LICENSE-2.0
103bf66744d61d18c66d46f2608de0467ad3df0268Mopria *
113bf66744d61d18c66d46f2608de0467ad3df0268Mopria * Unless required by applicable law or agreed to in writing, software
123bf66744d61d18c66d46f2608de0467ad3df0268Mopria * distributed under the License is distributed on an "AS IS" BASIS,
133bf66744d61d18c66d46f2608de0467ad3df0268Mopria * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143bf66744d61d18c66d46f2608de0467ad3df0268Mopria * See the License for the specific language governing permissions and
153bf66744d61d18c66d46f2608de0467ad3df0268Mopria * limitations under the License.
163bf66744d61d18c66d46f2608de0467ad3df0268Mopria */
173bf66744d61d18c66d46f2608de0467ad3df0268Mopria
183bf66744d61d18c66d46f2608de0467ad3df0268Mopriapackage com.android.bips.util;
193bf66744d61d18c66d46f2608de0467ad3df0268Mopria
203bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.BroadcastReceiver;
213bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.Context;
223bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.Intent;
233bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.content.IntentFilter;
243bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.net.ConnectivityManager;
253bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.net.Network;
263bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.net.NetworkInfo;
273bf66744d61d18c66d46f2608de0467ad3df0268Mopriaimport android.util.Log;
283bf66744d61d18c66d46f2608de0467ad3df0268Mopria
293bf66744d61d18c66d46f2608de0467ad3df0268Mopria/** Reliably reports on changes to Wi-Fi connectivity state */
303bf66744d61d18c66d46f2608de0467ad3df0268Mopriapublic class WifiMonitor implements AutoCloseable {
313bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private static final String TAG = WifiMonitor.class.getSimpleName();
323bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private static final boolean DEBUG = false;
333bf66744d61d18c66d46f2608de0467ad3df0268Mopria
343bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private final Context mContext;
353bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private final Listener mListener;
363bf66744d61d18c66d46f2608de0467ad3df0268Mopria
373bf66744d61d18c66d46f2608de0467ad3df0268Mopria    // Current connectivity state or null if not known yet
383bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private Boolean mConnected;
393bf66744d61d18c66d46f2608de0467ad3df0268Mopria
403bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public interface Listener {
413bf66744d61d18c66d46f2608de0467ad3df0268Mopria        void onConnectionStateChanged(boolean isConnected);
423bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
433bf66744d61d18c66d46f2608de0467ad3df0268Mopria
443bf66744d61d18c66d46f2608de0467ad3df0268Mopria    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
453bf66744d61d18c66d46f2608de0467ad3df0268Mopria        @Override
463bf66744d61d18c66d46f2608de0467ad3df0268Mopria        public void onReceive(Context context, Intent intent) {
473bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
483bf66744d61d18c66d46f2608de0467ad3df0268Mopria                boolean isConnected = isConnected(context);
493bf66744d61d18c66d46f2608de0467ad3df0268Mopria                if (mConnected == null || mConnected != isConnected) {
503bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    mConnected = isConnected;
513bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    mListener.onConnectionStateChanged(mConnected);
523bf66744d61d18c66d46f2608de0467ad3df0268Mopria                }
533bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
543bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
553bf66744d61d18c66d46f2608de0467ad3df0268Mopria    };
563bf66744d61d18c66d46f2608de0467ad3df0268Mopria
573bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
583bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Begin listening for connectivity changes, signalling the current WiFi
593bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * connectivity state and any subsequent state changes to the listener.
603bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
613bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public WifiMonitor(Context context, Listener listener) {
623bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (DEBUG) Log.d(TAG, "WifiMonitor()");
633bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mListener = listener;
643bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mContext = context;
653bf66744d61d18c66d46f2608de0467ad3df0268Mopria        IntentFilter filter = new IntentFilter();
663bf66744d61d18c66d46f2608de0467ad3df0268Mopria        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
673bf66744d61d18c66d46f2608de0467ad3df0268Mopria        mContext.registerReceiver(mBroadcastReceiver, filter);
683bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
693bf66744d61d18c66d46f2608de0467ad3df0268Mopria
703bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** Return the current connectivity state */
713bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public static boolean isConnected(Context context) {
723bf66744d61d18c66d46f2608de0467ad3df0268Mopria        ConnectivityManager cm =
733bf66744d61d18c66d46f2608de0467ad3df0268Mopria                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
743bf66744d61d18c66d46f2608de0467ad3df0268Mopria
753bf66744d61d18c66d46f2608de0467ad3df0268Mopria        for (Network network : cm.getAllNetworks()) {
763bf66744d61d18c66d46f2608de0467ad3df0268Mopria            NetworkInfo networkInfo = cm.getNetworkInfo(network);
773bf66744d61d18c66d46f2608de0467ad3df0268Mopria            if (networkInfo != null && networkInfo.isConnected() &&
783bf66744d61d18c66d46f2608de0467ad3df0268Mopria                    networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
793bf66744d61d18c66d46f2608de0467ad3df0268Mopria                return true;
803bf66744d61d18c66d46f2608de0467ad3df0268Mopria            }
813bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
823bf66744d61d18c66d46f2608de0467ad3df0268Mopria        return false;
833bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
843bf66744d61d18c66d46f2608de0467ad3df0268Mopria
853bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /**
863bf66744d61d18c66d46f2608de0467ad3df0268Mopria     * Stop listening for connectivity state
873bf66744d61d18c66d46f2608de0467ad3df0268Mopria     */
883bf66744d61d18c66d46f2608de0467ad3df0268Mopria    @Override
893bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public void close() {
903bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (DEBUG) Log.d(TAG, "close()");
913bf66744d61d18c66d46f2608de0467ad3df0268Mopria        if (mBroadcastReceiver != null) {
923bf66744d61d18c66d46f2608de0467ad3df0268Mopria            mContext.unregisterReceiver(mBroadcastReceiver);
933bf66744d61d18c66d46f2608de0467ad3df0268Mopria            mBroadcastReceiver = null;
943bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
953bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
963bf66744d61d18c66d46f2608de0467ad3df0268Mopria
973bf66744d61d18c66d46f2608de0467ad3df0268Mopria    /** A factory for creating instances of this object (needed for unit tests) */
983bf66744d61d18c66d46f2608de0467ad3df0268Mopria    public static class Factory {
993bf66744d61d18c66d46f2608de0467ad3df0268Mopria        public WifiMonitor create(Context context, Listener listener) {
1003bf66744d61d18c66d46f2608de0467ad3df0268Mopria            return new WifiMonitor(context, listener);
1013bf66744d61d18c66d46f2608de0467ad3df0268Mopria        }
1023bf66744d61d18c66d46f2608de0467ad3df0268Mopria    }
1033bf66744d61d18c66d46f2608de0467ad3df0268Mopria}