package com.ablsolutions.wificonnect.connector import android.content.Context import android.os.Build import android.content.SharedPreferences import android.net.wifi.WifiConfiguration import android.net.wifi.WifiEnterpriseConfig import android.net.wifi.WifiManager import androidx.appcompat.app.AppCompatActivity import com.ablsolutions.wificonnect.connector.ErrorCodes.activityDoesNotExist import com.ablwificonnectivity.settings.ConnectionSettings import com.ablsolutions.wificonnect.connector.ErrorCodes.failedToEnabledNetwork import com.ablsolutions.wificonnect.connector.ErrorCodes.failedToRemoveNetwork import com.ablsolutions.wificonnect.connector.ErrorCodes.unknownError import com.facebook.react.bridge.ReactApplicationContext import android.util.Log import java.util.* class Android9AndBeforeWifiConnector(private val reactContext: ReactApplicationContext) : WifiConnector { private val networkIdKey: String = "android9-network-id" @Suppress("DEPRECATION") override fun connect( connectionSettings: ConnectionSettings, successCallback: () -> Unit, failCallback: (errorCode: String, errorMessage: String) -> Unit ) { val wifiConfiguration = WifiConfiguration() // ssid must be quoted - otherwise the ssid is interpreted as hex value wifiConfiguration.SSID = "\"${connectionSettings.ssid}\"" wifiConfiguration.hiddenSSID = connectionSettings.isHiddenSSID val enterpriseConfig = WifiEnterpriseConfig(connectionSettings.enterpriseConfig) wifiConfiguration.enterpriseConfig = enterpriseConfig val allowedKeyManagement = BitSet() allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP) wifiConfiguration.allowedKeyManagement = allowedKeyManagement val wifiManager = reactContext.getSystemService(AppCompatActivity.WIFI_SERVICE) as WifiManager val sharedPreferences = getSharedPreferences() if (sharedPreferences == null) { failCallback(activityDoesNotExist, "Adding a network configuration must be executed in the context of an activity") return } val networkId = wifiManager.addNetwork(wifiConfiguration) if (networkId == -1) { failCallback(unknownError, "Failed to configure network") return } wifiManager.disconnect() val enableNetworkSucceeded = wifiManager.enableNetwork(networkId, true) if (!enableNetworkSucceeded) { failCallback( failedToEnabledNetwork, "Configured WiFi network successfully but failed to enable the configuration") return } val reconnectSucceeded = wifiManager.reconnect() sharedPreferences.edit().putInt(networkIdKey, networkId).apply() successCallback() } @Suppress("DEPRECATION") override fun deleteConfiguration(successCallback: () -> Unit, failCallback: (errorCode: String, errorMessage: String) -> Unit) { val wifiManager = reactContext.getSystemService(AppCompatActivity.WIFI_SERVICE) as WifiManager val sharedPreferences = getSharedPreferences() if (sharedPreferences == null) { failCallback(activityDoesNotExist, "Removing a network configuration must be executed in the context of an activity") return } val networkId = sharedPreferences.getInt(networkIdKey, -1) if (networkId == -1) { failCallback( failedToRemoveNetwork, "Could not select the network configuration that must be deleted. It seems like the network is not configured.") return } val removeNetworkResult = wifiManager.removeNetwork(networkId) // If android version 7 or below -> saving config after removal if (Build.VERSION.SDK_INT <= 25) { wifiManager.saveConfiguration() } sharedPreferences.edit().putInt(networkIdKey, -1).apply() if (removeNetworkResult) { successCallback() } else { failCallback( failedToRemoveNetwork, "Failed to remove network configuration from device. It might got already deleted manually.") } } override fun isWifiConfigured(): Boolean { val sharedPreferences = getSharedPreferences() val networkId = sharedPreferences?.getInt(networkIdKey, -1) return networkId != null && networkId != -1 } private fun getSharedPreferences(): SharedPreferences? { return reactContext.currentActivity?.getSharedPreferences("abl-solutions_wifi-connect", Context.MODE_PRIVATE) } }