• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.tether;
18 
19 import static android.net.ConnectivityManager.TETHERING_WIFI;
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 import android.net.wifi.WifiManager;
27 import android.os.Handler;
28 import android.os.Looper;
29 import android.provider.Settings;
30 import android.support.annotation.VisibleForTesting;
31 
32 import com.android.settings.datausage.DataSaverBackend;
33 import com.android.settings.widget.SwitchWidgetController;
34 import com.android.settingslib.core.lifecycle.LifecycleObserver;
35 import com.android.settingslib.core.lifecycle.events.OnStart;
36 import com.android.settingslib.core.lifecycle.events.OnStop;
37 
38 public class WifiTetherSwitchBarController implements SwitchWidgetController.OnSwitchChangeListener,
39         LifecycleObserver, OnStart, OnStop, DataSaverBackend.Listener {
40 
41     private static final IntentFilter WIFI_INTENT_FILTER;
42 
43     private final Context mContext;
44     private final SwitchWidgetController mSwitchBar;
45     private final ConnectivityManager mConnectivityManager;
46     private final WifiManager mWifiManager;
47 
48     @VisibleForTesting
49     final DataSaverBackend mDataSaverBackend;
50     @VisibleForTesting
51     final ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback =
52             new ConnectivityManager.OnStartTetheringCallback() {
53                 @Override
54                 public void onTetheringFailed() {
55                     super.onTetheringFailed();
56                     mSwitchBar.setChecked(false);
57                     updateWifiSwitch();
58                 }
59             };
60 
61     static {
62         WIFI_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
63         WIFI_INTENT_FILTER.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
64     }
65 
WifiTetherSwitchBarController(Context context, SwitchWidgetController switchBar)66     WifiTetherSwitchBarController(Context context, SwitchWidgetController switchBar) {
67         mContext = context;
68         mSwitchBar = switchBar;
69         mDataSaverBackend = new DataSaverBackend(context);
70         mConnectivityManager =
71                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
72         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
73         mSwitchBar.setChecked(mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED);
74         mSwitchBar.setListener(this);
75         updateWifiSwitch();
76     }
77 
78     @Override
onStart()79     public void onStart() {
80         mDataSaverBackend.addListener(this);
81         mSwitchBar.startListening();
82         mContext.registerReceiver(mReceiver, WIFI_INTENT_FILTER);
83     }
84 
85     @Override
onStop()86     public void onStop() {
87         mDataSaverBackend.remListener(this);
88         mSwitchBar.stopListening();
89         mContext.unregisterReceiver(mReceiver);
90     }
91 
92     @Override
onSwitchToggled(boolean isChecked)93     public boolean onSwitchToggled(boolean isChecked) {
94         if (!isChecked) {
95             stopTether();
96         } else if (!mWifiManager.isWifiApEnabled()) {
97             startTether();
98         }
99         return true;
100     }
101 
stopTether()102     void stopTether() {
103         mSwitchBar.setEnabled(false);
104         mConnectivityManager.stopTethering(TETHERING_WIFI);
105     }
106 
startTether()107     void startTether() {
108         mSwitchBar.setEnabled(false);
109         mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,
110                 mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
111     }
112 
113     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
114         @Override
115         public void onReceive(Context context, Intent intent) {
116             String action = intent.getAction();
117             if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
118                 final int state = intent.getIntExtra(
119                         WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
120                 handleWifiApStateChanged(state);
121             } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
122                 updateWifiSwitch();
123             }
124         }
125     };
126 
handleWifiApStateChanged(int state)127     private void handleWifiApStateChanged(int state) {
128         switch (state) {
129             case WifiManager.WIFI_AP_STATE_ENABLING:
130                 mSwitchBar.setEnabled(false);
131                 break;
132             case WifiManager.WIFI_AP_STATE_ENABLED:
133                 if (!mSwitchBar.isChecked()) {
134                     mSwitchBar.setChecked(true);
135                 }
136                 updateWifiSwitch();
137                 break;
138             case WifiManager.WIFI_AP_STATE_DISABLING:
139                 if (mSwitchBar.isChecked()) {
140                     mSwitchBar.setChecked(false);
141                 }
142                 mSwitchBar.setEnabled(false);
143                 break;
144             case WifiManager.WIFI_AP_STATE_DISABLED:
145                 mSwitchBar.setChecked(false);
146                 updateWifiSwitch();
147                 break;
148             default:
149                 mSwitchBar.setChecked(false);
150                 updateWifiSwitch();
151                 break;
152         }
153     }
154 
updateWifiSwitch()155     private void updateWifiSwitch() {
156         boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
157                 Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
158         if (!isAirplaneMode) {
159             mSwitchBar.setEnabled(!mDataSaverBackend.isDataSaverEnabled());
160         } else {
161             mSwitchBar.setEnabled(false);
162         }
163     }
164 
165     @Override
onDataSaverChanged(boolean isDataSaving)166     public void onDataSaverChanged(boolean isDataSaving) {
167         updateWifiSwitch();
168     }
169 
170     @Override
onWhitelistStatusChanged(int uid, boolean isWhitelisted)171     public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) {
172         // we don't care, since we just want to read the value
173     }
174 
175     @Override
onBlacklistStatusChanged(int uid, boolean isBlacklisted)176     public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) {
177         // we don't care, since we just want to read the value
178     }
179 }
180