/* * 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(); } }