Merge "ScanResult: Add radio chain information"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5fd1c97e34
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
193
wifi/tests/src/android/net/wifi/ScanResultTest.java
Normal file
193
wifi/tests/src/android/net/wifi/ScanResultTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user