• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.settings.wifi;
18 
19 import android.content.Context;
20 import android.content.DialogInterface;
21 import android.content.Intent;
22 import android.net.ConnectivityManager;
23 import android.net.ConnectivityManager.NetworkCallback;
24 import android.net.Network;
25 import android.net.NetworkCapabilities;
26 import android.net.NetworkInfo;
27 import android.net.NetworkRequest;
28 import android.net.wifi.WifiInfo;
29 import android.os.Bundle;
30 import android.provider.Settings;
31 import android.util.Log;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.widget.CheckBox;
35 
36 import com.android.internal.app.AlertActivity;
37 import com.android.internal.app.AlertController;
38 import com.android.settings.R;
39 
40 import static android.net.ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
41 import static android.net.ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
42 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
43 
44 public final class WifiNoInternetDialog extends AlertActivity implements
45         DialogInterface.OnClickListener {
46     private static final String TAG = "WifiNoInternetDialog";
47 
48     private ConnectivityManager mCM;
49     private Network mNetwork;
50     private String mNetworkName;
51     private ConnectivityManager.NetworkCallback mNetworkCallback;
52     private CheckBox mAlwaysAllow;
53     private String mAction;
54 
isKnownAction(Intent intent)55     private boolean isKnownAction(Intent intent) {
56         return intent.getAction().equals(ACTION_PROMPT_UNVALIDATED) ||
57                 intent.getAction().equals(ACTION_PROMPT_LOST_VALIDATION);
58     }
59 
60     @Override
onCreate(Bundle savedInstanceState)61     public void onCreate(Bundle savedInstanceState) {
62         super.onCreate(savedInstanceState);
63 
64         final Intent intent = getIntent();
65         if (intent == null || !isKnownAction(intent) || !"netId".equals(intent.getScheme())) {
66             Log.e(TAG, "Unexpected intent " + intent + ", exiting");
67             finish();
68             return;
69         }
70 
71         mAction = intent.getAction();
72 
73         try {
74             mNetwork = new Network(Integer.parseInt(intent.getData().getSchemeSpecificPart()));
75         } catch (NullPointerException|NumberFormatException e) {
76             mNetwork = null;
77         }
78 
79         if (mNetwork == null) {
80             Log.e(TAG, "Can't determine network from '" + intent.getData() + "' , exiting");
81             finish();
82             return;
83         }
84 
85         // TODO: add a registerNetworkCallback(Network network, NetworkCallback networkCallback) and
86         // simplify this.
87         final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
88         mNetworkCallback = new NetworkCallback() {
89             @Override
90             public void onLost(Network network) {
91                 // Close the dialog if the network disconnects.
92                 if (mNetwork.equals(network)) {
93                     Log.d(TAG, "Network " + mNetwork + " disconnected");
94                     finish();
95                 }
96             }
97             @Override
98             public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
99                 // Close the dialog if the network validates.
100                 if (mNetwork.equals(network) && nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
101                     Log.d(TAG, "Network " + mNetwork + " validated");
102                     finish();
103                 }
104             }
105         };
106 
107         mCM = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
108         mCM.registerNetworkCallback(request, mNetworkCallback);
109 
110         final NetworkInfo ni = mCM.getNetworkInfo(mNetwork);
111         final NetworkCapabilities nc = mCM.getNetworkCapabilities(mNetwork);
112         if (ni == null || !ni.isConnectedOrConnecting() || nc == null) {
113             Log.d(TAG, "Network " + mNetwork + " is not connected: " + ni);
114             finish();
115             return;
116         }
117         mNetworkName = nc.getSSID();
118         if (mNetworkName != null) {
119             mNetworkName = WifiInfo.removeDoubleQuotes(mNetworkName);
120         }
121 
122         createDialog();
123     }
124 
createDialog()125     private void createDialog() {
126         mAlert.setIcon(R.drawable.ic_settings_wireless);
127 
128         final AlertController.AlertParams ap = mAlertParams;
129         if (ACTION_PROMPT_UNVALIDATED.equals(mAction)) {
130             ap.mTitle = mNetworkName;
131             ap.mMessage = getString(R.string.no_internet_access_text);
132             ap.mPositiveButtonText = getString(R.string.yes);
133             ap.mNegativeButtonText = getString(R.string.no);
134         } else {
135             ap.mTitle = getString(R.string.lost_internet_access_title);
136             ap.mMessage = getString(R.string.lost_internet_access_text);
137             ap.mPositiveButtonText = getString(R.string.lost_internet_access_switch);
138             ap.mNegativeButtonText = getString(R.string.lost_internet_access_cancel);
139         }
140         ap.mPositiveButtonListener = this;
141         ap.mNegativeButtonListener = this;
142 
143         final LayoutInflater inflater = LayoutInflater.from(ap.mContext);
144         final View checkbox = inflater.inflate(
145                 com.android.internal.R.layout.always_use_checkbox, null);
146         ap.mView = checkbox;
147         mAlwaysAllow = (CheckBox) checkbox.findViewById(com.android.internal.R.id.alwaysUse);
148 
149         if (ACTION_PROMPT_UNVALIDATED.equals(mAction)) {
150             mAlwaysAllow.setText(getString(R.string.no_internet_access_remember));
151         } else {
152             mAlwaysAllow.setText(getString(R.string.lost_internet_access_persist));
153         }
154 
155         setupAlert();
156     }
157 
158     @Override
onDestroy()159     protected void onDestroy() {
160         if (mNetworkCallback != null) {
161             mCM.unregisterNetworkCallback(mNetworkCallback);
162             mNetworkCallback = null;
163         }
164         super.onDestroy();
165     }
166 
onClick(DialogInterface dialog, int which)167     public void onClick(DialogInterface dialog, int which) {
168         if (which != BUTTON_NEGATIVE && which != BUTTON_POSITIVE) return;
169         final boolean always = mAlwaysAllow.isChecked();
170         final String what, action;
171 
172         if (ACTION_PROMPT_UNVALIDATED.equals(mAction)) {
173             what = "NO_INTERNET";
174             final boolean accept = (which == BUTTON_POSITIVE);
175             action = (accept ? "Connect" : "Ignore");
176             mCM.setAcceptUnvalidated(mNetwork, accept, always);
177         } else {
178             what = "LOST_INTERNET";
179             final boolean avoid = (which == BUTTON_POSITIVE);
180             action = (avoid ? "Switch away" : "Get stuck");
181             if (always) {
182                 Settings.Global.putString(mAlertParams.mContext.getContentResolver(),
183                         Settings.Global.NETWORK_AVOID_BAD_WIFI, avoid ? "1" : "0");
184             } else if (avoid) {
185                 mCM.setAvoidUnvalidated(mNetwork);
186             }
187         }
188         Log.d(TAG, what + ": " + action +  " network=" + mNetwork +
189                 (always ? " and remember" : ""));
190     }
191 }
192