Home | History | Annotate | Download | only in wifi
      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
     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
    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
    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
    214     protected void onStop() {
    215         mReceiver.unregister();
    216         unscheduleToggleTimeout();
    217         super.onStop();
    218     }
    219 
    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
    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 
    277     private void scheduleToggleTimeout() {
    278         getWindow().getDecorView().postDelayed(mTimeoutCommand, TOGGLE_TIMEOUT_MILLIS);
    279     }
    280 
    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 
    289         public void register() {
    290             registerReceiver(this, mFilter);
    291         }
    292 
    293         public void unregister() {
    294             unregisterReceiver(this);
    295         }
    296 
    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