summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2017-05-12 16:45:05 -0700
committerRoshan Pius <rpius@google.com>2017-05-15 13:55:16 -0700
commit30f34829e0e7e49dc09c897c72dd0ded7d9805eb (patch)
tree982702e970d50862fe80e2878a6c953629f0c297
parentb7d05adc1f96fe0b0397e21d91696096322641d5 (diff)
WifiNative: Add VINTF check for vendor HAL
Currently, we're ignoring HAL start failures to support devices like gce, hikey which did not have any vendor HAL support previously. To solve that problem: 1. Remove the Vendor HAL daemon (HIDL shim) from such device's device.mk. Handled by other CL's in the topic. 2. Add the Wifi HAL's to the VINTF (manifest.xml) on all devices which has the Vendor HAL daemon running. (Unfortunately, there is no automatic translation from the module missing in device.mk to manifest.xml currently). Handled by other CL's in the topic. 3. Use the HalDeviceManager to query the VINTF to figure out if the Vendor HAL is present on the device or not. 4a. If the Vendor HAL is not supported, ignore start/stop calls. 4b. If the Vendor HAL is present, report failure if start/stop fails. Also, fixed a few invalid mock expectations set. Bug: 36886769 Test: Device boots up and connects to wifi on 2017 devices. Test: Unit tests. Change-Id: Ia3d90c8fafe2f8c156c843f5f47b94deaabe5a56
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java32
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java27
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java9
-rw-r--r--tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java30
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java64
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java8
6 files changed, 151 insertions, 19 deletions
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index c54be9b9a..b34c944a1 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -67,6 +67,8 @@ public class HalDeviceManager {
// attempt.
@VisibleForTesting
public static final int START_HAL_RETRY_TIMES = 3;
+ @VisibleForTesting
+ public static final String HAL_INSTANCE_NAME = "default";
// public API
public HalDeviceManager() {
@@ -108,6 +110,13 @@ public class HalDeviceManager {
}
/**
+ * Returns whether the vendor HAL is supported on this device or not.
+ */
+ public boolean isSupported() {
+ return isSupportedInternal();
+ }
+
+ /**
* Returns the current status of the HalDeviceManager: whether or not it is ready to execute
* commands. A return of 'false' indicates that the HAL service (IWifi) is not available. Use
* the registerStatusListener() to listener for status changes.
@@ -582,6 +591,29 @@ public class HalDeviceManager {
}
}
+ /**
+ * Uses the IServiceManager to query if the vendor HAL is present in the VINTF for the device
+ * or not.
+ * @return true if supported, false otherwise.
+ */
+ private boolean isSupportedInternal() {
+ if (DBG) Log.d(TAG, "isSupportedInternal");
+
+ synchronized (mLock) {
+ if (mServiceManager == null) {
+ Log.wtf(TAG, "isSupported: called but mServiceManager is null!?");
+ return false;
+ }
+ try {
+ return (mServiceManager.getTransport(IWifi.kInterfaceName, HAL_INSTANCE_NAME)
+ != IServiceManager.Transport.EMPTY);
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
+ return false;
+ }
+ }
+ }
+
private final HwRemoteBinder.DeathRecipient mIWifiDeathRecipient =
cookie -> {
Log.e(TAG, "IWifi HAL service died! Have a listener for it ... cookie=" + cookie);
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index eb2412311..cc0d277a4 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -102,9 +102,9 @@ public class WifiNative {
* Returns null on failure.
*/
public IClientInterface setupForClientMode() {
- if (!startHal(true)) {
- // TODO(b/34859006): Handle failures.
+ if (!startHalIfNecessary(true)) {
Log.e(mTAG, "Failed to start HAL for client mode");
+ return null;
}
return mWificondControl.setupDriverForClientMode();
}
@@ -119,9 +119,9 @@ public class WifiNative {
* Returns null on failure.
*/
public IApInterface setupForSoftApMode() {
- if (!startHal(false)) {
- // TODO(b/34859006): Handle failures.
+ if (!startHalIfNecessary(false)) {
Log.e(mTAG, "Failed to start HAL for AP mode");
+ return null;
}
return mWificondControl.setupDriverForSoftApMode();
}
@@ -140,7 +140,7 @@ public class WifiNative {
Log.e(mTAG, "Failed to teardown interfaces from Wificond");
return false;
}
- stopHal();
+ stopHalIfNecessary();
return true;
}
@@ -802,18 +802,27 @@ public class WifiNative {
}
/**
- * Bring up the Vendor HAL and configure for STA mode or AP mode.
+ * Bring up the Vendor HAL and configure for STA mode or AP mode, if vendor HAL is supported.
*
* @param isStaMode true to start HAL in STA mode, false to start in AP mode.
+ * @return false if the HAL start fails, true if successful or if vendor HAL not supported.
*/
- public boolean startHal(boolean isStaMode) {
+ private boolean startHalIfNecessary(boolean isStaMode) {
+ if (!mWifiVendorHal.isVendorHalSupported()) {
+ Log.i(mTAG, "Vendor HAL not supported, Ignore start...");
+ return true;
+ }
return mWifiVendorHal.startVendorHal(isStaMode);
}
/**
- * Stops the HAL
+ * Stops the HAL, if vendor HAL is supported.
*/
- public void stopHal() {
+ private void stopHalIfNecessary() {
+ if (!mWifiVendorHal.isVendorHalSupported()) {
+ Log.i(mTAG, "Vendor HAL not supported, Ignore stop...");
+ return;
+ }
mWifiVendorHal.stopVendorHal();
}
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index 31c000c59..9c1ae94b5 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -247,6 +247,15 @@ public class WifiVendorHal {
}
/**
+ * Returns whether the vendor HAL is supported on this device or not.
+ */
+ public boolean isVendorHalSupported() {
+ synchronized (sLock) {
+ return mHalDeviceManager.isSupported();
+ }
+ }
+
+ /**
* Bring up the HIDL Vendor HAL and configure for AP (Access Point) mode
*
* @return true for success
diff --git a/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java b/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
index 570100bbf..3e203a666 100644
--- a/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -21,6 +21,8 @@ import static com.android.server.wifi.HalDeviceManager.START_HAL_RETRY_TIMES;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
@@ -1050,6 +1052,34 @@ public class HalDeviceManagerTest {
executeAndValidateStartupSequence(1, false);
}
+ /**
+ * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
+ * the VINTF.
+ */
+ @Test
+ public void testIsSupportedTrue() throws Exception {
+ when(mServiceManagerMock.getTransport(
+ eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
+ .thenReturn(IServiceManager.Transport.HWBINDER);
+ mInOrder = inOrder(mServiceManagerMock, mWifiMock);
+ executeAndValidateInitializationSequence();
+ assertTrue(mDut.isSupported());
+ }
+
+ /**
+ * Validate that isSupported() returns true when IServiceManager finds the vendor HAL daemon in
+ * the VINTF.
+ */
+ @Test
+ public void testIsSupportedFalse() throws Exception {
+ when(mServiceManagerMock.getTransport(
+ eq(IWifi.kInterfaceName), eq(HalDeviceManager.HAL_INSTANCE_NAME)))
+ .thenReturn(IServiceManager.Transport.EMPTY);
+ mInOrder = inOrder(mServiceManagerMock, mWifiMock);
+ executeAndValidateInitializationSequence();
+ assertFalse(mDut.isSupported());
+ }
+
// utilities
private void dumpDut(String prefix) {
StringWriter sw = new StringWriter();
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
index 281c47a07..b1285042d 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -151,6 +152,7 @@ public class WifiNativeTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ when(mWifiVendorHal.isVendorHalSupported()).thenReturn(true);
when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(true);
mWifiNative = new WifiNative("test0", mWifiVendorHal, mStaIfaceHal, mWificondControl);
}
@@ -491,11 +493,27 @@ public class WifiNativeTest {
}
/**
+ * Verifies that setupDriverForClientMode() does not call start vendor HAL when it is not
+ * supported and calls underlying WificondControl setup.
+ */
+ @Test
+ public void testSetupDriverForClientModeWithNoVendorHal() {
+ when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
+ IClientInterface clientInterface = mock(IClientInterface.class);
+ when(mWificondControl.setupDriverForClientMode()).thenReturn(clientInterface);
+
+ IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
+ assertEquals(clientInterface, returnedClientInterface);
+ verify(mWifiVendorHal, never()).startVendorHal(anyBoolean());
+ verify(mWificondControl).setupDriverForClientMode();
+ }
+
+ /**
* Verifies that setupDriverForClientMode() returns null when underlying WificondControl
* call fails.
*/
@Test
- public void testSetupDriverForClientModeError() {
+ public void testSetupDriverForClientModeWificondError() {
when(mWificondControl.setupDriverForClientMode()).thenReturn(null);
IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
@@ -505,6 +523,19 @@ public class WifiNativeTest {
}
/**
+ * Verifies that setupDriverForClientMode() returns null when underlying Hal call fails.
+ */
+ @Test
+ public void testSetupDriverForClientModeHalError() {
+ when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(false);
+
+ IClientInterface returnedClientInterface = mWifiNative.setupForClientMode();
+ assertEquals(null, returnedClientInterface);
+ verify(mWifiVendorHal).startVendorHal(eq(true));
+ verify(mWificondControl, never()).setupDriverForClientMode();
+ }
+
+ /**
* Verifies that setupDriverForSoftApMode() calls underlying WificondControl.
*/
@Test
@@ -519,11 +550,27 @@ public class WifiNativeTest {
}
/**
+ * Verifies that setupDriverForClientMode() does not call start vendor HAL when it is not
+ * supported and calls underlying WificondControl setup.
+ */
+ @Test
+ public void testSetupDriverForSoftApModeWithNoVendorHal() {
+ when(mWifiVendorHal.isVendorHalSupported()).thenReturn(false);
+ IApInterface apInterface = mock(IApInterface.class);
+ when(mWificondControl.setupDriverForSoftApMode()).thenReturn(apInterface);
+
+ IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
+ assertEquals(apInterface, returnedApInterface);
+ verify(mWifiVendorHal, never()).startVendorHal(anyBoolean());
+ verify(mWificondControl).setupDriverForSoftApMode();
+ }
+
+ /**
* Verifies that setupDriverForSoftApMode() returns null when underlying WificondControl
* call fails.
*/
@Test
- public void testSetupDriverForSoftApModeError() {
+ public void testSetupDriverForSoftApModeWificondError() {
when(mWificondControl.setupDriverForSoftApMode()).thenReturn(null);
IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
@@ -533,6 +580,19 @@ public class WifiNativeTest {
}
/**
+ * Verifies that setupDriverForSoftApMode() returns null when underlying Hal call fails.
+ */
+ @Test
+ public void testSetupDriverForSoftApModeHalError() {
+ when(mWifiVendorHal.startVendorHal(anyBoolean())).thenReturn(false);
+
+ IApInterface returnedApInterface = mWifiNative.setupForSoftApMode();
+ assertEquals(null, returnedApInterface);
+ verify(mWifiVendorHal).startVendorHal(eq(false));
+ verify(mWificondControl, never()).setupDriverForSoftApMode();
+ }
+
+ /**
* Verifies that enableSupplicant() calls underlying WificondControl.
*/
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index 2e365a048..1fd6b5782 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -521,14 +521,12 @@ public class WifiStateMachineTest {
@Test
public void loadComponentsFailure() throws Exception {
- when(mWifiNative.startHal(anyBoolean())).thenReturn(false);
when(mWifiNative.enableSupplicant()).thenReturn(false);
mWsm.setSupplicantRunning(true);
mLooper.dispatchAll();
assertEquals("InitialState", getCurrentState().getName());
- when(mWifiNative.startHal(anyBoolean())).thenReturn(true);
mWsm.setSupplicantRunning(true);
mLooper.dispatchAll();
assertEquals("InitialState", getCurrentState().getName());
@@ -548,8 +546,6 @@ public class WifiStateMachineTest {
@Test
public void shouldStartSupplicantWhenConnectModeRequested() throws Exception {
- when(mWifiNative.startHal(anyBoolean())).thenReturn(true);
-
// The first time we start out in InitialState, we sit around here.
mLooper.dispatchAll();
assertEquals("InitialState", getCurrentState().getName());
@@ -566,8 +562,6 @@ public class WifiStateMachineTest {
*/
@Test
public void checkIsWifiEnabledForModeChanges() throws Exception {
- when(mWifiNative.startHal(anyBoolean())).thenReturn(true);
-
// Check initial state
mLooper.dispatchAll();
assertEquals("InitialState", getCurrentState().getName());
@@ -638,8 +632,6 @@ public class WifiStateMachineTest {
*/
@Test
public void checkStartInCorrectStateAfterChangingInitialState() throws Exception {
- when(mWifiNative.startHal(anyBoolean())).thenReturn(true);
-
// Check initial state
mLooper.dispatchAll();
assertEquals("InitialState", getCurrentState().getName());