• 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 android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.net.ConnectivityManager;
24 import android.net.wifi.WifiConfiguration;
25 import android.net.wifi.WifiManager;
26 import android.provider.Settings;
27 import android.support.v7.preference.PreferenceScreen;
28 import android.text.BidiFormatter;
29 
30 import com.android.settings.R;
31 import com.android.settings.Utils;
32 import com.android.settings.core.PreferenceControllerMixin;
33 import com.android.settings.widget.MasterSwitchController;
34 import com.android.settings.widget.MasterSwitchPreference;
35 import com.android.settingslib.core.AbstractPreferenceController;
36 import com.android.settingslib.core.lifecycle.Lifecycle;
37 import com.android.settingslib.core.lifecycle.LifecycleObserver;
38 import com.android.settingslib.core.lifecycle.events.OnStart;
39 import com.android.settingslib.core.lifecycle.events.OnStop;
40 
41 import java.util.List;
42 
43 public class WifiTetherPreferenceController extends AbstractPreferenceController
44         implements PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop {
45 
46     public static final IntentFilter WIFI_TETHER_INTENT_FILTER;
47     private static final String WIFI_TETHER_SETTINGS = "wifi_tether";
48 
49     private final ConnectivityManager mConnectivityManager;
50     private final String[] mWifiRegexs;
51     private final WifiManager mWifiManager;
52     private final Lifecycle mLifecycle;
53     private WifiTetherSwitchBarController mSwitchController;
54     private MasterSwitchPreference mPreference;
55 
56     static {
57         WIFI_TETHER_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
58         WIFI_TETHER_INTENT_FILTER.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
59         WIFI_TETHER_INTENT_FILTER.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
60     }
61 
WifiTetherPreferenceController(Context context, Lifecycle lifecycle)62     public WifiTetherPreferenceController(Context context, Lifecycle lifecycle) {
63         super(context);
64         mConnectivityManager =
65                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
66         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
67         mWifiRegexs = mConnectivityManager.getTetherableWifiRegexs();
68         mLifecycle = lifecycle;
69         if (lifecycle != null) {
70             lifecycle.addObserver(this);
71         }
72     }
73 
74     @Override
isAvailable()75     public boolean isAvailable() {
76         return mWifiRegexs != null
77                 && mWifiRegexs.length != 0
78                 && WifiTetherSettings.isTetherSettingPageEnabled()
79                 && !Utils.isMonkeyRunning();
80     }
81 
82     @Override
displayPreference(PreferenceScreen screen)83     public void displayPreference(PreferenceScreen screen) {
84         super.displayPreference(screen);
85         mPreference = (MasterSwitchPreference) screen.findPreference(WIFI_TETHER_SETTINGS);
86         if (mPreference == null) {
87             // unavailable
88             return;
89         }
90         mSwitchController = new WifiTetherSwitchBarController(
91                 mContext, new MasterSwitchController(mPreference));
92         mLifecycle.addObserver(mSwitchController);
93     }
94 
95     @Override
getPreferenceKey()96     public String getPreferenceKey() {
97         return WIFI_TETHER_SETTINGS;
98     }
99 
100     @Override
onStart()101     public void onStart() {
102         if (mPreference != null) {
103             mContext.registerReceiver(mReceiver, WIFI_TETHER_INTENT_FILTER);
104             clearSummaryForAirplaneMode();
105         }
106     }
107 
108     @Override
onStop()109     public void onStop() {
110         if (mPreference != null) {
111             mContext.unregisterReceiver(mReceiver);
112         }
113     }
114 
115     //
116     // Everything below is copied from WifiApEnabler
117     //
118     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
119         @Override
120         public void onReceive(Context context, Intent intent) {
121             String action = intent.getAction();
122             if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
123                 int state = intent.getIntExtra(
124                         WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
125                 int reason = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_FAILURE_REASON,
126                         WifiManager.SAP_START_FAILURE_GENERAL);
127                 handleWifiApStateChanged(state, reason);
128             } else if (ConnectivityManager.ACTION_TETHER_STATE_CHANGED.equals(action)) {
129                 List<String> active = intent.getStringArrayListExtra(
130                         ConnectivityManager.EXTRA_ACTIVE_TETHER);
131                 List<String> errored = intent.getStringArrayListExtra(
132                         ConnectivityManager.EXTRA_ERRORED_TETHER);
133                 updateTetherState(active.toArray(), errored.toArray());
134             } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
135                 clearSummaryForAirplaneMode();
136             }
137         }
138     };
139 
handleWifiApStateChanged(int state, int reason)140     private void handleWifiApStateChanged(int state, int reason) {
141         switch (state) {
142             case WifiManager.WIFI_AP_STATE_ENABLING:
143                 mPreference.setSummary(R.string.wifi_tether_starting);
144                 break;
145             case WifiManager.WIFI_AP_STATE_ENABLED:
146                 /**
147                  * Summary on enable is handled by tether
148                  * broadcast notice
149                  */
150                 break;
151             case WifiManager.WIFI_AP_STATE_DISABLING:
152                 mPreference.setSummary(R.string.wifi_tether_stopping);
153                 break;
154             case WifiManager.WIFI_AP_STATE_DISABLED:
155                 mPreference.setSummary(R.string.wifi_hotspot_off_subtext);
156                 clearSummaryForAirplaneMode();
157                 break;
158             default:
159                 if (reason == WifiManager.SAP_START_FAILURE_NO_CHANNEL) {
160                     mPreference.setSummary(R.string.wifi_sap_no_channel_error);
161                 } else {
162                     mPreference.setSummary(R.string.wifi_error);
163                 }
164                 clearSummaryForAirplaneMode();
165         }
166     }
167 
updateTetherState(Object[] tethered, Object[] errored)168     private void updateTetherState(Object[] tethered, Object[] errored) {
169         boolean wifiTethered = matchRegex(tethered);
170         boolean wifiErrored = matchRegex(errored);
171 
172         if (wifiTethered) {
173             WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration();
174             updateConfigSummary(wifiConfig);
175         } else if (wifiErrored) {
176             mPreference.setSummary(R.string.wifi_error);
177         } else {
178             mPreference.setSummary(R.string.wifi_hotspot_off_subtext);
179         }
180     }
181 
matchRegex(Object[] tethers)182     private boolean matchRegex(Object[] tethers) {
183         for (Object o : tethers) {
184             String s = (String) o;
185             for (String regex : mWifiRegexs) {
186                 if (s.matches(regex)) {
187                     return true;
188                 }
189             }
190         }
191         return false;
192     }
193 
updateConfigSummary(WifiConfiguration wifiConfig)194     private void updateConfigSummary(WifiConfiguration wifiConfig) {
195         final String s = mContext.getString(
196                 com.android.internal.R.string.wifi_tether_configure_ssid_default);
197 
198         mPreference.setSummary(mContext.getString(R.string.wifi_tether_enabled_subtext,
199                 BidiFormatter.getInstance().unicodeWrap(
200                         (wifiConfig == null) ? s : wifiConfig.SSID)));
201     }
202 
clearSummaryForAirplaneMode()203     private void clearSummaryForAirplaneMode() {
204         boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
205                 Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
206         if (isAirplaneMode) {
207             mPreference.setSummary(R.string.summary_placeholder);
208         }
209     }
210     //
211     // Everything above is copied from WifiApEnabler
212     //
213 }
214