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