Merge "Fix FastXmlSerializerTest" into mm-wireless-dev
diff --git a/api/system-current.txt b/api/system-current.txt
index a03f328..3706140 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20815,6 +20815,7 @@
field public int numberBurst;
field public int preamble;
field public int requestType;
+ field public boolean secure;
}
public static class RttManager.RttResult {
@@ -20846,6 +20847,7 @@
field public deprecated long rtt_sd_ns;
field public deprecated long rtt_spread_ns;
field public int rxRate;
+ field public boolean secure;
field public int status;
field public int successMeasurementFrameNumber;
field public long ts;
diff --git a/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java b/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java
deleted file mode 100644
index 7088650..0000000
--- a/core/tests/utiltests/src/com/android/internal/util/AsyncChannelTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import android.os.Debug;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import junit.framework.TestCase;
-
-/**
- * Test for AsyncChannel.
- */
-public class AsyncChannelTest extends TestCase {
- private static final boolean DBG = true;
- private static final boolean WAIT_FOR_DEBUGGER = false;
- private static final String TAG = "AsyncChannelTest";
-
- @SmallTest
- public void test1() throws Exception {
- if (DBG) log("test1");
- if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
- assertTrue(1 == 1);
- }
-
- protected void log(String s) {
- Log.d(TAG, s);
- }
-}
diff --git a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
index 2a2c24e..302aa87 100644
--- a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
@@ -25,6 +25,7 @@
import android.os.Message;
import android.os.SystemClock;
+import android.test.suitebuilder.annotation.Suppress;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.StateMachine.LogRec;
@@ -38,6 +39,7 @@
/**
* Test for StateMachine.
*/
+@Suppress // Failing
public class StateMachineTest extends TestCase {
private static final String ENTER = "enter";
private static final String EXIT = "exit";
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 9137d9d..249f64f 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -324,6 +324,11 @@
public int requestType;
/**
+ * Whether the secure RTT protocol needs to be used for ranging this peer device.
+ */
+ public boolean secure;
+
+ /**
* mac address of the device being ranged
* Default value: null
*/
@@ -478,6 +483,7 @@
for (RttParams params : mParams) {
dest.writeInt(params.deviceType);
dest.writeInt(params.requestType);
+ dest.writeByte(params.secure ? (byte) 1 : 0);
dest.writeString(params.bssid);
dest.writeInt(params.channelWidth);
dest.writeInt(params.frequency);
@@ -515,6 +521,7 @@
params[i] = new RttParams();
params[i].deviceType = in.readInt();
params[i].requestType = in.readInt();
+ params[i].secure = (in.readByte() != 0);
params[i].bssid = in.readString();
params[i].channelWidth = in.readInt();
params[i].frequency = in.readInt();
@@ -690,6 +697,11 @@
/** LCR information Element, only available to double side RTT. */
public WifiInformationElement LCR;
+
+ /**
+ * Whether the secure RTT protocol was used for ranging.
+ */
+ public boolean secure;
}
@@ -742,6 +754,7 @@
dest.writeInt((byte) result.LCR.data.length);
dest.writeByte(result.LCR.id);
}
+ dest.writeByte(result.secure ? (byte) 1 : 0);
}
} else {
dest.writeInt(0);
@@ -796,6 +809,7 @@
results[i].LCR.data = new byte[length];
in.readByteArray(results[i].LCR.data);
}
+ results[i].secure = (in.readByte() != 0);
}
ParcelableRttResults parcelableResults = new ParcelableRttResults(results);
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index a406fd7..964bfa2 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -20,6 +20,7 @@
import android.os.Parcelable;
import android.security.Credentials;
import android.text.TextUtils;
+import android.util.Log;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
@@ -122,6 +123,22 @@
/** {@hide} */
public static final String DISABLE_TLS_1_2 = "\"tls_disable_tlsv1_2=1\"";
+ // Fields to copy verbatim from wpa_supplicant.
+ private static final String[] SUPPLICANT_CONFIG_KEYS = new String[] {
+ IDENTITY_KEY,
+ ANON_IDENTITY_KEY,
+ PASSWORD_KEY,
+ CLIENT_CERT_KEY,
+ CA_CERT_KEY,
+ SUBJECT_MATCH_KEY,
+ ENGINE_KEY,
+ ENGINE_ID_KEY,
+ PRIVATE_KEY_ID_KEY,
+ ALTSUBJECT_MATCH_KEY,
+ DOM_SUFFIX_MATCH_KEY,
+ CA_PATH_KEY
+ };
+
private HashMap<String, String> mFields = new HashMap<String, String>();
//By default, we enable TLS1.2. However, due to a known bug on some radius, we may disable it to
// fall back to TLS 1.1.
@@ -129,6 +146,10 @@
private X509Certificate[] mCaCerts;
private PrivateKey mClientPrivateKey;
private X509Certificate mClientCertificate;
+ private int mEapMethod = Eap.NONE;
+ private int mPhase2Method = Phase2.NONE;
+
+ private static final String TAG = "WifiEnterpriseConfig";
public WifiEnterpriseConfig() {
// Do not set defaults so that the enterprise fields that are not changed
@@ -143,6 +164,8 @@
for (String key : source.mFields.keySet()) {
mFields.put(key, source.mFields.get(key));
}
+ mEapMethod = source.mEapMethod;
+ mPhase2Method = source.mPhase2Method;
}
@Override
@@ -158,6 +181,8 @@
dest.writeString(entry.getValue());
}
+ dest.writeInt(mEapMethod);
+ dest.writeInt(mPhase2Method);
writeCertificates(dest, mCaCerts);
if (mClientPrivateKey != null) {
@@ -210,6 +235,8 @@
enterpriseConfig.mFields.put(key, value);
}
+ enterpriseConfig.mEapMethod = in.readInt();
+ enterpriseConfig.mPhase2Method = in.readInt();
enterpriseConfig.mCaCerts = readCertificates(in);
PrivateKey userKey = null;
@@ -307,7 +334,8 @@
public static final int MSCHAPV2 = 3;
/** Generic Token Card */
public static final int GTC = 4;
- private static final String PREFIX = "auth=";
+ private static final String AUTH_PREFIX = "auth=";
+ private static final String AUTHEAP_PREFIX = "autheap=";
/** @hide */
public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP",
"MSCHAPV2", "GTC" };
@@ -316,11 +344,98 @@
private Phase2() {}
}
- /** Internal use only
+ // Loader and saver interfaces for exchanging data with wpa_supplicant.
+ // TODO: Decouple this object (which is just a placeholder of the configuration)
+ // from the implementation that knows what wpa_supplicant wants.
+ /**
+ * Interface used for retrieving supplicant configuration from WifiEnterpriseConfig
* @hide
*/
- public HashMap<String, String> getFields() {
- return mFields;
+ public interface SupplicantSaver {
+ /**
+ * Set a value within wpa_supplicant configuration
+ * @param key index to set within wpa_supplciant
+ * @param value the value for the key
+ * @return true if successful; false otherwise
+ */
+ boolean saveValue(String key, String value);
+ }
+
+ /**
+ * Interface used for populating a WifiEnterpriseConfig from supplicant configuration
+ * @hide
+ */
+ public interface SupplicantLoader {
+ /**
+ * Returns a value within wpa_supplicant configuration
+ * @param key index to set within wpa_supplciant
+ * @return string value if successful; null otherwise
+ */
+ String loadValue(String key);
+ }
+
+ /**
+ * Internal use only; supply field values to wpa_supplicant config. The configuration
+ * process aborts on the first failed call on {@code saver}.
+ * @param saver proxy for setting configuration in wpa_supplciant
+ * @return whether the save succeeded on all attempts
+ * @hide
+ */
+ public boolean saveToSupplicant(SupplicantSaver saver) {
+ if (!isEapMethodValid()) {
+ return false;
+ }
+
+ for (String key : mFields.keySet()) {
+ if (!saver.saveValue(key, mFields.get(key))) {
+ return false;
+ }
+ }
+
+ if (!saver.saveValue(EAP_KEY, Eap.strings[mEapMethod])) {
+ return false;
+ }
+
+ if (mEapMethod != Eap.TLS && mPhase2Method != Phase2.NONE) {
+ boolean is_autheap = mEapMethod == Eap.TTLS && mPhase2Method == Phase2.GTC;
+ String prefix = is_autheap ? Phase2.AUTHEAP_PREFIX : Phase2.AUTH_PREFIX;
+ String value = convertToQuotedString(prefix + Phase2.strings[mPhase2Method]);
+ return saver.saveValue(PHASE2_KEY, value);
+ } else if (mPhase2Method == Phase2.NONE) {
+ // By default, send a null phase 2 to clear old configuration values.
+ return saver.saveValue(PHASE2_KEY, null);
+ } else {
+ Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies a "
+ + "phase 2 method but the phase1 method does not support it.");
+ return false;
+ }
+ }
+
+ /**
+ * Internal use only; retrieve configuration from wpa_supplicant config.
+ * @param loader proxy for retrieving configuration keys from wpa_supplicant
+ * @hide
+ */
+ public void loadFromSupplicant(SupplicantLoader loader) {
+ for (String key : SUPPLICANT_CONFIG_KEYS) {
+ String value = loader.loadValue(key);
+ if (value == null) {
+ mFields.put(key, EMPTY_VALUE);
+ } else {
+ mFields.put(key, value);
+ }
+ }
+ String eapMethod = loader.loadValue(EAP_KEY);
+ mEapMethod = getStringIndex(Eap.strings, eapMethod, Eap.NONE);
+
+ String phase2Method = removeDoubleQuotes(loader.loadValue(PHASE2_KEY));
+ // Remove "auth=" or "autheap=" prefix.
+ if (phase2Method.startsWith(Phase2.AUTH_PREFIX)) {
+ phase2Method = phase2Method.substring(Phase2.AUTH_PREFIX.length());
+ } else if (phase2Method.startsWith(Phase2.AUTHEAP_PREFIX)) {
+ phase2Method = phase2Method.substring(Phase2.AUTHEAP_PREFIX.length());
+ }
+ mPhase2Method = getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
}
/**
@@ -341,7 +456,7 @@
case Eap.SIM:
case Eap.AKA:
case Eap.AKA_PRIME:
- mFields.put(EAP_KEY, Eap.strings[eapMethod]);
+ mEapMethod = eapMethod;
mFields.put(OPP_KEY_CACHING, "1");
break;
default:
@@ -374,8 +489,7 @@
* @return eap method configured
*/
public int getEapMethod() {
- String eapMethod = mFields.get(EAP_KEY);
- return getStringIndex(Eap.strings, eapMethod, Eap.NONE);
+ return mEapMethod;
}
/**
@@ -390,15 +504,11 @@
public void setPhase2Method(int phase2Method) {
switch (phase2Method) {
case Phase2.NONE:
- mFields.put(PHASE2_KEY, EMPTY_VALUE);
- break;
- /** Valid methods */
case Phase2.PAP:
case Phase2.MSCHAP:
case Phase2.MSCHAPV2:
case Phase2.GTC:
- mFields.put(PHASE2_KEY, convertToQuotedString(
- Phase2.PREFIX + Phase2.strings[phase2Method]));
+ mPhase2Method = phase2Method;
break;
default:
throw new IllegalArgumentException("Unknown Phase 2 method");
@@ -410,12 +520,7 @@
* @return a phase 2 method defined at {@link Phase2}
* */
public int getPhase2Method() {
- String phase2Method = removeDoubleQuotes(mFields.get(PHASE2_KEY));
- // Remove auth= prefix
- if (phase2Method.startsWith(Phase2.PREFIX)) {
- phase2Method = phase2Method.substring(Phase2.PREFIX.length());
- }
- return getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
+ return mPhase2Method;
}
/**
@@ -443,7 +548,8 @@
setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity, "");
}
- /** Get the anonymous identity
+ /**
+ * Get the anonymous identity
* @return anonymous identity
*/
public String getAnonymousIdentity() {
@@ -870,18 +976,15 @@
}
/** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */
- String getKeyId(WifiEnterpriseConfig current) {
- String eap = mFields.get(EAP_KEY);
- String phase2 = mFields.get(PHASE2_KEY);
-
- // If either eap or phase2 are not initialized, use current config details
- if (TextUtils.isEmpty((eap))) {
- eap = current.mFields.get(EAP_KEY);
+ public String getKeyId(WifiEnterpriseConfig current) {
+ // If EAP method is not initialized, use current config details
+ if (mEapMethod == Eap.NONE) {
+ return (current != null) ? current.getKeyId(null) : EMPTY_VALUE;
}
- if (TextUtils.isEmpty(phase2)) {
- phase2 = current.mFields.get(PHASE2_KEY);
+ if (!isEapMethodValid()) {
+ return EMPTY_VALUE;
}
- return eap + "_" + phase2;
+ return Eap.strings[mEapMethod] + "_" + Phase2.strings[mPhase2Method];
}
private String removeDoubleQuotes(String string) {
@@ -898,7 +1001,8 @@
return "\"" + string + "\"";
}
- /** Returns the index at which the toBeFound string is found in the array.
+ /**
+ * Returns the index at which the toBeFound string is found in the array.
* @param arr array of strings
* @param toBeFound string to be found
* @param defaultIndex default index to be returned when string is not found
@@ -912,13 +1016,16 @@
return defaultIndex;
}
- /** Returns the field value for the key.
+ /**
+ * Returns the field value for the key.
* @param key into the hash
* @param prefix is the prefix that the value may have
* @return value
* @hide
*/
public String getFieldValue(String key, String prefix) {
+ // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
+ // neither of these keys should be retrieved in this manner.
String value = mFields.get(key);
// Uninitialized or known to be empty after reading from supplicant
if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
@@ -931,13 +1038,16 @@
}
}
- /** Set a value with an optional prefix at key
+ /**
+ * Set a value with an optional prefix at key
* @param key into the hash
* @param value to be set
* @param prefix an optional value to be prefixed to actual value
* @hide
*/
public void setFieldValue(String key, String value, String prefix) {
+ // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
+ // neither of these keys should be set in this manner.
if (TextUtils.isEmpty(value)) {
mFields.put(key, EMPTY_VALUE);
} else {
@@ -946,13 +1056,16 @@
}
- /** Set a value with an optional prefix at key
+ /**
+ * Set a value with an optional prefix at key
* @param key into the hash
* @param value to be set
* @param prefix an optional value to be prefixed to actual value
* @hide
*/
public void setFieldValue(String key, String value) {
+ // TODO: Should raise an exception if |key| is EAP_KEY or PHASE2_KEY since
+ // neither of these keys should be set in this manner.
if (TextUtils.isEmpty(value)) {
mFields.put(key, EMPTY_VALUE);
} else {
@@ -968,4 +1081,25 @@
}
return sb.toString();
}
+
+ /**
+ * Returns whether the EAP method data is valid, i.e., whether mEapMethod and mPhase2Method
+ * are valid indices into {@code Eap.strings[]} and {@code Phase2.strings[]} respectively.
+ */
+ private boolean isEapMethodValid() {
+ if (mEapMethod == Eap.NONE) {
+ Log.e(TAG, "WiFi enterprise configuration is invalid as it supplies no EAP method.");
+ return false;
+ }
+ if (mEapMethod < 0 || mEapMethod >= Eap.strings.length) {
+ Log.e(TAG, "mEapMethod is invald for WiFi enterprise configuration: " + mEapMethod);
+ return false;
+ }
+ if (mPhase2Method < 0 || mPhase2Method >= Phase2.strings.length) {
+ Log.e(TAG, "mPhase2Method is invald for WiFi enterprise configuration: "
+ + mPhase2Method);
+ return false;
+ }
+ return true;
+ }
}