Merge "ScanResult: Add radio chain information"

This commit is contained in:
TreeHugger Robot
2018-01-08 19:06:11 +00:00
committed by Android (Google) Code Review
2 changed files with 263 additions and 0 deletions

View File

@@ -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
@@ -226,6 +228,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
@@ -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;
}

View File

@@ -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);
}
}