diff options
7 files changed, 153 insertions, 11 deletions
diff --git a/libwifi_hal/Android.mk b/libwifi_hal/Android.mk index 58e81ff8b..c7ff6364f 100644 --- a/libwifi_hal/Android.mk +++ b/libwifi_hal/Android.mk @@ -60,6 +60,12 @@ ifdef WIFI_DRIVER_STATE_OFF wifi_hal_cflags += -DWIFI_DRIVER_STATE_OFF=\"$(WIFI_DRIVER_STATE_OFF)\" endif +# Wait for Wifi driver to get ready +# Example: WIFI_DRIVER_OPERSTATE_PATH := "/sys/class/net/wlan0/operstate" +ifdef WIFI_DRIVER_OPERSTATE_PATH +wifi_hal_cflags += -DWIFI_DRIVER_OPERSTATE_PATH=\"$(WIFI_DRIVER_OPERSTATE_PATH)\" +endif + # Common code shared between the HALs. # ============================================================ include $(CLEAR_VARS) diff --git a/libwifi_hal/wifi_hal_common.cpp b/libwifi_hal/wifi_hal_common.cpp index 413daf7da..49bb9d1af 100644 --- a/libwifi_hal/wifi_hal_common.cpp +++ b/libwifi_hal/wifi_hal_common.cpp @@ -42,6 +42,12 @@ extern "C" int delete_module(const char *, unsigned int); #define WIFI_DRIVER_MODULE_ARG "" #endif +#ifdef WIFI_DRIVER_OPERSTATE_PATH +#include <sys/stat.h> +#define OPERSTATE_UP "up" +#define OPERSTATE_DOWN "down" +#endif + static const char DRIVER_PROP_NAME[] = "wlan.driver.status"; #ifdef WIFI_DRIVER_MODULE_PATH static const char DRIVER_MODULE_NAME[] = WIFI_DRIVER_MODULE_NAME; @@ -93,8 +99,20 @@ int wifi_change_driver_state(const char *state) { int len; int fd; int ret = 0; + int count = 5; /* wait at most 1 second for completion */ if (!state) return -1; + + do { + if (access(WIFI_DRIVER_STATE_CTRL_PARAM, W_OK) == 0) + break; + usleep(200000); + } while (--count > 0); + if (count == 0) { + PLOG(ERROR) << "Failed to access driver state control param " << strerror(errno) << ", " << errno; + return -1; + } + fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY)); if (fd < 0) { PLOG(ERROR) << "Failed to open driver state control param"; @@ -147,6 +165,40 @@ int is_wifi_driver_loaded() { #endif } +#ifdef WIFI_DRIVER_OPERSTATE_PATH +int is_wifi_driver_ready() { + struct stat sbuf; + FILE *fstate; + char operstate[8]; + int open_count = 25, read_count = 25; + while (open_count-- >= 0) { + if (stat(WIFI_DRIVER_OPERSTATE_PATH, &sbuf) == 0) { + if ((fstate = fopen(WIFI_DRIVER_OPERSTATE_PATH, "r")) == NULL) { + usleep(500000); + } else { + break; + } + } else { + usleep(500000); + } + } + if (fstate != NULL) { + while (read_count-- >= 0) { + fgets(operstate, sizeof(operstate), fstate); + if (strncmp(operstate, OPERSTATE_UP, strlen(OPERSTATE_UP)) == 0 || + strncmp(operstate, OPERSTATE_DOWN, strlen(OPERSTATE_DOWN)) == 0) { + PLOG(INFO) << "Wifi driver is ready"; + return 1; + } + PLOG(WARNING) << "Waiting for Wifi driver to get ready. (" << read_count << ")"; + usleep(500000); + } + fclose(fstate); + } + return 0; +} +#endif + int wifi_load_driver() { #ifdef WIFI_DRIVER_MODULE_PATH if (is_wifi_driver_loaded()) { @@ -163,6 +215,13 @@ int wifi_load_driver() { if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1; #endif + +#ifdef WIFI_DRIVER_OPERSTATE_PATH + if (!is_wifi_driver_ready()) { + PLOG(ERROR) << "Wifi driver didn't get ready in time, giving up!"; + return -1; + } +#endif property_set(DRIVER_PROP_NAME, "ok"); return 0; } diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 216c27cbb..24215617e 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -23,6 +23,7 @@ import static com.android.server.wifi.WifiStateMachine.WIFI_WORK_SOURCE; import android.app.AlarmManager; import android.content.Context; import android.content.pm.PackageManager; +import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.ScanResult; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; @@ -152,6 +153,7 @@ public class WifiConnectivityManager { private boolean mWifiEnabled = false; private boolean mWifiConnectivityManagerEnabled = true; private boolean mScreenOn = false; + private int mMiracastMode = WifiP2pManager.MIRACAST_DISABLED; private int mWifiState = WIFI_STATE_UNKNOWN; private boolean mUntrustedConnectionAllowed = false; private int mScanRestartCount = 0; @@ -902,6 +904,17 @@ public class WifiConnectivityManager { return; } + // Any scans will impact Wifi performance including WFD performance, + // So at least ignore scans triggered internally by ConnectivityManager + // when WFD session is active. We still allow connectivity scans initiated + // by other work source. + if (WIFI_WORK_SOURCE.equals(workSource) && + (mMiracastMode == WifiP2pManager.MIRACAST_SOURCE || + mMiracastMode == WifiP2pManager.MIRACAST_SINK)) { + localLog("Ignore connectivity scan, MiracastMode:" + mMiracastMode); + return; + } + mPnoScanListener.resetLowRssiNetworkRetryDelay(); ScanSettings settings = new ScanSettings(); @@ -1099,6 +1112,15 @@ public class WifiConnectivityManager { } /** + * Save current miracast mode, it will be used to ignore + * connectivity scan during the time when miracast is enabled. + */ + public void saveMiracastMode(int mode) { + localLog("saveMiracastMode: mode=" + mode); + mMiracastMode = mode; + } + + /** * Helper function that converts the WIFI_STATE_XXX constants to string */ private static String stateToString(int state) { diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 6a8e0639b..c38aa1c66 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -89,6 +89,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.provider.Settings; +import android.telephony.TelephonyManager; import android.util.Log; import android.util.MutableInt; import android.util.Slog; @@ -494,6 +495,39 @@ public class WifiServiceImpl extends IWifiManager.Stub { mClientHandler.setWifiLog(log); } + // Return true if it is DUAL SIM and either SIM is active. + private boolean checkDualSimActive() { + TelephonyManager tm = (TelephonyManager) + mContext.getSystemService(Context.TELEPHONY_SERVICE); + + if (tm == null) { + Log.i(TAG, "checkDualSimActive() is false, tm == null"); + return false; + } + + int phoneCount = tm.getPhoneCount(); + if (phoneCount < 2) { + Log.i(TAG, "checkDualSimActive() is false, phoneCount=" + + phoneCount + " slot0State=" + tm.getSimState(0)); + return false; + } + + int slot0State = tm.getSimState(0); + int slot1State = tm.getSimState(1); + if (slot0State != TelephonyManager.SIM_STATE_READY && + slot1State != TelephonyManager.SIM_STATE_READY) { + Log.i(TAG, "checkDualSimActive() is false, slot0State=" + + slot0State + " slot1State=" + slot1State); + return false; + } + + Log.i(TAG, "checkDualSimActive() is true, phoneCount=" + + phoneCount + + " slot0State=" + slot0State + " slot1State=" + slot1State); + + return true; + } + /** * Check if we are ready to start wifi. * @@ -536,6 +570,10 @@ public class WifiServiceImpl extends IWifiManager.Stub { public void onReceive(Context context, Intent intent) { String state = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(state)) { + if (checkDualSimActive()) { + Log.d(TAG, "Not resetting networks as other SIM may active"); + return; + } Log.d(TAG, "resetting networks because SIM was removed"); mWifiStateMachine.resetSimAuthNetworks(false); } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(state)) { diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 390a10238..c0f8f2266 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -313,6 +313,8 @@ public class WifiStateMachine extends StateMachine { private final NetworkCapabilities mDfltNetworkCapabilities; private SupplicantStateTracker mSupplicantStateTracker; + private int mWifiLinkLayerStatsSupported = 4; // Temporary disable + // Indicates that framework is attempting to roam, set true on CMD_START_ROAM, set false when // wifi connects or fails to connect private boolean mIsAutoRoaming = false; @@ -1249,18 +1251,23 @@ public class WifiStateMachine extends StateMachine { loge("getWifiLinkLayerStats called without an interface"); return null; } + WifiLinkLayerStats stats = null; lastLinkLayerStatsUpdate = mClock.getWallClockMillis(); - WifiLinkLayerStats stats = mWifiNative.getWifiLinkLayerStats(mInterfaceName); - if (stats != null) { - mOnTime = stats.on_time; - mTxTime = stats.tx_time; - mRxTime = stats.rx_time; - mRunningBeaconCount = stats.beacon_rx; - mWifiInfo.updatePacketRates(stats, lastLinkLayerStatsUpdate); - } else { - long mTxPkts = mFacade.getTxPackets(mInterfaceName); - long mRxPkts = mFacade.getRxPackets(mInterfaceName); - mWifiInfo.updatePacketRates(mTxPkts, mRxPkts, lastLinkLayerStatsUpdate); + if (mWifiLinkLayerStatsSupported > 0) { + stats = mWifiNative.getWifiLinkLayerStats(mInterfaceName); + if (stats == null) { + mWifiLinkLayerStatsSupported -= 1; + } else { + mOnTime = stats.on_time; + mTxTime = stats.tx_time; + mRxTime = stats.rx_time; + mRunningBeaconCount = stats.beacon_rx; + mWifiInfo.updatePacketRates(stats, lastLinkLayerStatsUpdate); + } + } else { // LinkLayerStats are broken or unsupported + long mTxPkts = mFacade.getTxPackets(mInterfaceName); + long mRxPkts = mFacade.getRxPackets(mInterfaceName); + mWifiInfo.updatePacketRates(mTxPkts, mRxPkts, lastLinkLayerStatsUpdate); } return stats; } @@ -3433,6 +3440,10 @@ public class WifiStateMachine extends StateMachine { mTemporarilyDisconnectWifi = (message.arg1 == 1); replyToMessage(message, WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE); break; + case WifiP2pServiceImpl.SET_MIRACAST_MODE: + if (mVerboseLoggingEnabled) logd("SET_MIRACAST_MODE: " + (int)message.arg1); + mWifiConnectivityManager.saveMiracastMode((int)message.arg1); + break; /* Link configuration (IP address, DNS, ...) changes notified via netlink */ case CMD_UPDATE_LINKPROPERTIES: updateLinkProperties((LinkProperties) message.obj); diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java index c089c9c09..97815b160 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java @@ -585,6 +585,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { enforceConnectivityInternalPermission(); checkConfigureWifiDisplayPermission(); mP2pStateMachine.sendMessage(SET_MIRACAST_MODE, mode); + if (mWifiChannel != null) { + mWifiChannel.sendMessage(WifiP2pServiceImpl.SET_MIRACAST_MODE, mode); + } else { + Log.e(TAG, "setMiracastMode(): WifiChannel is null"); + } } @Override diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java index 41ff9a5ab..68dce534e 100644 --- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java +++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java @@ -411,6 +411,7 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call } private boolean startHwPnoScan(WifiNative.PnoSettings pnoSettings) { + mWifiNative.removeAllNetworks(mIfaceName); return mWifiNative.startPnoScan(mIfaceName, pnoSettings); } |