blob: e5aec3b1d1cd6574f78baffd3b93b71225cc8777 [file] [log] [blame]
/*
* 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();
}
}