package com.lechucksoftware.proxy.proxysettings.services; import android.app.IntentService; import android.content.Intent; import android.net.wifi.WifiConfiguration; import android.text.TextUtils; import android.util.Log; import com.lechucksoftware.proxy.proxysettings.App; import com.lechucksoftware.proxy.proxysettings.constants.Intents; import com.lechucksoftware.proxy.proxysettings.db.WiFiAPEntity; import java.util.ArrayList; import java.util.List; import java.util.Map; import be.shouldit.proxy.lib.APL; import be.shouldit.proxy.lib.APLNetworkId; import be.shouldit.proxy.lib.WiFiApConfig; import be.shouldit.proxy.lib.constants.APLReflectionConstants; import be.shouldit.proxy.lib.enums.SecurityType; import be.shouldit.proxy.lib.utils.ProxyUtils; import timber.log.Timber; /** * Created by Marco on 09/03/14. */ public class WifiSyncService extends IntentService { public static final String CALLER_INTENT = "CallerIntent"; public static String TAG = WifiSyncService.class.getSimpleName(); private boolean isHandling = false; private static WifiSyncService instance; public WifiSyncService() { super("WifiSyncService"); } public static WifiSyncService getInstance() { return instance; } public boolean isHandlingIntent() { return isHandling; } @Override protected void onHandleIntent(Intent intent) { instance = this; isHandling = true; // try // { // Thread.sleep(1000); // } // catch (InterruptedException e) // { // e.printStackTrace(); // } App.getTraceUtils().startTrace(TAG, "syncAP", "Started handling intent", Log.DEBUG, true); List<APLNetworkId> configsToCheck = getConfigsToCheck(intent); App.getTraceUtils().partialTrace(TAG, "syncAP", "Got configurations to check", Log.DEBUG); syncProxyConfigurations(configsToCheck); App.getTraceUtils().stopTrace(TAG, "syncAP", "Sync-ed configurations", Log.DEBUG); isHandling = false; } private List<APLNetworkId> getConfigsToCheck(Intent intent) { List<APLNetworkId> networkIds = new ArrayList<APLNetworkId>(); if (intent != null && intent.hasExtra(WifiSyncService.CALLER_INTENT)) { Intent caller = (Intent) intent.getExtras().get(WifiSyncService.CALLER_INTENT); if (caller != null) { App.getTraceUtils().logIntent(TAG, caller, Log.DEBUG, true); if (caller.getAction().equals(APLReflectionConstants.CONFIGURED_NETWORKS_CHANGED_ACTION)) { boolean multipleChanges = false; int changeReason = -1; WifiConfiguration wifiConf = null; if (caller.hasExtra(APLReflectionConstants.EXTRA_MULTIPLE_NETWORKS_CHANGED)) { multipleChanges = (boolean) caller.getExtras().get(APLReflectionConstants.EXTRA_MULTIPLE_NETWORKS_CHANGED); } if (caller.hasExtra(APLReflectionConstants.EXTRA_CHANGE_REASON)) { changeReason = (int) caller.getExtras().get(APLReflectionConstants.EXTRA_CHANGE_REASON); } if (caller.hasExtra(APLReflectionConstants.EXTRA_WIFI_CONFIGURATION)) { wifiConf = (WifiConfiguration) caller.getExtras().get(APLReflectionConstants.EXTRA_WIFI_CONFIGURATION); } Timber.d("Multiple networks changed: %s", multipleChanges); Timber.d("Network change reason: %s", ProxyUtils.networksChangedReasonString(changeReason)); if (wifiConf != null) { Timber.d("Got change for WifiConfig: %s", wifiConf.toString()); APLNetworkId wifiId = null; String SSID = ProxyUtils.cleanUpSSID(wifiConf.SSID); SecurityType securityType = ProxyUtils.getSecurity(wifiConf); if (!TextUtils.isEmpty(wifiConf.SSID) && securityType != null) { wifiId = new APLNetworkId(SSID, securityType); } if (wifiId == null) { // Instead of using the WifiConfiguration passed into the Intent, // get the WifiConfiguration based on the network Id Timber.d("Cannot prepare APLNetworkId from WifiConfiguration, trying getting from the configured networks"); WifiConfiguration conf = APL.getConfiguredNetwork(wifiConf.networkId); if (conf != null) { wifiId = new APLNetworkId(ProxyUtils.cleanUpSSID(conf.SSID), ProxyUtils.getSecurity(conf)); } } if (wifiId != null) { Timber.d("Adding network %s to list to be checked", wifiId.toString()); networkIds.add(wifiId); } else { Timber.e("Cannot get WifiConfiguration from Intent"); } } } } } return networkIds; } private void syncProxyConfigurations(List<APLNetworkId> configurations) { Map<APLNetworkId, WifiConfiguration> configuredNetworks = APL.getConfiguredNetworks(); Timber.d("Configured %d Wi-Fi on the device", configuredNetworks.size()); if (configurations.isEmpty()) { Timber.d("No configurations specificed, must sync all of them!"); configurations.addAll(configuredNetworks.keySet()); } Timber.d("Analyzing %d Wi-Fi networks of %d total", configurations.size(), configuredNetworks.size()); int upserted = 0; int removed = 0; for (APLNetworkId aplNetworkId : configurations) { try { App.getTraceUtils().partialTrace(TAG, "syncAP", "Handling network: " + aplNetworkId.toString(), Log.DEBUG); if (configuredNetworks.containsKey(aplNetworkId)) { WifiConfiguration wifiConfiguration = configuredNetworks.get(aplNetworkId); App.getTraceUtils().partialTrace(TAG, "syncAP", String.format("Got WifiConfiguration: ID '%d'", wifiConfiguration.networkId), Log.DEBUG); WiFiApConfig wiFiApConfig = APL.getWiFiAPConfiguration(wifiConfiguration); App.getTraceUtils().partialTrace(TAG, "syncAP", String.format("Got WiFiApConfig: '%s'", wiFiApConfig.toShortString()), Log.DEBUG); WiFiAPEntity wiFiAPEntity = App.getDBManager().upsertWifiAP(wiFiApConfig); App.getTraceUtils().partialTrace(TAG, "syncAP", String.format("Upserted WiFiAPEntity: '%s'", wiFiAPEntity.toString()), Log.DEBUG); App.getWifiNetworksManager().updateWifiConfig(wiFiApConfig); App.getTraceUtils().partialTrace(TAG, "syncAP", String.format("Updated in memory networks status with WifiConfig: '%s'", wiFiAPEntity.toString()), Log.DEBUG); upserted++; } else { App.getDBManager().deleteWifiAP(aplNetworkId); App.getTraceUtils().partialTrace(TAG, "syncAP", "deleteWifiAP: " + aplNetworkId.toString(), Log.DEBUG); App.getWifiNetworksManager().removeWifiConfig(aplNetworkId); App.getTraceUtils().partialTrace(TAG, "syncAP", "removeWifiConfig: " + aplNetworkId.toString(), Log.DEBUG); removed++; } } catch (Exception e) { Timber.e(e, "Exception during WifiSyncService"); } } Timber.i("Analyzed %d Wi-Fi networks of %d total (%d upserted, %d removed)", configurations.size(), configuredNetworks.size(), upserted, removed); Timber.d("Sending broadcast intent " + Intents.PROXY_REFRESH_UI); Intent intent = new Intent(Intents.PROXY_REFRESH_UI); getApplicationContext().sendBroadcast(intent); } }