summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxinhe <xinhe@google.com>2015-11-19 09:40:30 -0800
committerxinhe <xinhe@google.com>2015-11-30 14:03:48 -0800
commite26ad459b63271548abbdeba4f8d77fcca9f88bd (patch)
tree2c6c184330fa63e2dfe99cc7bc5572404bc6da2b
parentd5f9ae241e9fc9842e9bea60ff7f128e7292f055 (diff)
downloadandroid_frameworks_opt_net_wifi-e26ad459b63271548abbdeba4f8d77fcca9f88bd.tar.gz
android_frameworks_opt_net_wifi-e26ad459b63271548abbdeba4f8d77fcca9f88bd.tar.bz2
android_frameworks_opt_net_wifi-e26ad459b63271548abbdeba4f8d77fcca9f88bd.zip
WiFi not connecting to WiFi when screen OFF
When framework toggle PNO too frequently, the lower layer (supplicant and driver) can have some corner case errors. Add minimum gap (5s) between two PNO toggle. Bug: 24777453 Change-Id: Ic360b753c65b77831dc8395834b9ac125f1aa7a1
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java109
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java2
2 files changed, 103 insertions, 8 deletions
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 2e25bae11..c2dbdfdb2 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -35,7 +35,11 @@ import android.text.TextUtils;
import android.util.Base64;
import android.util.LocalLog;
import android.util.Log;
-
+import android.content.Context;
+import android.content.Intent;
+import android.app.PendingIntent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
import com.android.server.connectivity.KeepalivePacketData;
import java.io.ByteArrayOutputStream;
@@ -50,6 +54,7 @@ import java.util.List;
import java.util.Locale;
import java.util.zip.Deflater;
import libcore.util.HexEncoding;
+import android.app.AlarmManager;
/**
* Native calls for bring up/shut down of the supplicant daemon and for
* sending requests to the supplicant daemon
@@ -123,9 +128,18 @@ public class WifiNative {
private native String doStringCommandNative(String command);
- public WifiNative(String interfaceName) {
+ private final Context mContext;
+ private final PnoMonitor mPnoMonitor;
+ public WifiNative(String interfaceName, Context context) {
mInterfaceName = interfaceName;
+ mContext = context;
mTAG = "WifiNative-" + interfaceName;
+ if (mContext != null) {
+ mPnoMonitor = new PnoMonitor();
+ } else {
+ mPnoMonitor = null;
+ }
+
if (!interfaceName.equals("p2p0")) {
mInterfacePrefix = "IFNAME=" + interfaceName + " ";
} else {
@@ -134,6 +148,10 @@ public class WifiNative {
}
}
+ public WifiNative(String interfaceName) {
+ this(interfaceName, null);
+ }
+
void enableVerboseLogging(int verbose) {
if (verbose > 0) {
DBG = true;
@@ -656,14 +674,91 @@ public class WifiNative {
return doBooleanCommand("DRIVER COUNTRY");
}
+ //PNO Monitor
+ private class PnoMonitor {
+ private static final int MINIMUM_PNO_GAP = 5 * 1000;
+ private static final String ACTION_TOGGLE_PNO =
+ "com.android.server.Wifi.action.TOGGLE_PNO";
+ long mLastPnoChangeTimeStamp = -1L;
+ boolean mExpectedPnoState = false;
+ boolean mCurrentPnoState = false;;
+ boolean mWaitForTimer = false;
+ final Object mPnoLock = new Object();
+ private final AlarmManager mAlarmManager =
+ (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+ private final PendingIntent mPnoIntent;
+
+ public PnoMonitor() {
+ Intent intent = new Intent(ACTION_TOGGLE_PNO, null);
+ intent.setPackage("android");
+ mPnoIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+
+ mContext.registerReceiver(
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized(mPnoLock) {
+ if (DBG) Log.d(mTAG, "PNO timer expire, PNO should change to " +
+ mExpectedPnoState);
+ if (mCurrentPnoState != mExpectedPnoState) {
+ if (DBG) Log.d(mTAG, "change PNO from " + mCurrentPnoState + " to "
+ + mExpectedPnoState);
+ boolean ret = setPno(mExpectedPnoState);
+ if (!ret) {
+ Log.e(mTAG, "set PNO failure");
+ }
+ } else {
+ if (DBG) Log.d(mTAG, "Do not change PNO since current is expected");
+ }
+ mWaitForTimer = false;
+ }
+ }
+ },
+ new IntentFilter(ACTION_TOGGLE_PNO));
+ }
+
+ private boolean setPno(boolean enable) {
+ String cmd = enable ? "SET pno 1" : "SET pno 0";
+ boolean ret = doBooleanCommand(cmd);
+ mLastPnoChangeTimeStamp = System.currentTimeMillis();
+ if (ret) {
+ mCurrentPnoState = enable;
+ }
+ return ret;
+ }
+
+ public boolean enableBackgroundScan(boolean enable) {
+ synchronized(mPnoLock) {
+ if (mWaitForTimer) {
+ //already has a timer
+ mExpectedPnoState = enable;
+ if (DBG) Log.d(mTAG, "update expected PNO to " + mExpectedPnoState);
+ } else {
+ if (mCurrentPnoState == enable) {
+ return true;
+ }
+ long timeDifference = System.currentTimeMillis() - mLastPnoChangeTimeStamp;
+ if (timeDifference >= MINIMUM_PNO_GAP) {
+ return setPno(enable);
+ } else {
+ mExpectedPnoState = enable;
+ mWaitForTimer = true;
+ if (DBG) Log.d(mTAG, "start PNO timer with delay:" + timeDifference);
+ mAlarmManager.set(AlarmManager.RTC_WAKEUP,
+ System.currentTimeMillis() + timeDifference, mPnoIntent);
+ }
+ }
+ return true;
+ }
+ }
+ }
+
public boolean enableBackgroundScan(boolean enable) {
- boolean ret;
- if (enable) {
- ret = doBooleanCommand("SET pno 1");
+ if (mPnoMonitor != null) {
+ return mPnoMonitor.enableBackgroundScan(enable);
} else {
- ret = doBooleanCommand("SET pno 0");
+ return false;
}
- return ret;
}
public void enableAutoConnect(boolean enable) {
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 7001a9adf..22ac64509 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -1119,7 +1119,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
mP2pSupported = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_DIRECT);
- mWifiNative = new WifiNative(mInterfaceName);
+ mWifiNative = new WifiNative(mInterfaceName, mContext);
mWifiConfigStore = new WifiConfigStore(context,this, mWifiNative);
mWifiAutoJoinController = new WifiAutoJoinController(context, this,
mWifiConfigStore, mWifiConnectionStatistics, mWifiNative);