summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libwifi_hal/Android.mk6
-rw-r--r--libwifi_hal/wifi_hal_common.cpp59
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java22
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java38
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java33
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java5
-rw-r--r--service/java/com/android/server/wifi/scanner/WificondScannerImpl.java1
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);
}