| /* |
| * Copyright 2014, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.managedprovisioning.task; |
| |
| import android.content.Context; |
| import android.content.Intent; |
| import android.net.ConnectivityManager; |
| import android.net.NetworkInfo; |
| import android.net.wifi.WifiManager; |
| import android.text.TextUtils; |
| |
| import java.lang.Thread; |
| |
| import com.android.managedprovisioning.NetworkMonitor; |
| import com.android.managedprovisioning.ProvisionLogger; |
| import com.android.managedprovisioning.WifiConfig; |
| |
| /** |
| * Adds a wifi network to system. |
| */ |
| public class AddWifiNetworkTask implements NetworkMonitor.Callback { |
| private static final int RETRY_SLEEP_DURATION_BASE_MS = 500; |
| private static final int RETRY_SLEEP_MULTIPLIER = 2; |
| private static final int MAX_RETRIES = 6; |
| |
| private final Context mContext; |
| private final String mSsid; |
| private final boolean mHidden; |
| private final String mSecurityType; |
| private final String mPassword; |
| private final String mProxyHost; |
| private final int mProxyPort; |
| private final String mProxyBypassHosts; |
| private final String mPacUrl; |
| private final Callback mCallback; |
| |
| private WifiManager mWifiManager; |
| private NetworkMonitor mNetworkMonitor; |
| private WifiConfig mWifiConfig; |
| |
| private int mDurationNextSleep = RETRY_SLEEP_DURATION_BASE_MS; |
| private int mRetriesLeft = MAX_RETRIES; |
| |
| public AddWifiNetworkTask(Context context, String ssid, boolean hidden, String securityType, |
| String password, String proxyHost, int proxyPort, String proxyBypassHosts, |
| String pacUrl, Callback callback) { |
| mCallback = callback; |
| mContext = context; |
| mSsid = ssid; |
| mHidden = hidden; |
| mSecurityType = securityType; |
| mPassword = password; |
| mProxyHost = proxyHost; |
| mProxyPort = proxyPort; |
| mProxyBypassHosts = proxyBypassHosts; |
| mPacUrl = pacUrl; |
| mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); |
| mWifiConfig = new WifiConfig(mWifiManager); |
| } |
| |
| public void run() { |
| if (!enableWifi()) { |
| ProvisionLogger.loge("Failed to enable wifi"); |
| mCallback.onError(); |
| return; |
| } |
| |
| mNetworkMonitor = new NetworkMonitor(mContext, this); |
| |
| if (!isConnectedToWifi(mContext)) { |
| if (TextUtils.isEmpty(mSsid)) { |
| ProvisionLogger.loge("Wifi is supposed to be setup in activity," + |
| " or a valid wifi ssid has to be specified."); |
| mCallback.onError(); |
| return; |
| } |
| |
| connectToProvidedNetwork(); |
| } else { |
| mCallback.onSuccess(); |
| } |
| } |
| |
| private void connectToProvidedNetwork() { |
| int netId = mWifiConfig.addNetwork(mSsid, mHidden, mSecurityType, mPassword, mProxyHost, |
| mProxyPort, mProxyBypassHosts, mPacUrl); |
| |
| if (netId == -1) { |
| ProvisionLogger.loge("Failed to save network."); |
| if (mRetriesLeft > 0) { |
| ProvisionLogger.loge("Retrying in " + mDurationNextSleep + " ms."); |
| try { |
| Thread.sleep(mDurationNextSleep); |
| } catch (InterruptedException e) { |
| ProvisionLogger.loge("Retry interrupted."); |
| } |
| mDurationNextSleep *= RETRY_SLEEP_MULTIPLIER; |
| mRetriesLeft--; |
| connectToProvidedNetwork(); |
| return; |
| } else { |
| ProvisionLogger.loge("Already retried " + MAX_RETRIES + " times." |
| + " Quit retrying and report error."); |
| mCallback.onError(); |
| return; |
| } |
| } else { |
| if (!mWifiManager.reconnect()) { |
| ProvisionLogger.loge("Unable to connect to wifi"); |
| mCallback.onError(); |
| return; |
| } |
| } |
| |
| // NetworkMonitor will call onNetworkConnected when in Wifi mode. |
| } |
| |
| private boolean enableWifi() { |
| if (mWifiManager != null) { |
| int wifiState = mWifiManager.getWifiState(); |
| boolean wifiOn = wifiState == WifiManager.WIFI_STATE_ENABLED; |
| if (!wifiOn) { |
| if (!mWifiManager.setWifiEnabled(true)) { |
| return false; |
| } else { |
| return true; |
| } |
| } else { |
| return true; |
| } |
| } else { |
| return false; |
| } |
| } |
| |
| @Override |
| public void onNetworkConnected() { |
| if (NetworkMonitor.isConnectedToWifi(mContext) && |
| mWifiManager.getConnectionInfo().getSSID().equals(mSsid)) { |
| ProvisionLogger.logd("Connected to the correct network"); |
| mNetworkMonitor.close(); |
| mNetworkMonitor = null; |
| mCallback.onSuccess(); |
| } |
| } |
| |
| @Override |
| public void onNetworkDisconnected() { |
| |
| } |
| |
| public void cleanUp() { |
| if (mNetworkMonitor != null) { |
| mNetworkMonitor.close(); |
| mNetworkMonitor = null; |
| } |
| } |
| |
| public static boolean isConnectedToWifi(Context context) { |
| ConnectivityManager cm = |
| (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); |
| NetworkInfo info = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); |
| return info.isConnected(); |
| } |
| |
| public static Intent getWifiPickIntent() { |
| Intent wifiIntent = new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK); |
| wifiIntent.putExtra("only_access_points", true); |
| wifiIntent.putExtra("extra_prefs_show_button_bar", true); |
| wifiIntent.putExtra("wifi_enable_next_on_connect", true); |
| return wifiIntent; |
| } |
| |
| public abstract static class Callback { |
| public abstract void onSuccess(); |
| public abstract void onError(); |
| } |
| } |