convert WifiStateChangeService to IntentService
The IntentService provides the nice incoming Intent queue. It also runs the Intent in a thread, so even the initial check is now in a very low priority thread. The queuing prevents the incoming Intents from competing. This also simplifies the code since the lifecycle is more automatic now.
This commit is contained in:
parent
7eeab77aaf
commit
26d173acdc
@ -1,18 +1,14 @@
|
||||
package org.fdroid.fdroid.net;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.app.IntentService;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.net.DhcpInfo;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
@ -23,7 +19,6 @@ import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.localrepo.LocalRepoKeyStore;
|
||||
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
||||
import org.fdroid.fdroid.localrepo.SwapService;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
@ -34,54 +29,63 @@ import java.security.cert.Certificate;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
|
||||
public class WifiStateChangeService extends Service {
|
||||
/**
|
||||
* Handle state changes to the device's wifi, storing the required bits.
|
||||
* The {@link Intent} that starts it either has no extras included,
|
||||
* which is how it can be triggered by code, or it came in from the system
|
||||
* via {@link org.fdroid.fdroid.receiver.WifiStateChangeReceiver}, in
|
||||
* which case an instance of {@link NetworkInfo} is included.
|
||||
*/
|
||||
public class WifiStateChangeService extends IntentService {
|
||||
private static final String TAG = "WifiStateChangeService";
|
||||
|
||||
public static final String BROADCAST = "org.fdroid.fdroid.action.WIFI_CHANGE";
|
||||
|
||||
private WifiManager wifiManager;
|
||||
private static WaitForWifiAsyncTask asyncTask;
|
||||
private int wifiState;
|
||||
private static WifiInfoThread wifiInfoThread;
|
||||
|
||||
public WifiStateChangeService() {
|
||||
super("WifiStateChangeService");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST);
|
||||
Utils.debugLog(TAG, "WiFi change service started, clearing info about wifi state until we have figured it out again.");
|
||||
FDroidApp.initWifiSettings();
|
||||
NetworkInfo ni = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
|
||||
wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
|
||||
wifiState = wifiManager.getWifiState();
|
||||
int wifiState = wifiManager.getWifiState();
|
||||
if (ni == null || ni.isConnected()) {
|
||||
/* started on app start or from WifiStateChangeReceiver,
|
||||
NetworkInfo is only passed via WifiStateChangeReceiver */
|
||||
Utils.debugLog(TAG, "ni == " + ni + " wifiState == " + printWifiState(wifiState));
|
||||
if (wifiState == WifiManager.WIFI_STATE_ENABLED
|
||||
|| wifiState == WifiManager.WIFI_STATE_DISABLING // might be switching to hotspot
|
||||
|| wifiState == WifiManager.WIFI_STATE_DISABLED // might be hotspot
|
||||
|| wifiState == WifiManager.WIFI_STATE_UNKNOWN) { // might be hotspot
|
||||
if (asyncTask != null) {
|
||||
asyncTask.cancel(true);
|
||||
if (wifiInfoThread != null) {
|
||||
wifiInfoThread.interrupt();
|
||||
}
|
||||
asyncTask = new WaitForWifiAsyncTask();
|
||||
asyncTask.execute();
|
||||
wifiInfoThread = new WifiInfoThread();
|
||||
wifiInfoThread.start();
|
||||
}
|
||||
}
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
public class WaitForWifiAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
private static final String TAG = "WaitForWifiAsyncTask";
|
||||
public class WifiInfoThread extends Thread {
|
||||
private static final String TAG = "WifiInfoThread";
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
public void run() {
|
||||
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST);
|
||||
try {
|
||||
Utils.debugLog(TAG, "Checking wifi state (in background thread).");
|
||||
WifiInfo wifiInfo = null;
|
||||
|
||||
wifiState = wifiManager.getWifiState();
|
||||
int wifiState = wifiManager.getWifiState();
|
||||
|
||||
while (FDroidApp.ipAddressString == null) {
|
||||
if (isCancelled()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return null;
|
||||
if (isInterrupted()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return;
|
||||
}
|
||||
if (wifiState == WifiManager.WIFI_STATE_ENABLED) {
|
||||
wifiInfo = wifiManager.getConnectionInfo();
|
||||
@ -98,7 +102,7 @@ public class WifiStateChangeService extends Service {
|
||||
// try once to see if its a hotspot
|
||||
setIpInfoFromNetworkInterface();
|
||||
if (FDroidApp.ipAddressString == null) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
} else { // a hotspot can be active during WIFI_STATE_UNKNOWN
|
||||
setIpInfoFromNetworkInterface();
|
||||
@ -109,8 +113,8 @@ public class WifiStateChangeService extends Service {
|
||||
Utils.debugLog(TAG, "waiting for an IP address...");
|
||||
}
|
||||
}
|
||||
if (isCancelled()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return null;
|
||||
if (isInterrupted()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return;
|
||||
}
|
||||
|
||||
if (wifiInfo != null) {
|
||||
@ -125,7 +129,6 @@ public class WifiStateChangeService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Can this be moved to the swap service instead?
|
||||
String scheme;
|
||||
if (Preferences.get().isLocalRepoHttpsEnabled()) {
|
||||
scheme = "https";
|
||||
@ -136,16 +139,16 @@ public class WifiStateChangeService extends Service {
|
||||
FDroidApp.REPO.address = String.format(Locale.ENGLISH, "%s://%s:%d/fdroid/repo",
|
||||
scheme, FDroidApp.ipAddressString, FDroidApp.port);
|
||||
|
||||
if (isCancelled()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return null;
|
||||
if (isInterrupted()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = WifiStateChangeService.this.getApplicationContext();
|
||||
LocalRepoManager lrm = LocalRepoManager.get(context);
|
||||
lrm.writeIndexPage(Utils.getSharingUri(FDroidApp.REPO).toString());
|
||||
|
||||
if (isCancelled()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return null;
|
||||
if (isInterrupted()) { // can be canceled by a change via WifiStateChangeReceiver
|
||||
return;
|
||||
}
|
||||
|
||||
// the fingerprint for the local repo's signing key
|
||||
@ -164,38 +167,17 @@ public class WifiStateChangeService extends Service {
|
||||
localRepoKeyStore.setupHTTPSCertificate();
|
||||
}
|
||||
|
||||
} catch (LocalRepoKeyStore.InitException | InterruptedException e) {
|
||||
} catch (LocalRepoKeyStore.InitException e) {
|
||||
Log.e(TAG, "Unable to configure a fingerprint or HTTPS for the local repo", e);
|
||||
} catch (InterruptedException e) {
|
||||
Utils.debugLog(TAG, "interrupted");
|
||||
return;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
Intent intent = new Intent(BROADCAST);
|
||||
LocalBroadcastManager.getInstance(WifiStateChangeService.this).sendBroadcast(intent);
|
||||
WifiStateChangeService.this.stopSelf();
|
||||
|
||||
Intent swapService = new Intent(WifiStateChangeService.this, SwapService.class);
|
||||
getApplicationContext().bindService(swapService, new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
((SwapService.Binder) service).getService().stopWifiIfEnabled(true);
|
||||
getApplicationContext().unbindService(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
}
|
||||
}, BIND_AUTO_CREATE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@TargetApi(9)
|
||||
private void setIpInfoFromNetworkInterface() {
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user