package org.fdroid.fdroid.net;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.localrepo.LocalRepoKeyStore;
import org.fdroid.fdroid.localrepo.LocalRepoManager;
import java.security.cert.Certificate;
import java.util.Locale;
public class WifiStateChangeService extends Service {
public static final String BROADCAST = "org.fdroid.fdroid.action.WIFI_CHANGE";
private static WaitForWifiAsyncTask asyncTask;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (asyncTask != null)
asyncTask.cancel(true);
asyncTask = new WaitForWifiAsyncTask();
asyncTask.execute();
return START_NOT_STICKY;
}
public class WaitForWifiAsyncTask extends AsyncTask<Void, Void, Void> {
private static final String TAG = "WaitForWifiAsyncTask";
private WifiManager wifiManager;
@Override
protected Void doInBackground(Void... params) {
wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
try {
while (!wifiManager.isWifiEnabled()) {
if (isCancelled())
return null;
Log.i(TAG, "waiting for the wifi to be enabled...");
Thread.sleep(1000);
}
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
while (ipAddress == 0) {
if (isCancelled())
return null;
Log.i(TAG, "waiting for an IP address...");
Thread.sleep(1000);
ipAddress = wifiManager.getConnectionInfo().getIpAddress();
}
if (isCancelled())
return null;
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
ipAddress = wifiInfo.getIpAddress();
FDroidApp.ipAddressString = String.format(Locale.ENGLISH, "%d.%d.%d.%d",
(ipAddress & 0xff),
(ipAddress >> 8 & 0xff),
(ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));
FDroidApp.ssid = wifiInfo.getSSID().replaceAll("^\"(.*)\"$", "$1");
FDroidApp.bssid = wifiInfo.getBSSID();
String scheme;
if (Preferences.get().isLocalRepoHttpsEnabled())
scheme = "https";
else
scheme = "http";
FDroidApp.repo.name = Preferences.get().getLocalRepoName();
FDroidApp.repo.address = String.format(Locale.ENGLISH, "%s://%s:%d/fdroid/repo",
scheme, FDroidApp.ipAddressString, FDroidApp.port);
if (isCancelled())
return null;
Context context = WifiStateChangeService.this.getApplicationContext();
LocalRepoManager lrm = LocalRepoManager.get(context);
lrm.setUriString(FDroidApp.repo.address);
lrm.writeIndexPage(Utils.getSharingUri(context, FDroidApp.repo).toString());
if (isCancelled())
return null;
try {
LocalRepoKeyStore localRepoKeyStore = LocalRepoKeyStore.get(context);
Certificate localCert = localRepoKeyStore.getCertificate();
FDroidApp.repo.fingerprint = Utils.calcFingerprint(localCert);
/*
* Once the IP address is known we need to generate a self
* signed certificate to use for HTTPS that has a CN field set
* to the ipAddressString. This must be run in the background
* because if this is the first time the singleton is run, it
* can take a while to instantiate.
*/
if (Preferences.get().isLocalRepoHttpsEnabled())
localRepoKeyStore.setupHTTPSCertificate();
} catch (LocalRepoKeyStore.InitException e) {
Log.e(TAG, "Unable to configure a fingerprint or HTTPS for the local repo: " + e.getMessage());
Log.e(TAG, Log.getStackTraceString(e));
}
} catch (InterruptedException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return null;
}
@Override
protected void onPostExecute(Void result) {
Intent intent = new Intent(BROADCAST);
LocalBroadcastManager.getInstance(WifiStateChangeService.this).sendBroadcast(intent);
WifiStateChangeService.this.stopSelf();
FDroidApp.restartLocalRepoService();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}