summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java10
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pNative.java77
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java28
-rw-r--r--tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java183
5 files changed, 272 insertions, 29 deletions
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index 5bc52d429..a5e461eaf 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -76,6 +76,9 @@ public class HalDeviceManager {
private final Clock mClock;
+ // cache the value for supporting vendor HAL or not
+ private boolean mIsVendorHalSupported = false;
+
// public API
public HalDeviceManager(Clock clock) {
mClock = clock;
@@ -134,7 +137,7 @@ public class HalDeviceManager {
* Returns whether the vendor HAL is supported on this device or not.
*/
public boolean isSupported() {
- return isSupportedInternal();
+ return mIsVendorHalSupported;
}
/**
@@ -611,7 +614,7 @@ public class HalDeviceManager {
private void initializeInternal() {
initIServiceManagerIfNecessary();
- if (isSupportedInternal()) {
+ if (mIsVendorHalSupported) {
initIWifiIfNecessary();
}
}
@@ -685,6 +688,9 @@ public class HalDeviceManager {
Log.wtf(TAG, "Exception while operating on IServiceManager: " + e);
mServiceManager = null;
}
+
+ // Cache the result for the supporting vendor hal or not
+ mIsVendorHalSupported = isSupportedInternal();
}
}
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index c03c46aad..9826a4cc8 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -210,7 +210,8 @@ public class WifiInjector {
mWifiP2pMonitor = new WifiP2pMonitor(this);
mSupplicantP2pIfaceHal = new SupplicantP2pIfaceHal(mWifiP2pMonitor);
mWifiP2pNative = new WifiP2pNative(
- mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager);
+ mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager,
+ mPropertyService);
// Now get instances of all the objects that depend on the HandlerThreads
mWifiTrafficPoller = new WifiTrafficPoller(clientModeImplLooper);
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
index 3e0aaa145..58ebb60e8 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
@@ -28,6 +28,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.PropertyService;
import com.android.server.wifi.WifiVendorHal;
/**
@@ -41,6 +42,7 @@ public class WifiP2pNative {
private boolean mVerboseLoggingEnabled = false;
private final SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
private final HalDeviceManager mHalDeviceManager;
+ private final PropertyService mPropertyService;
private final WifiVendorHal mWifiVendorHal;
private IWifiP2pIface mIWifiP2pIface;
private InterfaceAvailableListenerInternal mInterfaceAvailableListener;
@@ -104,10 +106,12 @@ public class WifiP2pNative {
}
public WifiP2pNative(WifiVendorHal wifiVendorHal,
- SupplicantP2pIfaceHal p2pIfaceHal, HalDeviceManager halDeviceManager) {
+ SupplicantP2pIfaceHal p2pIfaceHal, HalDeviceManager halDeviceManager,
+ PropertyService propertyService) {
mWifiVendorHal = wifiVendorHal;
mSupplicantP2pIfaceHal = p2pIfaceHal;
mHalDeviceManager = halDeviceManager;
+ mPropertyService = propertyService;
}
/**
@@ -153,6 +157,41 @@ public class WifiP2pNative {
}
/**
+ * Returns whether HAL (HIDL) is supported on this device or not.
+ */
+ public boolean isHalInterfaceSupported() {
+ return mHalDeviceManager.isSupported();
+ }
+
+ private static final String P2P_IFACE_NAME = "p2p0";
+ private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
+ /**
+ * Helper function to handle creation of P2P iface.
+ * For devices which do not the support the HAL, this will bypass HalDeviceManager &
+ * teardown any existing iface.
+ */
+ private String createP2pIface(Handler handler) {
+ if (mHalDeviceManager.isSupported()) {
+ mIWifiP2pIface = mHalDeviceManager
+ .createP2pIface(mInterfaceDestroyedListener, handler);
+ if (mIWifiP2pIface == null) {
+ Log.e(TAG, "Failed to create P2p iface in HalDeviceManager");
+ return null;
+ }
+ String ifaceName = HalDeviceManager.getName(mIWifiP2pIface);
+ if (TextUtils.isEmpty(ifaceName)) {
+ Log.e(TAG, "Failed to get p2p iface name");
+ teardownInterface();
+ return null;
+ }
+ return ifaceName;
+ } else {
+ Log.i(TAG, "Vendor Hal is not supported, ignoring createP2pIface.");
+ return mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
+ }
+ }
+
+ /**
* Register for an interface available callbacks from HalDeviceManager.
*
* @param listener callback to be invoked when the interface is available/not available.
@@ -187,10 +226,11 @@ public class WifiP2pNative {
Handler handler) {
Log.d(TAG, "Setup P2P interface");
if (mIWifiP2pIface == null) {
- mInterfaceDestroyedListener = new InterfaceDestroyedListenerInternal(destroyedListener);
- mIWifiP2pIface = mHalDeviceManager.createP2pIface(mInterfaceDestroyedListener, handler);
- if (mIWifiP2pIface == null) {
- Log.e(TAG, "Failed to create P2p iface in HalDeviceManager");
+ mInterfaceDestroyedListener =
+ new InterfaceDestroyedListenerInternal(destroyedListener);
+ String ifaceName = createP2pIface(handler);
+ if (ifaceName == null) {
+ Log.e(TAG, "Failed to create P2p iface");
return null;
}
if (!waitForSupplicantConnection()) {
@@ -198,20 +238,19 @@ public class WifiP2pNative {
teardownInterface();
return null;
}
- String ifaceName = HalDeviceManager.getName(mIWifiP2pIface);
- if (TextUtils.isEmpty(ifaceName)) {
- Log.e(TAG, "Failed to get p2p iface name");
- teardownInterface();
- return null;
- }
if (!mSupplicantP2pIfaceHal.setupIface(ifaceName)) {
Log.e(TAG, "Failed to setup P2p iface in supplicant");
teardownInterface();
return null;
}
Log.i(TAG, "P2P interface setup completed");
+ return ifaceName;
+ } else {
+ Log.i(TAG, "P2P interface is already existed");
+ return mHalDeviceManager.isSupported()
+ ? HalDeviceManager.getName(mIWifiP2pIface)
+ : mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
}
- return HalDeviceManager.getName(mIWifiP2pIface);
}
/**
@@ -219,11 +258,17 @@ public class WifiP2pNative {
*/
public void teardownInterface() {
Log.d(TAG, "Teardown P2P interface");
- if (mIWifiP2pIface != null) {
- String ifaceName = HalDeviceManager.getName(mIWifiP2pIface);
- mHalDeviceManager.removeIface(mIWifiP2pIface);
+ if (mHalDeviceManager.isSupported()) {
+ if (mIWifiP2pIface != null) {
+ String ifaceName = HalDeviceManager.getName(mIWifiP2pIface);
+ mHalDeviceManager.removeIface(mIWifiP2pIface);
+ mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName);
+ Log.i(TAG, "P2P interface teardown completed");
+ }
+ } else {
+ Log.i(TAG, "HAL (HIDL) is not supported. Destroy listener for the interface.");
+ String ifaceName = mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME);
mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName);
- Log.i(TAG, "P2P interface teardown completed");
}
}
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 3e3da2326..430c5fd20 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -765,8 +765,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
});
private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
private WifiP2pGroup mGroup;
- // Is the P2P interface available for use.
- private boolean mIsInterfaceAvailable = false;
+ // Is the HAL (HIDL) interface available for use.
+ private boolean mIsHalInterfaceAvailable = false;
// Is wifi on or off.
private boolean mIsWifiEnabled = false;
@@ -836,7 +836,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}, new IntentFilter(LocationManager.MODE_CHANGED_ACTION));
// Register for interface availability from HalDeviceManager
mWifiNative.registerInterfaceAvailableListener((boolean isAvailable) -> {
- mIsInterfaceAvailable = isAvailable;
+ mIsHalInterfaceAvailable = isAvailable;
if (isAvailable) {
checkAndReEnableP2p();
}
@@ -1058,7 +1058,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
case WifiP2pManager.REQUEST_P2P_STATE:
replyToMessage(message, WifiP2pManager.RESPONSE_P2P_STATE,
- (mIsWifiEnabled && mIsInterfaceAvailable && isLocationModeEnabled())
+ (mIsWifiEnabled && isHalInterfaceAvailable()
+ && isLocationModeEnabled())
? WifiP2pManager.WIFI_P2P_STATE_ENABLED
: WifiP2pManager.WIFI_P2P_STATE_DISABLED);
break;
@@ -2916,15 +2917,16 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// Check & re-enable P2P if needed.
// P2P interface will be created if all of the below are true:
// a) Wifi is enabled.
- // b) P2P interface is available.
+ // b) HAL (HIDL) interface is available.
// c) There is atleast 1 client app which invoked initialize().
// d) Location is enabled.
private void checkAndReEnableP2p() {
boolean isLocationEnabled = isLocationModeEnabled();
+ boolean isHalInterfaceAvailable = isHalInterfaceAvailable();
Log.d(TAG, "Wifi enabled=" + mIsWifiEnabled + ", P2P Interface availability="
- + mIsInterfaceAvailable + ", Number of clients=" + mDeathDataByBinder.size()
- + ", Location enabled=" + isLocationEnabled);
- if (mIsWifiEnabled && mIsInterfaceAvailable
+ + isHalInterfaceAvailable + ", Number of clients="
+ + mDeathDataByBinder.size() + ", Location enabled=" + isLocationEnabled);
+ if (mIsWifiEnabled && isHalInterfaceAvailable
&& isLocationEnabled && !mDeathDataByBinder.isEmpty()) {
sendMessage(ENABLE_P2P);
}
@@ -2934,11 +2936,17 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
return mWifiPermissionsUtil.isLocationModeEnabled();
}
+ // Ignore judgement if the device do not support HAL (HIDL) interface
+ private boolean isHalInterfaceAvailable() {
+ return mWifiNative.isHalInterfaceSupported() ? mIsHalInterfaceAvailable : true;
+ }
+
private void checkAndSendP2pStateChangedBroadcast() {
boolean isLocationEnabled = isLocationModeEnabled();
+ boolean isHalInterfaceAvailable = isHalInterfaceAvailable();
Log.d(TAG, "Wifi enabled=" + mIsWifiEnabled + ", P2P Interface availability="
- + mIsInterfaceAvailable + ", Location enabled=" + isLocationEnabled);
- sendP2pStateChangedBroadcast(mIsWifiEnabled && mIsInterfaceAvailable
+ + isHalInterfaceAvailable + ", Location enabled=" + isLocationEnabled);
+ sendP2pStateChangedBroadcast(mIsWifiEnabled && isHalInterfaceAvailable
&& isLocationEnabled);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java b/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java
new file mode 100644
index 000000000..962acd01e
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2019 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 com.android.server.wifi.p2p;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.test.MockAnswerUtil;
+import android.hardware.wifi.V1_0.IWifiIface;
+import android.hardware.wifi.V1_0.IWifiP2pIface;
+import android.hardware.wifi.V1_0.IfaceType;
+import android.hardware.wifi.V1_0.WifiStatus;
+import android.hardware.wifi.V1_0.WifiStatusCode;
+import android.os.Handler;
+import android.os.RemoteException;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wifi.HalDeviceManager;
+import com.android.server.wifi.HalDeviceManager.InterfaceAvailableForRequestListener;
+import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
+import com.android.server.wifi.HalDeviceManager.ManagerStatusListener;
+import com.android.server.wifi.PropertyService;
+import com.android.server.wifi.WifiVendorHal;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for the interface management operations in
+ * {@link com.android.server.wifi.WifiP2pNative}.
+ */
+@SmallTest
+public class WifiP2pNativeInterfaceManagementTest {
+ private static final String P2P_IFACE_NAME = "p2p0";
+ private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface";
+
+ @Mock private SupplicantP2pIfaceHal mSupplicantP2pIfaceHal;
+ @Mock private HalDeviceManager mHalDeviceManager;
+ @Mock private PropertyService mPropertyService;
+ @Mock private Handler mHandler;
+ @Mock private InterfaceAvailableForRequestListener mInterfaceRequestListener;
+ @Mock private InterfaceDestroyedListener mHalDeviceInterfaceDestroyedListener;
+ @Mock private IWifiP2pIface mIWifiP2pIface;
+ @Mock private IWifiIface mIWifiIface;
+ @Mock private WifiVendorHal mWifiVendorHal;
+ private WifiP2pNative mWifiP2pNative;
+ private WifiStatus mWifiStatusSuccess;
+ private ManagerStatusListener mManagerStatusListener;
+
+ /**
+ * Sets up for unit test
+ */
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mWifiStatusSuccess = new WifiStatus();
+ mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
+
+ when(mHalDeviceManager.isSupported()).thenReturn(true);
+ when(mHalDeviceManager.createP2pIface(any(InterfaceDestroyedListener.class),
+ any(Handler.class))).thenReturn(mIWifiP2pIface);
+ doAnswer(new MockAnswerUtil.AnswerWithArguments() {
+ public void answer(IWifiIface.getNameCallback cb)
+ throws RemoteException {
+ cb.onValues(mWifiStatusSuccess, P2P_IFACE_NAME);
+ }
+ }).when(mIWifiP2pIface).getName(any(IWifiIface.getNameCallback.class));
+
+ when(mSupplicantP2pIfaceHal.isInitializationStarted()).thenReturn(true);
+ when(mSupplicantP2pIfaceHal.initialize()).thenReturn(true);
+ when(mSupplicantP2pIfaceHal.isInitializationComplete()).thenReturn(true);
+ when(mSupplicantP2pIfaceHal.setupIface(P2P_IFACE_NAME)).thenReturn(true);
+ when(mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME))
+ .thenReturn(P2P_IFACE_NAME);
+
+ mWifiP2pNative = new WifiP2pNative(
+ mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager,
+ mPropertyService);
+ }
+
+ /**
+ * Verifies the HAL (HIDL) interface listener.
+ */
+ @Test
+ public void testRegisterInterfaceAvailableListener() throws Exception {
+ when(mHalDeviceManager.isStarted()).thenReturn(false);
+
+ mWifiP2pNative.registerInterfaceAvailableListener(mInterfaceRequestListener, mHandler);
+ when(mHalDeviceManager.isStarted()).thenReturn(true);
+
+ ArgumentCaptor<ManagerStatusListener> hdmCallbackCaptor =
+ ArgumentCaptor.forClass(ManagerStatusListener.class);
+ verify(mHalDeviceManager).registerStatusListener(hdmCallbackCaptor.capture(), eq(mHandler));
+ // Simulate to call status callback from device hal manager
+ hdmCallbackCaptor.getValue().onStatusChanged();
+
+ verify(mHalDeviceManager).registerInterfaceAvailableForRequestListener(eq(IfaceType.P2P),
+ any(InterfaceAvailableForRequestListener.class), eq(mHandler));
+ }
+
+ /**
+ * Verifies the setup of a p2p interface.
+ */
+ @Test
+ public void testSetUpInterface() throws Exception {
+ assertEquals(P2P_IFACE_NAME,
+ mWifiP2pNative.setupInterface(mHalDeviceInterfaceDestroyedListener, mHandler));
+
+ verify(mHalDeviceManager).createP2pIface(any(InterfaceDestroyedListener.class),
+ eq(mHandler));
+ verify(mSupplicantP2pIfaceHal).setupIface(eq(P2P_IFACE_NAME));
+ }
+
+ /**
+ * Verifies the setup of a p2p interface with no HAL (HIDL) support.
+ */
+ @Test
+ public void testSetUpInterfaceWithNoVendorHal() throws Exception {
+ when(mHalDeviceManager.isSupported()).thenReturn(false);
+
+ assertEquals(P2P_IFACE_NAME, mWifiP2pNative.setupInterface(
+ mHalDeviceInterfaceDestroyedListener, mHandler));
+
+ verify(mHalDeviceManager, never())
+ .createP2pIface(any(InterfaceDestroyedListener.class), any(Handler.class));
+ verify(mSupplicantP2pIfaceHal).setupIface(eq(P2P_IFACE_NAME));
+ }
+
+ /**
+ * Verifies the teardown of a p2p interface.
+ */
+ @Test
+ public void testTeardownInterface() throws Exception {
+ assertEquals(P2P_IFACE_NAME,
+ mWifiP2pNative.setupInterface(mHalDeviceInterfaceDestroyedListener,
+ mHandler));
+
+ mWifiP2pNative.teardownInterface();
+
+ verify(mHalDeviceManager).removeIface(any(IWifiIface.class));
+ verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME));
+ }
+
+ /**
+ * Verifies the teardown of a p2p interface with no HAL (HIDL) support.
+ */
+ @Test
+ public void testTeardownInterfaceWithNoVendorHal() throws Exception {
+ when(mHalDeviceManager.isSupported()).thenReturn(false);
+
+ assertEquals(P2P_IFACE_NAME, mWifiP2pNative.setupInterface(
+ mHalDeviceInterfaceDestroyedListener, mHandler));
+
+ mWifiP2pNative.teardownInterface();
+
+ verify(mHalDeviceManager, never()).removeIface(any(IWifiIface.class));
+ verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME));
+ }
+}