summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-01-08 19:06:11 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-01-08 19:06:11 +0000
commit5fd1c97e34e54cd74c304cacf5c3ccdaaa7a7e13 (patch)
treeebf7dbac9c8eaeda26c924c135adc7ba66183611
parent4eac4338de9bf4393fba9cb071f513dc3b0c4f81 (diff)
parent4f176150667b518ac77b9e71282d3b03670a5d73 (diff)
Merge "ScanResult: Add radio chain information"
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java70
-rw-r--r--wifi/tests/src/android/net/wifi/ScanResultTest.java193
2 files changed, 263 insertions, 0 deletions
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index b6ad92614bfe..eaad137b9b6e 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -21,7 +21,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* Describes information about a detected access point. In addition
@@ -227,6 +229,50 @@ public class ScanResult implements Parcelable {
public long seen;
/**
+ * On devices with multiple hardware radio chains, this class provides metadata about
+ * each radio chain that was used to receive this scan result (probe response or beacon).
+ * {@hide}
+ */
+ public static class RadioChainInfo {
+ /** Vendor defined id for a radio chain. */
+ public int id;
+ /** Detected signal level in dBm (also known as the RSSI) on this radio chain. */
+ public int level;
+
+ @Override
+ public String toString() {
+ return "RadioChainInfo: id=" + id + ", level=" + level;
+ }
+
+ @Override
+ public boolean equals(Object otherObj) {
+ if (this == otherObj) {
+ return true;
+ }
+ if (!(otherObj instanceof RadioChainInfo)) {
+ return false;
+ }
+ RadioChainInfo other = (RadioChainInfo) otherObj;
+ return id == other.id && level == other.level;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, level);
+ }
+ };
+
+ /**
+ * Information about the list of the radio chains used to receive this scan result
+ * (probe response or beacon).
+ *
+ * For Example: On devices with 2 hardware radio chains, this list could hold 1 or 2
+ * entries based on whether this scan result was received using one or both the chains.
+ * {@hide}
+ */
+ public RadioChainInfo[] radioChainInfos;
+
+ /**
* @hide
* Update RSSI of the scan result
* @param previousRssi
@@ -481,6 +527,7 @@ public class ScanResult implements Parcelable {
this.isCarrierAp = false;
this.carrierApEapType = UNSPECIFIED;
this.carrierName = null;
+ this.radioChainInfos = null;
}
/** {@hide} */
@@ -502,6 +549,7 @@ public class ScanResult implements Parcelable {
this.isCarrierAp = false;
this.carrierApEapType = UNSPECIFIED;
this.carrierName = null;
+ this.radioChainInfos = null;
}
/** {@hide} */
@@ -530,6 +578,7 @@ public class ScanResult implements Parcelable {
this.isCarrierAp = false;
this.carrierApEapType = UNSPECIFIED;
this.carrierName = null;
+ this.radioChainInfos = null;
}
/** {@hide} */
@@ -572,6 +621,7 @@ public class ScanResult implements Parcelable {
isCarrierAp = source.isCarrierAp;
carrierApEapType = source.carrierApEapType;
carrierName = source.carrierName;
+ radioChainInfos = source.radioChainInfos;
}
}
@@ -615,6 +665,7 @@ public class ScanResult implements Parcelable {
sb.append(", Carrier AP: ").append(isCarrierAp ? "yes" : "no");
sb.append(", Carrier AP EAP Type: ").append(carrierApEapType);
sb.append(", Carrier name: ").append(carrierName);
+ sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
return sb.toString();
}
@@ -687,6 +738,16 @@ public class ScanResult implements Parcelable {
dest.writeInt(isCarrierAp ? 1 : 0);
dest.writeInt(carrierApEapType);
dest.writeString(carrierName);
+
+ if (radioChainInfos != null) {
+ dest.writeInt(radioChainInfos.length);
+ for (int i = 0; i < radioChainInfos.length; i++) {
+ dest.writeInt(radioChainInfos[i].id);
+ dest.writeInt(radioChainInfos[i].level);
+ }
+ } else {
+ dest.writeInt(0);
+ }
}
/** Implement the Parcelable interface {@hide} */
@@ -759,6 +820,15 @@ public class ScanResult implements Parcelable {
sr.isCarrierAp = in.readInt() != 0;
sr.carrierApEapType = in.readInt();
sr.carrierName = in.readString();
+ n = in.readInt();
+ if (n != 0) {
+ sr.radioChainInfos = new RadioChainInfo[n];
+ for (int i = 0; i < n; i++) {
+ sr.radioChainInfos[i] = new RadioChainInfo();
+ sr.radioChainInfos[i].id = in.readInt();
+ sr.radioChainInfos[i].level = in.readInt();
+ }
+ }
return sr;
}
diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java
new file mode 100644
index 000000000000..689ebbafe527
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2018 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 android.net.wifi;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.validateMockitoUsage;
+
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.net.wifi.WifiScanner.ScanSettings;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiScanner}.
+ */
+@SmallTest
+public class ScanResultTest {
+ public static final String TEST_SSID = "\"test_ssid\"";
+ public static final String TEST_BSSID = "04:ac:fe:45:34:10";
+ public static final String TEST_CAPS = "CCMP";
+ public static final int TEST_LEVEL = -56;
+ public static final int TEST_FREQUENCY = 2412;
+ public static final long TEST_TSF = 04660l;
+
+ /**
+ * Setup before tests.
+ */
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ /**
+ * Clean up after tests.
+ */
+ @After
+ public void cleanup() {
+ validateMockitoUsage();
+ }
+
+ /**
+ * Verify parcel read/write for ScanResult.
+ */
+ @Test
+ public void verifyScanResultParcelWithoutRadioChainInfo() throws Exception {
+ ScanResult writeScanResult = createScanResult();
+ ScanResult readScanResult = parcelReadWrite(writeScanResult);
+ assertScanResultEquals(writeScanResult, readScanResult);
+ }
+
+ /**
+ * Verify parcel read/write for ScanResult.
+ */
+ @Test
+ public void verifyScanResultParcelWithZeroRadioChainInfo() throws Exception {
+ ScanResult writeScanResult = createScanResult();
+ writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[0];
+ ScanResult readScanResult = parcelReadWrite(writeScanResult);
+ assertNull(readScanResult.radioChainInfos);
+ }
+
+ /**
+ * Verify parcel read/write for ScanResult.
+ */
+ @Test
+ public void verifyScanResultParcelWithRadioChainInfo() throws Exception {
+ ScanResult writeScanResult = createScanResult();
+ writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
+ writeScanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
+ writeScanResult.radioChainInfos[0].id = 0;
+ writeScanResult.radioChainInfos[0].level = -45;
+ writeScanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
+ writeScanResult.radioChainInfos[1].id = 1;
+ writeScanResult.radioChainInfos[1].level = -54;
+ ScanResult readScanResult = parcelReadWrite(writeScanResult);
+ assertScanResultEquals(writeScanResult, readScanResult);
+ }
+
+ /**
+ * Verify copy constructor for ScanResult.
+ */
+ @Test
+ public void verifyScanResultCopyWithoutRadioChainInfo() throws Exception {
+ ScanResult scanResult = createScanResult();
+ ScanResult copyScanResult = new ScanResult(scanResult);
+ assertScanResultEquals(scanResult, copyScanResult);
+ }
+
+ /**
+ * Verify copy constructor for ScanResult.
+ */
+ @Test
+ public void verifyScanResultCopyWithRadioChainInfo() throws Exception {
+ ScanResult scanResult = createScanResult();
+ scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
+ scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
+ scanResult.radioChainInfos[0].id = 0;
+ scanResult.radioChainInfos[0].level = -45;
+ scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
+ scanResult.radioChainInfos[1].id = 1;
+ scanResult.radioChainInfos[1].level = -54;
+ ScanResult copyScanResult = new ScanResult(scanResult);
+ assertScanResultEquals(scanResult, copyScanResult);
+ }
+
+ /**
+ * Verify toString for ScanResult.
+ */
+ @Test
+ public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception {
+ ScanResult scanResult = createScanResult();
+ assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " +
+ "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), distanceSd: 0(cm), " +
+ "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " +
+ "80211mcResponder: is not supported, Carrier AP: no, " +
+ "Carrier AP EAP Type: 0, Carrier name: null, " +
+ "Radio Chain Infos: null", scanResult.toString());
+ }
+
+ /**
+ * Verify toString for ScanResult.
+ */
+ @Test
+ public void verifyScanResultToStringWithRadioChainInfo() throws Exception {
+ ScanResult scanResult = createScanResult();
+ scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
+ scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
+ scanResult.radioChainInfos[0].id = 0;
+ scanResult.radioChainInfos[0].level = -45;
+ scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
+ scanResult.radioChainInfos[1].id = 1;
+ scanResult.radioChainInfos[1].level = -54;
+ assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, " +
+ "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), distanceSd: 0(cm), " +
+ "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, " +
+ "80211mcResponder: is not supported, Carrier AP: no, " +
+ "Carrier AP EAP Type: 0, Carrier name: null, " +
+ "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, " +
+ "RadioChainInfo: id=1, level=-54]", scanResult.toString());
+ }
+
+ /**
+ * Write the provided {@link ScanResult} to a parcel and deserialize it.
+ */
+ private static ScanResult parcelReadWrite(ScanResult writeResult) throws Exception {
+ Parcel parcel = Parcel.obtain();
+ writeResult.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ return ScanResult.CREATOR.createFromParcel(parcel);
+ }
+
+ private static ScanResult createScanResult() {
+ ScanResult result = new ScanResult();
+ result.wifiSsid = WifiSsid.createFromAsciiEncoded(TEST_SSID);
+ result.BSSID = TEST_BSSID;
+ result.capabilities = TEST_CAPS;
+ result.level = TEST_LEVEL;
+ result.frequency = TEST_FREQUENCY;
+ result.timestamp = TEST_TSF;
+ return result;
+ }
+
+ private static void assertScanResultEquals(ScanResult expected, ScanResult actual) {
+ assertEquals(expected.SSID, actual.SSID);
+ assertEquals(expected.BSSID, actual.BSSID);
+ assertEquals(expected.capabilities, actual.capabilities);
+ assertEquals(expected.level, actual.level);
+ assertEquals(expected.frequency, actual.frequency);
+ assertEquals(expected.timestamp, actual.timestamp);
+ assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos);
+ }
+}