1 /*
2  * Copyright 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.managedprovisioning.task.wifi;
18 
19 import static com.android.internal.util.Preconditions.checkNotNull;
20 
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.net.ConnectivityManager;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.managedprovisioning.common.ProvisionLogger;
29 import com.android.managedprovisioning.common.Utils;
30 
31 /**
32  * Monitor the state of the data network and the checkin service. Invoke a callback when the network
33  * is connected and checkin has succeeded.
34  */
35 public class NetworkMonitor {
36 
37     @VisibleForTesting
38     static final IntentFilter FILTER;
39     static {
40         FILTER = new IntentFilter();
41         FILTER.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
42         // Listen to immediate connectivity changes which are 3 seconds
43         // earlier than CONNECTIVITY_ACTION and may not have IPv6 routes
44         // setup. However, this may allow us to start up services like
45         // the CheckinService a bit earlier.
46         FILTER.addAction(ConnectivityManager.INET_CONDITION_ACTION);
47     }
48 
49     /** State notification callback. Expect some duplicate notifications. */
50     public interface NetworkConnectedCallback {
onNetworkConnected()51         void onNetworkConnected();
52     }
53 
54     private final Context mContext;
55     private final Utils mUtils ;
56 
57     private NetworkConnectedCallback mCallback = null;
58 
59     /**
60      * Start watching the network and monitoring the checkin service. Immediately invokes one of the
61      * callback methods to report the current state, and then invokes callback methods over time as
62      * the state changes.
63      *
64      * @param context to use for intent observers and such
65      */
NetworkMonitor(Context context)66     public NetworkMonitor(Context context) {
67         this(context, new Utils());
68     }
69 
70     @VisibleForTesting
NetworkMonitor(Context context, Utils utils)71     NetworkMonitor(Context context, Utils utils) {
72         mContext = checkNotNull(context);
73         mUtils = checkNotNull(utils);
74     }
75 
76     /**
77      * Start listening for connectivity changes.
78      * @param callback Callback to inform about those changes.
79      */
startListening(NetworkConnectedCallback callback)80     public synchronized void startListening(NetworkConnectedCallback callback) {
81         mCallback = checkNotNull(callback);
82         mContext.registerReceiver(mBroadcastReceiver, FILTER);
83     }
84 
85     /**
86      * Stop listening for connectivity changes.
87      */
stopListening()88     public synchronized void stopListening() {
89         if (mCallback == null) {
90             return;
91         }
92 
93         mCallback = null;
94         mContext.unregisterReceiver(mBroadcastReceiver);
95     }
96 
97     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
98         @Override
99         public void onReceive(Context context, Intent intent) {
100             ProvisionLogger.logd("NetworkMonitor.onReceive: " + intent);
101             if (!FILTER.matchAction(intent.getAction())) {
102                 return;
103             }
104             synchronized (NetworkMonitor.this) {
105                 if (!mUtils.isConnectedToNetwork(context)) {
106                     ProvisionLogger.logd("NetworkMonitor: not connected to network");
107                     return;
108                 }
109                 if (mCallback != null) {
110                     mCallback.onNetworkConnected();
111                 }
112             }
113         }
114     };
115 }
116