Merge "Update gps status icon to be a "high power" location icon. Move icon to right side of the screen and synchronize status with AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION." into klp-dev
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 6318e38..1c28138 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -786,10 +786,14 @@
// 2 most significant bits in screenLayout).
setLayoutDirection(locale);
}
+ if (delta.screenLayout != 0 && screenLayout != delta.screenLayout) {
+ changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+ setLayoutDirection(locale);
+ }
if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
{
- userSetLocale = true;
changed |= ActivityInfo.CONFIG_LOCALE;
+ userSetLocale = true;
}
if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
&& touchscreen != delta.touchscreen) {
@@ -933,6 +937,9 @@
changed |= ActivityInfo.CONFIG_LOCALE;
changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
}
+ if (delta.screenLayout != 0 && screenLayout != delta.screenLayout) {
+ changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+ }
if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
&& touchscreen != delta.touchscreen) {
changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
@@ -1005,7 +1012,7 @@
public static boolean needNewResources(int configChanges, int interestingChanges) {
return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
}
-
+
/**
* @hide Return true if the sequence of 'other' is better than this. Assumes
* that 'this' is your current sequence and 'other' is a new one you have
diff --git a/core/java/android/database/DefaultDatabaseErrorHandler.java b/core/java/android/database/DefaultDatabaseErrorHandler.java
old mode 100644
new mode 100755
index a9e39c3..b234e34
--- a/core/java/android/database/DefaultDatabaseErrorHandler.java
+++ b/core/java/android/database/DefaultDatabaseErrorHandler.java
@@ -99,7 +99,7 @@
}
Log.e(TAG, "deleting the database file: " + fileName);
try {
- new File(fileName).delete();
+ SQLiteDatabase.deleteDatabase(new File(fileName));
} catch (Exception e) {
/* print warning and ignore exception */
Log.w(TAG, "delete failed: " + e.getMessage());
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1ba39b3..4865fd0 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5662,6 +5662,12 @@
public static final String SELINUX_STATUS = "selinux_status";
/**
+ * Developer setting to force RTL layout.
+ * @hide
+ */
+ public static final String DEVELOPMENT_FORCE_RTL = "debug.force_rtl";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index e2035c2..596ca8c 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -19,6 +19,8 @@
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemProperties;
+import android.provider.Settings;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.AlignmentSpan;
import android.text.style.BackgroundColorSpan;
@@ -1743,8 +1745,10 @@
return View.LAYOUT_DIRECTION_RTL;
}
}
-
- return View.LAYOUT_DIRECTION_LTR;
+ // If forcing into RTL layout mode, return RTL as default, else LTR
+ return SystemProperties.getBoolean(Settings.Global.DEVELOPMENT_FORCE_RTL, false)
+ ? View.LAYOUT_DIRECTION_RTL
+ : View.LAYOUT_DIRECTION_LTR;
}
/**
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 7e70c7c..6d23c32 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -141,7 +141,7 @@
dns, server, &lease, vendorInfo, domains, mtu);
}
if (result != 0) {
- ALOGD("dhcp_do_request failed");
+ ALOGD("dhcp_do_request failed : %s (%s)", nameStr, renew ? "renew" : "new");
}
env->ReleaseStringUTFChars(ifname, nameStr);
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 08962e2..aa6dbf3 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -33,11 +33,11 @@
static jint DBG = false;
-static int doCommand(const char *ifname, char *cmd, char *replybuf, int replybuflen)
+static int doCommand(char *cmd, char *replybuf, int replybuflen)
{
size_t reply_len = replybuflen - 1;
- if (::wifi_command(ifname, cmd, BUF_SIZE, replybuf, &reply_len) != 0)
+ if (::wifi_command(cmd, replybuf, &reply_len) != 0)
return -1;
else {
// Strip off trailing newline
@@ -49,7 +49,7 @@
}
}
-static jint doIntCommand(const char *ifname, const char* fmt, ...)
+static jint doIntCommand(const char* fmt, ...)
{
char buf[BUF_SIZE];
va_list args;
@@ -60,13 +60,13 @@
return -1;
}
char reply[BUF_SIZE];
- if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
+ if (doCommand(buf, reply, sizeof(reply)) != 0) {
return -1;
}
return static_cast<jint>(atoi(reply));
}
-static jboolean doBooleanCommand(const char *ifname, const char* expect, const char* fmt, ...)
+static jboolean doBooleanCommand(const char* expect, const char* fmt, ...)
{
char buf[BUF_SIZE];
va_list args;
@@ -77,14 +77,14 @@
return JNI_FALSE;
}
char reply[BUF_SIZE];
- if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
+ if (doCommand(buf, reply, sizeof(reply)) != 0) {
return JNI_FALSE;
}
return (strcmp(reply, expect) == 0);
}
// Send a command to the supplicant, and return the reply as a String
-static jstring doStringCommand(JNIEnv* env, const char *ifname, const char* fmt, ...) {
+static jstring doStringCommand(JNIEnv* env, const char* fmt, ...) {
char buf[BUF_SIZE];
va_list args;
va_start(args, fmt);
@@ -94,7 +94,7 @@
return NULL;
}
char reply[4096];
- if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
+ if (doCommand(buf, reply, sizeof(reply)) != 0) {
return NULL;
}
// TODO: why not just NewStringUTF?
@@ -127,23 +127,20 @@
return (jboolean)(::wifi_stop_supplicant(p2pSupported) == 0);
}
-static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
+static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
{
- ScopedUtfChars ifname(env, jIface);
- return (jboolean)(::wifi_connect_to_supplicant(ifname.c_str()) == 0);
+ return (jboolean)(::wifi_connect_to_supplicant() == 0);
}
-static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject, jstring jIface)
+static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
{
- ScopedUtfChars ifname(env, jIface);
- ::wifi_close_supplicant_connection(ifname.c_str());
+ ::wifi_close_supplicant_connection();
}
-static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject, jstring jIface)
+static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
{
char buf[EVENT_BUF_SIZE];
- ScopedUtfChars ifname(env, jIface);
- int nread = ::wifi_wait_for_event(ifname.c_str(), buf, sizeof buf);
+ int nread = ::wifi_wait_for_event(buf, sizeof buf);
if (nread > 0) {
return env->NewStringUTF(buf);
} else {
@@ -151,43 +148,36 @@
}
}
-static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jIface,
- jstring jCommand)
+static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jCommand)
{
- ScopedUtfChars ifname(env, jIface);
ScopedUtfChars command(env, jCommand);
if (command.c_str() == NULL) {
return JNI_FALSE;
}
if (DBG) ALOGD("doBoolean: %s", command.c_str());
- return doBooleanCommand(ifname.c_str(), "OK", "%s", command.c_str());
+ return doBooleanCommand("OK", "%s", command.c_str());
}
-static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jIface,
- jstring jCommand)
+static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jCommand)
{
- ScopedUtfChars ifname(env, jIface);
ScopedUtfChars command(env, jCommand);
if (command.c_str() == NULL) {
return -1;
}
if (DBG) ALOGD("doInt: %s", command.c_str());
- return doIntCommand(ifname.c_str(), "%s", command.c_str());
+ return doIntCommand("%s", command.c_str());
}
-static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jIface,
- jstring jCommand)
+static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jCommand)
{
- ScopedUtfChars ifname(env, jIface);
-
ScopedUtfChars command(env, jCommand);
if (command.c_str() == NULL) {
return NULL;
}
if (DBG) ALOGD("doString: %s", command.c_str());
- return doStringCommand(env, ifname.c_str(), "%s", command.c_str());
+ return doStringCommand(env, "%s", command.c_str());
}
@@ -205,17 +195,13 @@
{ "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
{ "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
{ "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
- { "connectToSupplicant", "(Ljava/lang/String;)Z",
- (void *)android_net_wifi_connectToSupplicant },
- { "closeSupplicantConnection", "(Ljava/lang/String;)V",
+ { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
+ { "closeSupplicantConnectionNative", "()V",
(void *)android_net_wifi_closeSupplicantConnection },
- { "waitForEvent", "(Ljava/lang/String;)Ljava/lang/String;",
- (void*) android_net_wifi_waitForEvent },
- { "doBooleanCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
- (void*) android_net_wifi_doBooleanCommand },
- { "doIntCommand", "(Ljava/lang/String;Ljava/lang/String;)I",
- (void*) android_net_wifi_doIntCommand },
- { "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+ { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent },
+ { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand },
+ { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand },
+ { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_doStringCommand },
};
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index e0c87d7..3b1292e 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -285,7 +285,7 @@
<p>
Starting an {@link android.app.Activity} when the user clicks the notification is the most
common action scenario. You can also start an {@link android.app.Activity} when the user
- dismisses an {@link android.app.Activity}. In Android 4.1 and later, you can start an
+ dismisses a notification. In Android 4.1 and later, you can start an
{@link android.app.Activity} from an action button. To learn more, read the reference guide for
{@link android.support.v4.app.NotificationCompat.Builder}.
</p>
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
old mode 100644
new mode 100755
index 632334b..cf1238a
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -221,7 +221,7 @@
if (c != null) c.close();
if (db != null) db.close();
}
- databaseFile.delete();
+ context.deleteDatabase(devicePropertiesName);
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3d8843e..b950cd0 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8453,9 +8453,17 @@
resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
boolean alwaysFinishActivities = Settings.Global.getInt(
resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
+ boolean forceRtl = Settings.Global.getInt(
+ resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
+ // Transfer any global setting for forcing RTL layout, into a System Property
+ SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
Configuration configuration = new Configuration();
Settings.System.getConfiguration(resolver, configuration);
+ if (forceRtl) {
+ // This will take care of setting the correct layout direction flags
+ configuration.setLayoutDirection(configuration.locale);
+ }
synchronized (this) {
mDebugApp = mOrigDebugApp = debugApp;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index fe3c709..92b8e46 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -32,7 +32,10 @@
import com.android.internal.util.Protocol;
import com.android.internal.util.StateMachine;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
@@ -44,6 +47,7 @@
*/
public class WifiMonitor {
+ private static final boolean DBG = false;
private static final String TAG = "WifiMonitor";
/** Events we receive from the supplicant daemon */
@@ -279,9 +283,6 @@
/* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
- private final StateMachine mStateMachine;
- private final WifiNative mWifiNative;
-
/* Supplicant events reported to a state machine */
private static final int BASE = Protocol.BASE_WIFI_MONITOR;
@@ -347,164 +348,324 @@
private static final String WPA_RECV_ERROR_STR = "recv error";
/**
- * Tracks consecutive receive errors
- */
- private int mRecvErrors = 0;
-
- /**
* Max errors before we close supplicant connection
*/
private static final int MAX_RECV_ERRORS = 10;
+ private final String mInterfaceName;
+ private final WifiNative mWifiNative;
+ private final StateMachine mWifiStateMachine;
+ private boolean mMonitoring;
+
public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
- mStateMachine = wifiStateMachine;
+ if (DBG) Log.d(TAG, "Creating WifiMonitor");
mWifiNative = wifiNative;
+ mInterfaceName = wifiNative.mInterfaceName;
+ mWifiStateMachine = wifiStateMachine;
+ mMonitoring = false;
+
+ WifiMonitorSingleton.getMonitor().registerInterfaceMonitor(mInterfaceName, this);
}
public void startMonitoring() {
- new MonitorThread().start();
+ WifiMonitorSingleton.getMonitor().startMonitoring(mInterfaceName);
}
- class MonitorThread extends Thread {
- public MonitorThread() {
- super("WifiMonitor");
+ public void stopMonitoring() {
+ WifiMonitorSingleton.getMonitor().stopMonitoring(mInterfaceName);
+ }
+
+ public void stopSupplicant() {
+ WifiMonitorSingleton.getMonitor().stopSupplicant();
+ }
+
+ public void killSupplicant(boolean p2pSupported) {
+ WifiMonitorSingleton.getMonitor().killSupplicant(p2pSupported);
+ }
+
+ private static class WifiMonitorSingleton {
+ private static Object sSingletonLock = new Object();
+ private static WifiMonitorSingleton sWifiMonitorSingleton = null;
+ private HashMap<String, WifiMonitor> mIfaceMap = new HashMap<String, WifiMonitor>();
+ private boolean mConnected = false;
+ private WifiNative mWifiNative;
+
+ private WifiMonitorSingleton() {
}
- public void run() {
+ static WifiMonitorSingleton getMonitor() {
+ if (DBG) Log.d(TAG, "WifiMonitorSingleton gotten");
+ synchronized (sSingletonLock) {
+ if (sWifiMonitorSingleton == null) {
+ if (DBG) Log.d(TAG, "WifiMonitorSingleton created");
+ sWifiMonitorSingleton = new WifiMonitorSingleton();
+ }
+ }
+ return sWifiMonitorSingleton;
+ }
- if (connectToSupplicant()) {
- // Send a message indicating that it is now possible to send commands
- // to the supplicant
- mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
- } else {
- mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+ public synchronized void startMonitoring(String iface) {
+ WifiMonitor m = mIfaceMap.get(iface);
+ if (m == null) {
+ Log.e(TAG, "startMonitor called with unknown iface=" + iface);
return;
}
+ Log.d(TAG, "startMonitoring(" + iface + ") with mConnected = " + mConnected);
+
+ if (mConnected) {
+ m.mMonitoring = true;
+ m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
+ } else {
+ if (DBG) Log.d(TAG, "connecting to supplicant");
+ int connectTries = 0;
+ while (true) {
+ if (mWifiNative.connectToSupplicant()) {
+ m.mMonitoring = true;
+ m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
+ new MonitorThread(mWifiNative, this).start();
+ mConnected = true;
+ break;
+ }
+ if (connectTries++ < 5) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignore) {
+ }
+ } else {
+ mIfaceMap.remove(iface);
+ m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+ break;
+ }
+ }
+ }
+ }
+
+ public synchronized void stopMonitoring(String iface) {
+ WifiMonitor m = mIfaceMap.get(iface);
+ if (DBG) Log.d(TAG, "stopMonitoring(" + iface + ") = " + m.mWifiStateMachine);
+ m.mMonitoring = false;
+ m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+ }
+
+ public synchronized void registerInterfaceMonitor(String iface, WifiMonitor m) {
+ if (DBG) Log.d(TAG, "registerInterface(" + iface + "+" + m.mWifiStateMachine + ")");
+ mIfaceMap.put(iface, m);
+ if (mWifiNative == null) {
+ mWifiNative = m.mWifiNative;
+ }
+ }
+
+ public synchronized void unregisterInterfaceMonitor(String iface) {
+ // REVIEW: When should we call this? If this isn't called, then WifiMonitor
+ // objects will remain in the mIfaceMap; and won't ever get deleted
+
+ WifiMonitor m = mIfaceMap.remove(iface);
+ if (DBG) Log.d(TAG, "unregisterInterface(" + iface + "+" + m.mWifiStateMachine + ")");
+ }
+
+ public synchronized void stopSupplicant() {
+ mWifiNative.stopSupplicant();
+ }
+
+ public synchronized void killSupplicant(boolean p2pSupported) {
+ mWifiNative.killSupplicant(p2pSupported);
+ mConnected = false;
+ Iterator<Map.Entry<String, WifiMonitor>> it = mIfaceMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, WifiMonitor> e = it.next();
+ WifiMonitor m = e.getValue();
+ m.mMonitoring = false;
+ }
+ }
+
+ private synchronized WifiMonitor getMonitor(String iface) {
+ return mIfaceMap.get(iface);
+ }
+ }
+
+ private static class MonitorThread extends Thread {
+ private final WifiNative mWifiNative;
+ private final WifiMonitorSingleton mWifiMonitorSingleton;
+ private int mRecvErrors = 0;
+ private StateMachine mStateMachine = null;
+
+ public MonitorThread(WifiNative wifiNative, WifiMonitorSingleton wifiMonitorSingleton) {
+ super("WifiMonitor");
+ mWifiNative = wifiNative;
+ mWifiMonitorSingleton = wifiMonitorSingleton;
+ }
+
+ public void run() {
//noinspection InfiniteLoopStatement
for (;;) {
String eventStr = mWifiNative.waitForEvent();
// Skip logging the common but mostly uninteresting scan-results event
- if (false && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
+ if (DBG && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
Log.d(TAG, "Event [" + eventStr + "]");
}
- if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
- if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
- 0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
- mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
- } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
- mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
- } else if (eventStr.startsWith(WPS_FAIL_STR)) {
- handleWpsFailEvent(eventStr);
- } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
- mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
- } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
- mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
- } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
- handleP2pEvents(eventStr);
- } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
- handleHostApEvents(eventStr);
+
+ WifiMonitor m = null;
+ mStateMachine = null;
+
+ if (eventStr.startsWith("IFNAME=")) {
+ int space = eventStr.indexOf(' ');
+ if (space != -1) {
+ String iface = eventStr.substring(7,space);
+ m = mWifiMonitorSingleton.getMonitor(iface);
+ if (m != null) {
+ if (m.mMonitoring) {
+ mStateMachine = m.mWifiStateMachine;
+ eventStr = eventStr.substring(space + 1);
+ }
+ else {
+ if (DBG) Log.d(TAG, "Dropping event because monitor (" + iface +
+ ") is stopped");
+ continue;
+ }
+ }
+ else {
+ eventStr = eventStr.substring(space + 1);
+ }
}
- continue;
}
- String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
- int nameEnd = eventName.indexOf(' ');
- if (nameEnd != -1)
- eventName = eventName.substring(0, nameEnd);
- if (eventName.length() == 0) {
- if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name");
- continue;
- }
- /*
- * Map event name into event enum
- */
- int event;
- if (eventName.equals(CONNECTED_STR))
- event = CONNECTED;
- else if (eventName.equals(DISCONNECTED_STR))
- event = DISCONNECTED;
- else if (eventName.equals(STATE_CHANGE_STR))
- event = STATE_CHANGE;
- else if (eventName.equals(SCAN_RESULTS_STR))
- event = SCAN_RESULTS;
- else if (eventName.equals(LINK_SPEED_STR))
- event = LINK_SPEED;
- else if (eventName.equals(TERMINATING_STR))
- event = TERMINATING;
- else if (eventName.equals(DRIVER_STATE_STR))
- event = DRIVER_STATE;
- else if (eventName.equals(EAP_FAILURE_STR))
- event = EAP_FAILURE;
- else if (eventName.equals(ASSOC_REJECT_STR))
- event = ASSOC_REJECT;
- else
- event = UNKNOWN;
-
- String eventData = eventStr;
- if (event == DRIVER_STATE || event == LINK_SPEED)
- eventData = eventData.split(" ")[1];
- else if (event == STATE_CHANGE || event == EAP_FAILURE) {
- int ind = eventStr.indexOf(" ");
- if (ind != -1) {
- eventData = eventStr.substring(ind + 1);
+ if (mStateMachine != null) {
+ if (dispatchEvent(eventStr)) {
+ break;
}
} else {
- int ind = eventStr.indexOf(" - ");
- if (ind != -1) {
- eventData = eventStr.substring(ind + 3);
- }
- }
-
- if (event == STATE_CHANGE) {
- handleSupplicantStateChange(eventData);
- } else if (event == DRIVER_STATE) {
- handleDriverEvent(eventData);
- } else if (event == TERMINATING) {
- /**
- * Close the supplicant connection if we see
- * too many recv errors
- */
- if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
- if (++mRecvErrors > MAX_RECV_ERRORS) {
- if (false) {
- Log.d(TAG, "too many recv errors, closing connection");
- }
- } else {
- continue;
+ if (DBG) Log.d(TAG, "Sending to all monitors because there's no interface id");
+ boolean done = false;
+ Iterator<Map.Entry<String, WifiMonitor>> it =
+ mWifiMonitorSingleton.mIfaceMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, WifiMonitor> e = it.next();
+ m = e.getValue();
+ mStateMachine = m.mWifiStateMachine;
+ if (dispatchEvent(eventStr)) {
+ done = true;
}
}
- // notify and exit
- mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
- break;
- } else if (event == EAP_FAILURE) {
- if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
- mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+ if (done) {
+ // After this thread terminates, we'll no longer
+ // be connected to the supplicant
+ if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
+ mWifiMonitorSingleton.mConnected = false;
+ break;
}
- } else if (event == ASSOC_REJECT) {
- mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
- } else {
- handleEvent(event, eventData);
}
- mRecvErrors = 0;
}
}
- private boolean connectToSupplicant() {
- int connectTries = 0;
+ /* @return true if the event was supplicant disconnection */
+ private boolean dispatchEvent(String eventStr) {
- while (true) {
- if (mWifiNative.connectToSupplicant()) {
- return true;
+ if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
+ if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
+ 0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
+ mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+ } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
+ mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
+ } else if (eventStr.startsWith(WPS_FAIL_STR)) {
+ handleWpsFailEvent(eventStr);
+ } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
+ mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
+ } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
+ mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
+ } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
+ handleP2pEvents(eventStr);
+ } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
+ handleHostApEvents(eventStr);
}
- if (connectTries++ < 5) {
- nap(1);
- } else {
- break;
+ else {
+ if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
+ }
+ return false;
+ }
+
+ String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
+ int nameEnd = eventName.indexOf(' ');
+ if (nameEnd != -1)
+ eventName = eventName.substring(0, nameEnd);
+ if (eventName.length() == 0) {
+ if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
+ return false;
+ }
+ /*
+ * Map event name into event enum
+ */
+ int event;
+ if (eventName.equals(CONNECTED_STR))
+ event = CONNECTED;
+ else if (eventName.equals(DISCONNECTED_STR))
+ event = DISCONNECTED;
+ else if (eventName.equals(STATE_CHANGE_STR))
+ event = STATE_CHANGE;
+ else if (eventName.equals(SCAN_RESULTS_STR))
+ event = SCAN_RESULTS;
+ else if (eventName.equals(LINK_SPEED_STR))
+ event = LINK_SPEED;
+ else if (eventName.equals(TERMINATING_STR))
+ event = TERMINATING;
+ else if (eventName.equals(DRIVER_STATE_STR))
+ event = DRIVER_STATE;
+ else if (eventName.equals(EAP_FAILURE_STR))
+ event = EAP_FAILURE;
+ else if (eventName.equals(ASSOC_REJECT_STR))
+ event = ASSOC_REJECT;
+ else
+ event = UNKNOWN;
+
+ String eventData = eventStr;
+ if (event == DRIVER_STATE || event == LINK_SPEED)
+ eventData = eventData.split(" ")[1];
+ else if (event == STATE_CHANGE || event == EAP_FAILURE) {
+ int ind = eventStr.indexOf(" ");
+ if (ind != -1) {
+ eventData = eventStr.substring(ind + 1);
+ }
+ } else {
+ int ind = eventStr.indexOf(" - ");
+ if (ind != -1) {
+ eventData = eventStr.substring(ind + 3);
}
}
+
+ if (event == STATE_CHANGE) {
+ handleSupplicantStateChange(eventData);
+ } else if (event == DRIVER_STATE) {
+ handleDriverEvent(eventData);
+ } else if (event == TERMINATING) {
+ /**
+ * Close the supplicant connection if we see
+ * too many recv errors
+ */
+ if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
+ if (++mRecvErrors > MAX_RECV_ERRORS) {
+ if (DBG) {
+ Log.d(TAG, "too many recv errors, closing connection");
+ }
+ } else {
+ return false;
+ }
+ }
+
+ // notify and exit
+ mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+ return true;
+ } else if (event == EAP_FAILURE) {
+ if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
+ mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+ }
+ } else if (event == ASSOC_REJECT) {
+ mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
+ } else {
+ handleEvent(event, eventData);
+ }
+ mRecvErrors = 0;
return false;
}
@@ -723,71 +884,60 @@
}
notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
}
- }
- private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
- String BSSID = null;
- int networkId = -1;
- if (newState == NetworkInfo.DetailedState.CONNECTED) {
- Matcher match = mConnectedEventPattern.matcher(data);
- if (!match.find()) {
- if (false) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
- } else {
- BSSID = match.group(1);
- try {
- networkId = Integer.parseInt(match.group(2));
- } catch (NumberFormatException e) {
- networkId = -1;
+ private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
+ String BSSID = null;
+ int networkId = -1;
+ if (newState == NetworkInfo.DetailedState.CONNECTED) {
+ Matcher match = mConnectedEventPattern.matcher(data);
+ if (!match.find()) {
+ if (DBG) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
+ } else {
+ BSSID = match.group(1);
+ try {
+ networkId = Integer.parseInt(match.group(2));
+ } catch (NumberFormatException e) {
+ networkId = -1;
+ }
}
+ notifyNetworkStateChange(newState, BSSID, networkId);
}
}
- notifyNetworkStateChange(newState, BSSID, networkId);
- }
- /**
- * Send the state machine a notification that the state of Wifi connectivity
- * has changed.
- * @param networkId the configured network on which the state change occurred
- * @param newState the new network state
- * @param BSSID when the new state is {@link DetailedState#CONNECTED
- * NetworkInfo.DetailedState.CONNECTED},
- * this is the MAC address of the access point. Otherwise, it
- * is {@code null}.
- */
- void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
- if (newState == NetworkInfo.DetailedState.CONNECTED) {
- Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
- netId, 0, BSSID);
- mStateMachine.sendMessage(m);
- } else {
- Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
- netId, 0, BSSID);
- mStateMachine.sendMessage(m);
+ /**
+ * Send the state machine a notification that the state of Wifi connectivity
+ * has changed.
+ * @param networkId the configured network on which the state change occurred
+ * @param newState the new network state
+ * @param BSSID when the new state is {@link DetailedState#CONNECTED
+ * NetworkInfo.DetailedState.CONNECTED},
+ * this is the MAC address of the access point. Otherwise, it
+ * is {@code null}.
+ */
+ void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
+ if (newState == NetworkInfo.DetailedState.CONNECTED) {
+ Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
+ netId, 0, BSSID);
+ mStateMachine.sendMessage(m);
+ } else {
+ Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
+ netId, 0, BSSID);
+ mStateMachine.sendMessage(m);
+ }
}
- }
- /**
- * Send the state machine a notification that the state of the supplicant
- * has changed.
- * @param networkId the configured network on which the state change occurred
- * @param wifiSsid network name
- * @param BSSID network address
- * @param newState the new {@code SupplicantState}
- */
- void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
- SupplicantState newState) {
- mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
- new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
- }
-
- /**
- * Sleep for a period of time.
- * @param secs the number of seconds to sleep
- */
- private static void nap(int secs) {
- try {
- Thread.sleep(secs * 1000);
- } catch (InterruptedException ignore) {
+ /**
+ * Send the state machine a notification that the state of the supplicant
+ * has changed.
+ * @param networkId the configured network on which the state change occurred
+ * @param wifiSsid network name
+ * @param BSSID network address
+ * @param newState the new {@code SupplicantState}
+ */
+ void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
+ SupplicantState newState) {
+ mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
+ new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
}
}
}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index b1dd2ce..d30c7cf 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -47,7 +47,9 @@
static final int SCAN_WITHOUT_CONNECTION_SETUP = 1;
static final int SCAN_WITH_CONNECTION_SETUP = 2;
- String mInterface = "";
+ public final String mInterfaceName;
+ public final String mInterfacePrefix;
+
private boolean mSuspendOptEnabled = false;
public native static boolean loadDriver();
@@ -62,52 +64,53 @@
or when the supplicant is hung */
public native static boolean killSupplicant(boolean p2pSupported);
- private native boolean connectToSupplicant(String iface);
+ private native boolean connectToSupplicantNative();
- private native void closeSupplicantConnection(String iface);
+ private native void closeSupplicantConnectionNative();
/**
* Wait for the supplicant to send an event, returning the event string.
* @return the event string sent by the supplicant.
*/
- private native String waitForEvent(String iface);
+ private native String waitForEventNative();
- private native boolean doBooleanCommand(String iface, String command);
+ private native boolean doBooleanCommandNative(String command);
- private native int doIntCommand(String iface, String command);
+ private native int doIntCommandNative(String command);
- private native String doStringCommand(String iface, String command);
+ private native String doStringCommandNative(String command);
- public WifiNative(String iface) {
- mInterface = iface;
- mTAG = "WifiNative-" + iface;
+ public WifiNative(String interfaceName) {
+ mInterfaceName = interfaceName;
+ mInterfacePrefix = "IFNAME=" + interfaceName + " ";
+ mTAG = "WifiNative-" + interfaceName;
}
public boolean connectToSupplicant() {
- return connectToSupplicant(mInterface);
+ return connectToSupplicantNative();
}
public void closeSupplicantConnection() {
- closeSupplicantConnection(mInterface);
+ closeSupplicantConnectionNative();
}
public String waitForEvent() {
- return waitForEvent(mInterface);
+ return waitForEventNative();
}
private boolean doBooleanCommand(String command) {
if (DBG) Log.d(mTAG, "doBoolean: " + command);
- return doBooleanCommand(mInterface, command);
+ return doBooleanCommandNative(mInterfacePrefix + command);
}
private int doIntCommand(String command) {
if (DBG) Log.d(mTAG, "doInt: " + command);
- return doIntCommand(mInterface, command);
+ return doIntCommandNative(mInterfacePrefix + command);
}
private String doStringCommand(String command) {
if (DBG) Log.d(mTAG, "doString: " + command);
- return doStringCommand(mInterface, command);
+ return doStringCommandNative(mInterfacePrefix + command);
}
public boolean ping() {
@@ -411,9 +414,9 @@
public boolean startWpsPbc(String iface, String bssid) {
if (TextUtils.isEmpty(bssid)) {
- return doBooleanCommand("IFNAME=" + iface + " WPS_PBC");
+ return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
} else {
- return doBooleanCommand("IFNAME=" + iface + " WPS_PBC " + bssid);
+ return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
}
}
@@ -424,7 +427,7 @@
public boolean startWpsPinKeypad(String iface, String pin) {
if (TextUtils.isEmpty(pin)) return false;
- return doBooleanCommand("IFNAME=" + iface + " WPS_PIN any " + pin);
+ return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
}
@@ -438,9 +441,9 @@
public String startWpsPinDisplay(String iface, String bssid) {
if (TextUtils.isEmpty(bssid)) {
- return doStringCommand("IFNAME=" + iface + " WPS_PIN any");
+ return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
} else {
- return doStringCommand("IFNAME=" + iface + " WPS_PIN " + bssid);
+ return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
}
}
@@ -492,7 +495,7 @@
}
public boolean setP2pGroupIdle(String iface, int time) {
- return doBooleanCommand("IFNAME=" + iface + " SET p2p_group_idle " + time);
+ return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
}
public void setPowerSave(boolean enabled) {
@@ -505,9 +508,9 @@
public boolean setP2pPowerSave(String iface, boolean enabled) {
if (enabled) {
- return doBooleanCommand("IFNAME=" + iface + " P2P_SET ps 1");
+ return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
} else {
- return doBooleanCommand("IFNAME=" + iface + " P2P_SET ps 0");
+ return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
}
}
@@ -645,7 +648,7 @@
public boolean p2pGroupRemove(String iface) {
if (TextUtils.isEmpty(iface)) return false;
- return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
+ return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
}
public boolean p2pReject(String deviceAddress) {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 4628c91..91702f9 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -68,6 +68,7 @@
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
+import android.util.Log;
import android.util.LruCache;
import android.text.TextUtils;
@@ -543,7 +544,6 @@
public WifiStateMachine(Context context, String wlanInterface) {
super("WifiStateMachine");
-
mContext = context;
mInterfaceName = wlanInterface;
@@ -888,6 +888,7 @@
* TODO: doc
*/
public void setOperationalMode(int mode) {
+ if (DBG) log("setting operational mode to " + String.valueOf(mode));
sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0);
}
@@ -1756,8 +1757,7 @@
/* Socket connection can be lost when we do a graceful shutdown
* or when the driver is hung. Ensure supplicant is stopped here.
*/
- mWifiNative.killSupplicant(mP2pSupported);
- mWifiNative.closeSupplicantConnection();
+ mWifiMonitor.killSupplicant(mP2pSupported);
sendSupplicantConnectionChangedBroadcast(false);
setWifiState(WIFI_STATE_DISABLED);
}
@@ -2139,7 +2139,7 @@
* Avoids issues with drivers that do not handle interface down
* on a running supplicant properly.
*/
- mWifiNative.killSupplicant(mP2pSupported);
+ mWifiMonitor.killSupplicant(mP2pSupported);
if(mWifiNative.startSupplicant(mP2pSupported)) {
setWifiState(WIFI_STATE_ENABLING);
if (DBG) log("Supplicant start successful");
@@ -2222,7 +2222,7 @@
case WifiMonitor.SUP_DISCONNECTION_EVENT:
if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
loge("Failed to setup control channel, restart supplicant");
- mWifiNative.killSupplicant(mP2pSupported);
+ mWifiMonitor.killSupplicant(mP2pSupported);
transitionTo(mInitialState);
sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
} else {
@@ -2329,9 +2329,7 @@
}
if (DBG) log("stopping supplicant");
- if (!mWifiNative.stopSupplicant()) {
- loge("Failed to stop supplicant");
- }
+ mWifiMonitor.stopSupplicant();
/* Send ourselves a delayed message to indicate failure after a wait time */
sendMessageDelayed(obtainMessage(CMD_STOP_SUPPLICANT_FAILED,
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 68a082a..63b94a2 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -858,7 +858,7 @@
}
if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
- mWifiNative.closeSupplicantConnection();
+ mWifiMonitor.stopMonitoring();
transitionTo(mP2pDisablingState);
break;
case WifiP2pManager.SET_DEVICE_NAME: