• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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.settings.wifi;
18 
19 import android.app.Activity;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.PackageManager;
27 import android.net.wifi.WifiManager;
28 import android.os.Bundle;
29 import android.support.annotation.NonNull;
30 import android.text.TextUtils;
31 import android.util.Log;
32 import android.widget.Toast;
33 import com.android.internal.app.AlertActivity;
34 import com.android.settings.R;
35 
36 /**
37  * This activity handles requests to toggle WiFi by collecting user
38  * consent and waiting until the state change is completed.
39  */
40 public class RequestToggleWiFiActivity extends AlertActivity
41         implements DialogInterface.OnClickListener {
42     private static final String LOG_TAG = "RequestToggleWiFiActivity";
43 
44     private static final long TOGGLE_TIMEOUT_MILLIS = 10000; // 10 sec
45 
46     private static final int STATE_UNKNOWN = -1;
47     private static final int STATE_ENABLE = 1;
48     private static final int STATE_ENABLING = 2;
49     private static final int STATE_DISABLE = 3;
50     private static final int STATE_DISABLING = 4;
51 
52     private final StateChangeReceiver mReceiver = new StateChangeReceiver();
53 
54     private final Runnable mTimeoutCommand = () -> {
55         if (!isFinishing() && !isDestroyed()) {
56             finish();
57         }
58     };
59 
60     private @NonNull WifiManager mWiFiManager;
61     private @NonNull CharSequence mAppLabel;
62 
63     private int mState = STATE_UNKNOWN;
64     private int mLastUpdateState = STATE_UNKNOWN;
65 
66     @Override
onCreate(Bundle savedInstanceState)67     protected void onCreate(Bundle savedInstanceState) {
68         super.onCreate(savedInstanceState);
69 
70         mWiFiManager = getSystemService(WifiManager.class);
71 
72         setResult(Activity.RESULT_CANCELED);
73 
74         String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
75         if (TextUtils.isEmpty(packageName)) {
76             finish();
77             return;
78         }
79 
80         try {
81             ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(
82                     packageName, 0);
83             mAppLabel = applicationInfo.loadSafeLabel(getPackageManager());
84         } catch (PackageManager.NameNotFoundException e) {
85             Log.e(LOG_TAG, "Couldn't find app with package name " + packageName);
86             finish();
87             return;
88         }
89 
90         String action = getIntent().getAction();
91         switch (action) {
92             case WifiManager.ACTION_REQUEST_ENABLE: {
93                 mState = STATE_ENABLE;
94             } break;
95 
96             case WifiManager.ACTION_REQUEST_DISABLE: {
97                 mState = STATE_DISABLE;
98             } break;
99 
100             default: {
101                 finish();
102             }
103         }
104     }
105 
106     @Override
onClick(DialogInterface dialog, int which)107     public void onClick(DialogInterface dialog, int which) {
108         switch (which) {
109             case DialogInterface.BUTTON_POSITIVE: {
110                 switch (mState) {
111                     case STATE_ENABLE: {
112                         mWiFiManager.setWifiEnabled(true);
113                         mState = STATE_ENABLING;
114                         scheduleToggleTimeout();
115                         updateUi();
116                     } break;
117 
118                     case STATE_DISABLE: {
119                         mWiFiManager.setWifiEnabled(false);
120                         mState = STATE_DISABLING;
121                         scheduleToggleTimeout();
122                         updateUi();
123                     } break;
124                 }
125             }
126             break;
127             case DialogInterface.BUTTON_NEGATIVE: {
128                 finish();
129             }
130             break;
131         }
132     }
133 
134     @Override
onStart()135     protected void onStart() {
136         super.onStart();
137 
138         mReceiver.register();
139 
140         final int wifiState = mWiFiManager.getWifiState();
141 
142         switch (mState) {
143             case STATE_ENABLE: {
144                 switch (wifiState) {
145                     case WifiManager.WIFI_STATE_ENABLED: {
146                         setResult(RESULT_OK);
147                         finish();
148                     } return;
149 
150                     case WifiManager.WIFI_STATE_ENABLING: {
151                         mState = STATE_ENABLING;
152                         scheduleToggleTimeout();
153                     } break;
154                 }
155             } break;
156 
157             case STATE_DISABLE: {
158                 switch (wifiState) {
159                     case WifiManager.WIFI_STATE_DISABLED: {
160                         setResult(RESULT_OK);
161                         finish();
162                     }
163                     return;
164 
165                     case WifiManager.WIFI_STATE_ENABLING: {
166                         mState = STATE_DISABLING;
167                         scheduleToggleTimeout();
168                     }
169                     break;
170                 }
171             } break;
172 
173             case STATE_ENABLING: {
174                 switch (wifiState) {
175                     case WifiManager.WIFI_STATE_ENABLED: {
176                         setResult(RESULT_OK);
177                         finish();
178                     } return;
179 
180                     case WifiManager.WIFI_STATE_ENABLING: {
181                         scheduleToggleTimeout();
182                     } break;
183 
184                     case WifiManager.WIFI_STATE_DISABLED:
185                     case WifiManager.WIFI_STATE_DISABLING: {
186                         mState = STATE_ENABLE;
187                     } break;
188                 }
189             } break;
190 
191             case STATE_DISABLING: {
192                 switch (wifiState) {
193                     case WifiManager.WIFI_STATE_DISABLED: {
194                         setResult(RESULT_OK);
195                         finish();
196                     } return;
197 
198                     case WifiManager.WIFI_STATE_DISABLING: {
199                         scheduleToggleTimeout();
200                     } break;
201 
202                     case WifiManager.WIFI_STATE_ENABLED:
203                     case WifiManager.WIFI_STATE_ENABLING: {
204                         mState = STATE_DISABLE;
205                     } break;
206                 }
207             } break;
208         }
209 
210         updateUi();
211     }
212 
213     @Override
onStop()214     protected void onStop() {
215         mReceiver.unregister();
216         unscheduleToggleTimeout();
217         super.onStop();
218     }
219 
updateUi()220     private void updateUi() {
221         if (mLastUpdateState == mState) {
222             return;
223         }
224         mLastUpdateState = mState;
225 
226         switch (mState) {
227             case STATE_ENABLE: {
228                 mAlertParams.mPositiveButtonText = getString(R.string.allow);
229                 mAlertParams.mPositiveButtonListener = this;
230                 mAlertParams.mNegativeButtonText = getString(R.string.deny);
231                 mAlertParams.mNegativeButtonListener = this;
232                 mAlertParams.mMessage = getString(R.string.wifi_ask_enable, mAppLabel);
233             } break;
234 
235             case STATE_ENABLING: {
236                 // Params set button text only if non-null, but we want a null
237                 // button text to hide the button, so reset the controller directly.
238                 mAlert.setButton(DialogInterface.BUTTON_POSITIVE, null, null, null);
239                 mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, null, null, null);
240                 mAlertParams.mPositiveButtonText = null;
241                 mAlertParams.mPositiveButtonListener = null;
242                 mAlertParams.mNegativeButtonText = null;
243                 mAlertParams.mNegativeButtonListener = null;
244                 mAlertParams.mMessage = getString(R.string.wifi_starting);
245             } break;
246 
247             case STATE_DISABLE: {
248                 mAlertParams.mPositiveButtonText = getString(R.string.allow);
249                 mAlertParams.mPositiveButtonListener = this;
250                 mAlertParams.mNegativeButtonText = getString(R.string.deny);
251                 mAlertParams.mNegativeButtonListener = this;
252                 mAlertParams.mMessage = getString(R.string.wifi_ask_disable, mAppLabel);
253             } break;
254 
255             case STATE_DISABLING: {
256                 // Params set button text only if non-null, but we want a null
257                 // button text to hide the button, so reset the controller directly.
258                 mAlert.setButton(DialogInterface.BUTTON_POSITIVE, null, null, null);
259                 mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, null, null, null);
260                 mAlertParams.mPositiveButtonText = null;
261                 mAlertParams.mPositiveButtonListener = null;
262                 mAlertParams.mNegativeButtonText = null;
263                 mAlertParams.mNegativeButtonListener = null;
264                 mAlertParams.mMessage = getString(R.string.wifi_stopping);
265             } break;
266         }
267 
268         setupAlert();
269     }
270 
271     @Override
dismiss()272     public void dismiss() {
273         // Clicking on the dialog buttons dismisses the dialog and finishes
274         // the activity but we want to finish after the WiFi state changed.
275     }
276 
scheduleToggleTimeout()277     private void scheduleToggleTimeout() {
278         getWindow().getDecorView().postDelayed(mTimeoutCommand, TOGGLE_TIMEOUT_MILLIS);
279     }
280 
unscheduleToggleTimeout()281     private void unscheduleToggleTimeout() {
282         getWindow().getDecorView().removeCallbacks(mTimeoutCommand);
283     }
284 
285     private final class StateChangeReceiver extends BroadcastReceiver {
286         private final IntentFilter mFilter = new IntentFilter(
287                 WifiManager.WIFI_STATE_CHANGED_ACTION);
288 
register()289         public void register() {
290             registerReceiver(this, mFilter);
291         }
292 
unregister()293         public void unregister() {
294             unregisterReceiver(this);
295         }
296 
onReceive(Context context, Intent intent)297         public void onReceive(Context context, Intent intent) {
298             Activity activity = RequestToggleWiFiActivity.this;
299             if (activity.isFinishing() || activity.isDestroyed()) {
300                 return;
301             }
302             final int currentState = mWiFiManager.getWifiState();
303             switch (currentState) {
304                 case WifiManager.WIFI_STATE_ENABLED:
305                 case WifiManager.WIFI_STATE_DISABLED: {
306                     if (mState == STATE_ENABLING || mState == STATE_DISABLING) {
307                         RequestToggleWiFiActivity.this.setResult(Activity.RESULT_OK);
308                         finish();
309                     }
310                 } break;
311 
312                 case WifiManager.ERROR: {
313                     Toast.makeText(activity, R.string.wifi_error, Toast.LENGTH_SHORT).show();
314                     finish();
315                 } break;
316             }
317         }
318     }
319 }
320