[WifiVendorHal] RingBufferLogging
Test: unit tests added
Bug: 34902105
Change-Id: I6411ad720fe537bd2b97b22b180762c4c9e48145
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 32b1768..165285b 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -2678,6 +2678,11 @@
int readBytes;
int writtenRecords;
+ // Bit masks for interpreting |flag|
+ public static final int HAS_BINARY_ENTRIES = (1 << 0);
+ public static final int HAS_ASCII_ENTRIES = (1 << 1);
+ public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
+
@Override
public String toString() {
return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index b099eda..1c2502b 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -25,6 +25,8 @@
import android.hardware.wifi.V1_0.StaRoamingConfig;
import android.hardware.wifi.V1_0.StaRoamingState;
import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.net.apf.ApfCapabilities;
@@ -43,6 +45,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.connectivity.KeepalivePacketData;
+import com.android.server.wifi.util.BitMask;
import com.android.server.wifi.util.NativeUtil;
import java.util.ArrayList;
@@ -671,7 +674,24 @@
public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxIntervalInSec,
int minDataSizeInBytes, String ringName) {
kilroy();
- throw new UnsupportedOperationException();
+ synchronized (sLock) {
+ try {
+ if (mIWifiChip == null) return false;
+ kilroy();
+ // note - flags are not used
+ WifiStatus status = mIWifiChip.startLoggingToDebugRingBuffer(
+ ringName,
+ verboseLevel,
+ maxIntervalInSec,
+ minDataSizeInBytes
+ );
+ return status.code == WifiStatusCode.SUCCESS;
+ } catch (RemoteException e) {
+ kilroy();
+ handleRemoteException(e);
+ return false;
+ }
+ }
}
/**
@@ -736,11 +756,81 @@
}
/**
+ * Creates RingBufferStatus from the Hal version
+ */
+ private static WifiNative.RingBufferStatus ringBufferStatus(WifiDebugRingBufferStatus h) {
+ WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus();
+ ans.name = h.ringName;
+ ans.flag = frameworkRingBufferFlagsFromHal(h.flags);
+ ans.ringBufferId = h.ringId;
+ ans.ringBufferByteSize = h.sizeInBytes;
+ ans.verboseLevel = h.verboseLevel;
+ // Remaining fields are unavailable
+ // writtenBytes;
+ // readBytes;
+ // writtenRecords;
+ return ans;
+ }
+
+ /**
+ * Translates a hal wifiDebugRingBufferFlag to the WifiNative version
+ */
+ private static int frameworkRingBufferFlagsFromHal(int wifiDebugRingBufferFlag) {
+ BitMask checkoff = new BitMask(wifiDebugRingBufferFlag);
+ int flags = 0;
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES;
+ }
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES;
+ }
+ if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) {
+ flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES;
+ }
+ if (checkoff.value != 0) {
+ throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value);
+ }
+ return flags;
+ }
+
+ /**
+ * Creates array of RingBufferStatus from the Hal version
+ */
+ private static WifiNative.RingBufferStatus[] makeRingBufferStatusArray(
+ ArrayList<WifiDebugRingBufferStatus> ringBuffers) {
+ WifiNative.RingBufferStatus[] ans = new WifiNative.RingBufferStatus[ringBuffers.size()];
+ int i = 0;
+ for (WifiDebugRingBufferStatus b : ringBuffers) {
+ ans[i++] = ringBufferStatus(b);
+ }
+ return ans;
+ }
+
+ /**
* API to get the status of all ring buffers supported by driver
*/
public WifiNative.RingBufferStatus[] getRingBufferStatus() {
kilroy();
- throw new UnsupportedOperationException();
+ class AnswerBox {
+ public WifiNative.RingBufferStatus[] value = null;
+ }
+ AnswerBox ans = new AnswerBox();
+ synchronized (sLock) {
+ if (mIWifiChip == null) return null;
+ try {
+ kilroy();
+ mIWifiChip.getDebugRingBuffersStatus((status, ringBuffers) -> {
+ kilroy();
+ if (status.code != WifiStatusCode.SUCCESS) return;
+ ans.value = makeRingBufferStatusArray(ringBuffers);
+ });
+ } catch (RemoteException e) {
+ kilroy();
+ handleRemoteException(e);
+ return null;
+ }
+ }
+ return ans.value;
}
/**
@@ -749,7 +839,17 @@
*/
public boolean getRingBufferData(String ringName) {
kilroy();
- throw new UnsupportedOperationException();
+ synchronized (sLock) {
+ try {
+ if (mIWifiChip == null) return false;
+ kilroy();
+ WifiStatus status = mIWifiChip.forceDumpToDebugRingBuffer(ringName);
+ return status.code == WifiStatusCode.SUCCESS;
+ } catch (RemoteException e) {
+ handleRemoteException(e);
+ return false;
+ }
+ }
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index eabcad0..3a4feb1 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -23,20 +23,22 @@
import android.hardware.wifi.V1_0.IWifiRttController;
import android.hardware.wifi.V1_0.IWifiStaIface;
import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
+import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel;
import android.hardware.wifi.V1_0.WifiStatus;
import android.hardware.wifi.V1_0.WifiStatusCode;
import android.net.apf.ApfCapabilities;
import android.net.wifi.WifiManager;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.RemoteException;
import com.android.server.wifi.util.NativeUtil;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.RemoteException;
-
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -497,4 +499,108 @@
verify(mIWifiApIface).setCountryCode(eq(expected));
}
+
+ /**
+ * Test that startLoggingToDebugRingBuffer is plumbed to chip
+ *
+ * A call before the vendor hal is started should just return false.
+ * After starting in STA mode, the call should succeed, and pass ther right things down.
+ */
+ @Test
+ public void testStartLoggingRingBuffer() throws Exception {
+ when(mIWifiChip.startLoggingToDebugRingBuffer(
+ any(String.class), anyInt(), anyInt(), anyInt()
+ )).thenReturn(mWifiStatusSuccess);
+
+ assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
+ assertTrue(mWifiVendorHal.startVendorHalSta());
+ assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
+
+ verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
+ }
+
+ /**
+ * Same test as testStartLoggingRingBuffer, but in AP mode rather than STA.
+ */
+ @Test
+ public void testStartLoggingRingBufferOnAp() throws Exception {
+ when(mIWifiChip.startLoggingToDebugRingBuffer(
+ any(String.class), anyInt(), anyInt(), anyInt()
+ )).thenReturn(mWifiStatusSuccess);
+
+ assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
+ assertTrue(mWifiVendorHal.startVendorHalAp());
+ assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
+
+ verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
+ }
+
+ /**
+ * Test that getRingBufferStatus gets and translates its stuff correctly
+ */
+ @Test
+ public void testRingBufferStatus() throws Exception {
+ WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus();
+ one.ringName = "One";
+ one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES;
+ one.ringId = 5607371;
+ one.sizeInBytes = 54321;
+ one.freeSizeInBytes = 42;
+ one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE;
+ String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321"
+ + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0";
+
+ WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus();
+ two.ringName = "Two";
+ two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES
+ | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES;
+ two.ringId = 4512470;
+ two.sizeInBytes = 300;
+ two.freeSizeInBytes = 42;
+ two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT;
+
+ ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2);
+ halBufferStatus.add(one);
+ halBufferStatus.add(two);
+
+ WifiNative.RingBufferStatus[] actual;
+
+ doAnswer(new AnswerWithArguments() {
+ public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb)
+ throws RemoteException {
+ cb.onValues(mWifiStatusSuccess, halBufferStatus);
+ }
+ }).when(mIWifiChip).getDebugRingBuffersStatus(any(
+ IWifiChip.getDebugRingBuffersStatusCallback.class));
+
+ assertTrue(mWifiVendorHal.startVendorHalSta());
+ actual = mWifiVendorHal.getRingBufferStatus();
+
+ assertEquals(halBufferStatus.size(), actual.length);
+ assertEquals(oneExpect, actual[0].toString());
+ assertEquals(two.ringId, actual[1].ringBufferId);
+
+ }
+
+ /**
+ * Test that getRingBufferData calls forceDumpToDebugRingBuffer
+ *
+ * Try once before hal start, and twice after (one success, one failure).
+ */
+ @Test
+ public void testForceRingBufferDump() throws Exception {
+ when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess);
+ when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure);
+
+ assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started
+
+ assertTrue(mWifiVendorHal.startVendorHalSta());
+
+ assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds
+ assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails
+
+ verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk");
+ verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop");
+ }
+
}