diff options
7 files changed, 647 insertions, 136 deletions
diff --git a/flags/wifi_flags.aconfig b/flags/wifi_flags.aconfig index 1fb14cc8ec..304dcd0900 100644 --- a/flags/wifi_flags.aconfig +++ b/flags/wifi_flags.aconfig @@ -161,4 +161,11 @@ flag { description: "For new API added to Android V" bug: "319927407" is_fixed_read_only: true -}
\ No newline at end of file +} + +flag { + name: "d2d_usage_when_wifi_off" + namespace: "wifi" + description: "Add new API to configure d2d usage when wifi is off" + bug: "295792510" +} diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 9b9a456cdd..de96c660e9 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -355,7 +355,7 @@ public class WifiInjector { mWifiP2pMonitor = new WifiP2pMonitor(); mSupplicantP2pIfaceHal = new SupplicantP2pIfaceHal(mWifiP2pMonitor, mWifiGlobals, this); mWifiP2pNative = new WifiP2pNative(mWifiCondManager, mWifiNative, mWifiMetrics, - mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService); + mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService, this); SubscriptionManager subscriptionManager = mContext.getSystemService(SubscriptionManager.class); if (SdkLevel.isAtLeastS()) { diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index bda8d1d755..b27f055d42 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -22,6 +22,8 @@ import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP; import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE; import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA; import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_FEATURES; +import static com.android.server.wifi.p2p.WifiP2pNative.P2P_IFACE_NAME; +import static com.android.server.wifi.p2p.WifiP2pNative.P2P_INTERFACE_PROPERTY; import android.annotation.IntDef; import android.annotation.NonNull; @@ -348,13 +350,15 @@ public class WifiNative { /** * Meta-info about every iface that is active. */ - private static class Iface { + public static class Iface { /** Type of ifaces possible */ public static final int IFACE_TYPE_AP = 0; public static final int IFACE_TYPE_STA_FOR_CONNECTIVITY = 1; public static final int IFACE_TYPE_STA_FOR_SCAN = 2; + public static final int IFACE_TYPE_P2P = 3; - @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA_FOR_CONNECTIVITY, IFACE_TYPE_STA_FOR_SCAN}) + @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA_FOR_CONNECTIVITY, IFACE_TYPE_STA_FOR_SCAN, + IFACE_TYPE_P2P}) @Retention(RetentionPolicy.SOURCE) public @interface IfaceType{} @@ -1197,6 +1201,67 @@ public class WifiNative { } } + private String createP2pIfaceFromHalOrGetNameFromProperty( + HalDeviceManager.InterfaceDestroyedListener p2pInterfaceDestroyedListener, + Handler handler, WorkSource requestorWs) { + synchronized (mLock) { + if (mWifiVendorHal.isVendorHalSupported()) { + return mWifiInjector.getHalDeviceManager().createP2pIface( + p2pInterfaceDestroyedListener, handler, requestorWs); + } else { + Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface."); + return mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); + } + } + } + + /** + * 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. + */ + public Iface createP2pIface( + HalDeviceManager.InterfaceDestroyedListener p2pInterfaceDestroyedListener, + Handler handler, WorkSource requestorWs) { + synchronized (mLock) { + // Make sure HAL is started for p2p + if (!startHal()) { + Log.e(TAG, "Failed to start Hal"); + mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal(); + return null; + } + // maintain iface status in WifiNative + Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_P2P); + if (iface == null) { + Log.e(TAG, "Failed to allocate new P2P iface"); + stopHalAndWificondIfNecessary(); + return null; + } + iface.name = createP2pIfaceFromHalOrGetNameFromProperty( + p2pInterfaceDestroyedListener, handler, requestorWs); + if (TextUtils.isEmpty(iface.name)) { + Log.e(TAG, "Failed to create P2p iface in HalDeviceManager"); + mIfaceMgr.removeIface(iface.id); + mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal(); + stopHalAndWificondIfNecessary(); + return null; + } + return iface; + } + } + + /** + * Teardown P2p iface with input interface Id which was returned by createP2pIface. + * + * @param interfaceId the interface identify which was gerenated when creating P2p iface. + */ + public void teardownP2pIface(int interfaceId) { + synchronized (mLock) { + mIfaceMgr.removeIface(interfaceId); + stopHalAndWificondIfNecessary(); + } + } + /** * Get list of instance name from this bridged AP iface. * diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java index c85dd7ffdf..d67f060f71 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java @@ -37,9 +37,11 @@ import android.util.Log; import com.android.server.wifi.HalDeviceManager; import com.android.server.wifi.PropertyService; +import com.android.server.wifi.WifiInjector; import com.android.server.wifi.WifiMetrics; import com.android.server.wifi.WifiNative; import com.android.server.wifi.WifiVendorHal; +import com.android.wifi.flags.FeatureFlags; import java.util.HashSet; import java.util.List; @@ -59,10 +61,13 @@ public class WifiP2pNative { private final HalDeviceManager mHalDeviceManager; private final PropertyService mPropertyService; private final WifiVendorHal mWifiVendorHal; + private final WifiInjector mWifiInjector; + private final FeatureFlags mFeatureFlags; + private final Object mLock = new Object(); + private WifiNative.Iface mP2pIface; private String mP2pIfaceName; private InterfaceDestroyedListenerInternal mInterfaceDestroyedListener; - // Internal callback registered to HalDeviceManager. private class InterfaceDestroyedListenerInternal implements HalDeviceManager.InterfaceDestroyedListener { @@ -76,22 +81,31 @@ public class WifiP2pNative { } public void teardownAndInvalidate(@Nullable String ifaceName) { - if (!TextUtils.isEmpty(ifaceName)) { - mSupplicantP2pIfaceHal.teardownIface(ifaceName); + synchronized (mLock) { + if (!TextUtils.isEmpty(ifaceName)) { + mSupplicantP2pIfaceHal.teardownIface(ifaceName); + if (mP2pIface != null) { + mWifiNative.teardownP2pIface(mP2pIface.id); + } + } + mP2pIfaceName = null; + mP2pIface = null; + mValid = false; + Log.i(TAG, "teardownAndInvalidate is completed"); } - mP2pIfaceName = null; - mValid = false; } @Override public void onDestroyed(String ifaceName) { - Log.d(TAG, "P2P InterfaceDestroyedListener " + ifaceName); - if (!mValid) { - Log.d(TAG, "Ignoring stale interface destroyed listener"); - return; + synchronized (mLock) { + Log.d(TAG, "P2P InterfaceDestroyedListener " + ifaceName); + if (!mValid) { + Log.d(TAG, "Ignoring stale interface destroyed listener"); + return; + } + teardownAndInvalidate(ifaceName); + mExternalListener.onDestroyed(ifaceName); } - teardownAndInvalidate(ifaceName); - mExternalListener.onDestroyed(ifaceName); } } @@ -102,7 +116,8 @@ public class WifiP2pNative { WifiVendorHal wifiVendorHal, SupplicantP2pIfaceHal p2pIfaceHal, HalDeviceManager halDeviceManager, - PropertyService propertyService) { + PropertyService propertyService, + WifiInjector wifiInjector) { mWifiNative = wifiNative; mWifiMetrics = wifiMetrics; mWifiNl80211Manager = wifiNl80211Manager; @@ -110,6 +125,8 @@ public class WifiP2pNative { mSupplicantP2pIfaceHal = p2pIfaceHal; mHalDeviceManager = halDeviceManager; mPropertyService = propertyService; + mWifiInjector = wifiInjector; + mFeatureFlags = wifiInjector.getDeviceConfigFacade().getFeatureFlags(); } /** @@ -161,8 +178,8 @@ public class WifiP2pNative { return mHalDeviceManager.isSupported(); } - private static final String P2P_IFACE_NAME = "p2p0"; - private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface"; + public static final String P2P_IFACE_NAME = "p2p0"; + public static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface"; /** * Helper function to handle creation of P2P iface. @@ -194,39 +211,49 @@ public class WifiP2pNative { public String setupInterface( @Nullable HalDeviceManager.InterfaceDestroyedListener destroyedListener, @NonNull Handler handler, @NonNull WorkSource requestorWs) { - Log.d(TAG, "Setup P2P interface"); - if (mP2pIfaceName == null) { - mInterfaceDestroyedListener = (null == destroyedListener) - ? null - : new InterfaceDestroyedListenerInternal(destroyedListener); - String ifaceName = createP2pIface(handler, requestorWs); - if (ifaceName == null) { - Log.e(TAG, "Failed to create P2p iface"); - if (mHalDeviceManager.isItPossibleToCreateIface(HDM_CREATE_IFACE_P2P, - requestorWs)) { - mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal(); + synchronized (mLock) { + Log.d(TAG, "Setup P2P interface"); + if (mP2pIfaceName == null) { + mInterfaceDestroyedListener = (null == destroyedListener) + ? null + : new InterfaceDestroyedListenerInternal(destroyedListener); + if (mFeatureFlags.d2dUsageWhenWifiOff()) { + mP2pIface = mWifiNative.createP2pIface(mInterfaceDestroyedListener, handler, + requestorWs); + if (mP2pIface != null) { + mP2pIfaceName = mP2pIface.name; + } + } else { + mP2pIfaceName = createP2pIface(handler, requestorWs); } - return null; - } - if (!waitForSupplicantConnection()) { - Log.e(TAG, "Failed to connect to supplicant"); - teardownInterface(); - mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant(); - return null; - } - if (!mSupplicantP2pIfaceHal.setupIface(ifaceName)) { - Log.e(TAG, "Failed to setup P2p iface in supplicant"); - teardownInterface(); - mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant(); - return null; + if (mP2pIfaceName == null) { + Log.e(TAG, "Failed to create P2p iface"); + if (mHalDeviceManager.isItPossibleToCreateIface(HDM_CREATE_IFACE_P2P, + requestorWs)) { + mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal(); + } + return null; + } + if (!waitForSupplicantConnection()) { + Log.e(TAG, "Failed to connect to supplicant"); + teardownInterface(); + mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant(); + return null; + } + if (!mSupplicantP2pIfaceHal.setupIface(mP2pIfaceName)) { + Log.e(TAG, "Failed to setup P2p iface in supplicant"); + teardownInterface(); + mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant(); + return null; + } + Log.i(TAG, "P2P interface setup completed"); + return mP2pIfaceName; + } else { + Log.i(TAG, "P2P interface already exists"); + return mHalDeviceManager.isSupported() + ? mP2pIfaceName + : mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); } - Log.i(TAG, "P2P interface setup completed"); - return ifaceName; - } else { - Log.i(TAG, "P2P interface already exists"); - return mHalDeviceManager.isSupported() - ? mP2pIfaceName - : mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); } } @@ -234,20 +261,25 @@ public class WifiP2pNative { * Teardown P2p interface. */ public void teardownInterface() { - Log.d(TAG, "Teardown P2P interface"); - if (mHalDeviceManager.isSupported()) { - if (mP2pIfaceName != null) { - mHalDeviceManager.removeP2pIface(mP2pIfaceName); + synchronized (mLock) { + Log.d(TAG, "Teardown P2P interface:" + mP2pIfaceName); + if (mHalDeviceManager.isSupported()) { + if (mP2pIfaceName != null) { + mHalDeviceManager.removeP2pIface(mP2pIfaceName); + Log.i(TAG, "P2P interface teardown completed"); + if (!mFeatureFlags.d2dUsageWhenWifiOff()) { + if (null != mInterfaceDestroyedListener) { + mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIfaceName); + } + } + } + } else { + Log.i(TAG, "HAL is not supported. Destroy listener for the interface."); + String ifaceName = mPropertyService.getString(P2P_INTERFACE_PROPERTY, + P2P_IFACE_NAME); if (null != mInterfaceDestroyedListener) { - mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIfaceName); + mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName); } - Log.i(TAG, "P2P interface teardown completed"); - } - } else { - Log.i(TAG, "HAL is not supported. Destroy listener for the interface."); - String ifaceName = mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); - if (null != mInterfaceDestroyedListener) { - mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName); } } } @@ -256,12 +288,14 @@ public class WifiP2pNative { * Replace requestorWs in-place when iface is already enabled. */ public boolean replaceRequestorWs(WorkSource requestorWs) { - if (mHalDeviceManager.isSupported()) { - if (mP2pIfaceName == null) return false; - return mHalDeviceManager.replaceRequestorWsForP2pIface(mP2pIfaceName, requestorWs); - } else { - Log.i(TAG, "HAL is not supported. Ignore replace requestorWs"); - return true; + synchronized (mLock) { + if (mHalDeviceManager.isSupported()) { + if (mP2pIfaceName == null) return false; + return mHalDeviceManager.replaceRequestorWsForP2pIface(mP2pIfaceName, requestorWs); + } else { + Log.i(TAG, "HAL is not supported. Ignore replace requestorWs"); + return true; + } } } @@ -936,9 +970,11 @@ public class WifiP2pNative { /** Indicate whether or not 5GHz/6GHz DBS is supported. */ public boolean is5g6gDbsSupported() { - if (mP2pIfaceName == null) return false; - if (!mHalDeviceManager.isSupported()) return false; - return mHalDeviceManager.is5g6gDbsSupportedOnP2pIface(mP2pIfaceName); + synchronized (mLock) { + if (mP2pIfaceName == null) return false; + if (!mHalDeviceManager.isSupported()) return false; + return mHalDeviceManager.is5g6gDbsSupportedOnP2pIface(mP2pIfaceName); + } } /** diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java index 92a111fea7..11329dbef7 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java @@ -16,8 +16,12 @@ package com.android.server.wifi; +import static com.android.server.wifi.p2p.WifiP2pNative.P2P_IFACE_NAME; +import static com.android.server.wifi.p2p.WifiP2pNative.P2P_INTERFACE_PROPERTY; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -88,6 +92,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { private static final int SOFTAP_FAILURE_CODE_START_DAEMON = 2; private static final int SOFTAP_FAILURE_CODE_CREATE_IFACE = 3; private static final int SOFTAP_FAILURE_CODE_BRIDGED_AP_INSTANCES = 4; + private static final int P2P_FAILURE_CODE_CREATE_INTERFACE = 1; private static final int TEST_SUPPORTED_BANDS = 15; MockResources mResources; @@ -103,11 +108,14 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { @Mock BuildProperties mBuildProperties; @Mock private WifiInjector mWifiInjector; @Mock private WifiContext mContext; + @Mock private HalDeviceManager mHalDeviceManager; @Mock private WifiNative.StatusListener mStatusListener; @Mock private WifiNative.InterfaceCallback mIfaceCallback0; @Mock private WifiNative.InterfaceCallback mIfaceCallback1; @Mock private WifiNative.InterfaceEventCallback mIfaceEventCallback0; + @Mock private HalDeviceManager.InterfaceDestroyedListener mP2pInterfaceDestroyedListener; + @Mock private Handler mP2pEventHandler; @Mock private WifiSettingsConfigStore mWifiSettingsConfigStore; @Mock private WifiGlobals mWifiGlobals; @@ -116,6 +124,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { @Mock DeviceConfigFacade mDeviceConfigFacade; private TestLooper mLooper; + private WifiNative.Iface mActiveP2pIface; private ArgumentCaptor<VendorHalDeathEventHandler> mWifiVendorHalDeathHandlerCaptor = ArgumentCaptor.forClass(VendorHalDeathEventHandler.class); @@ -206,6 +215,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore); when(mWifiInjector.getContext()).thenReturn(mContext); when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals); + when(mWifiInjector.getHalDeviceManager()).thenReturn(mHalDeviceManager); mResources = getMockResources(); mResources.setBoolean(R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled, false); mResources.setString( @@ -237,6 +247,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { mWificondDeathHandlerCaptor.capture()); mInOrder.verify(mWificondControl).tearDownInterfaces(); mInOrder.verify(mWifiVendorHal).registerRadioModeChangeHandler(any()); + mActiveP2pIface = null; } @After @@ -1395,6 +1406,70 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { assertEquals(Set.of(IFACE_NAME_0, IFACE_NAME_1), mWifiNative.getClientInterfaceNames()); } + @Test + public void testSetupP2pInterfaceAndTeardownP2p() throws Exception { + executeAndValidateCreateP2pInterface(false, false, false, P2P_IFACE_NAME, true, 0); + executeAndValidateTeardownP2pInterface(false, false, false, mActiveP2pIface, true, 0); + } + + /** + * Verifies the setup of a single client interface and teardown by P2P on. + */ + @Test + public void testSetupClientInterfaceAndTeardownP2p() throws Exception { + executeAndValidateCreateP2pInterface(false, false, false, P2P_IFACE_NAME, true, 0); + // Trigger the P2P interface teardown when STA interface is created. + // The iface name will remain the same. + doAnswer(new MockAnswerUtil.AnswerWithArguments() { + public String answer(InterfaceDestroyedListener destroyedListener, WorkSource ws, + ConcreteClientModeManager concreteClientModeManager) { + mWifiNative.teardownP2pIface(mActiveP2pIface.id); + return IFACE_NAME_0; + } + }).when(mWifiVendorHal).createStaIface(any(), any(), eq(mConcreteClientModeManager)); + + assertEquals(IFACE_NAME_0, + mWifiNative.setupInterfaceForClientInScanMode(mIfaceCallback0, TEST_WORKSOURCE, + mConcreteClientModeManager)); + assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getClientInterfaceNames()); + validateSetupClientInterfaceForScan( + true, false, false, IFACE_NAME_0, mIfaceDestroyedListenerCaptor0, + mNetworkObserverCaptor0, true, 0); + validateStartHal(true, true); + validateOnDestroyedP2pInterface(true, false, false, mActiveP2pIface, true, 0); + } + + /** + * Verifies the setup of a single client interface (for scan) and teardown by P2P on. + */ + @Test + public void testCreateP2pIfaceAndTeardownClientIface() throws Exception { + executeAndValidateSetupClientInterface( + false, false, IFACE_NAME_0, mIfaceCallback0, mIfaceDestroyedListenerCaptor0, + mNetworkObserverCaptor0); + assertEquals(Set.of(IFACE_NAME_0), mWifiNative.getClientInterfaceNames()); + // Trigger the STA interface teardown when P2p interface is created. + // The iface name will remain the same. + doAnswer(new MockAnswerUtil.AnswerWithArguments() { + public String answer( + HalDeviceManager.InterfaceDestroyedListener p2pInterfaceDestroyedListener, + Handler handler, WorkSource requestorWs) { + mIfaceDestroyedListenerCaptor0.getValue().onDestroyed(IFACE_NAME_0); + return P2P_IFACE_NAME; + } + }).when(mHalDeviceManager).createP2pIface(any(), any(), any()); + mActiveP2pIface = mWifiNative.createP2pIface(mP2pInterfaceDestroyedListener, + mP2pEventHandler, TEST_WORKSOURCE); + assertEquals(P2P_IFACE_NAME, mActiveP2pIface.name); + // Creation of P2P interface should trigger the STA interface destroy + verify(mWifiVendorHal, atLeastOnce()).isVendorHalSupported(); + verify(mWifiVendorHal, atLeastOnce()).isVendorHalReady(); + validateOnDestroyedClientInterface(false, false, true, + IFACE_NAME_0, mIfaceCallback0, mNetworkObserverCaptor0.getValue()); + validateCreateP2pInterface(true, false, false, P2P_IFACE_NAME, true, 0); + executeAndValidateTeardownP2pInterface(false, false, false, mActiveP2pIface, true, 0); + } + private void executeAndValidateSetupClientInterface( boolean hasStaIface, boolean hasApIface, String ifaceName, @Mock WifiNative.InterfaceCallback callback, @@ -1411,10 +1486,21 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported, int failureCode) throws Exception { + executeAndValidateSetupClientInterface(hasStaIface, hasApIface, false, ifaceName, callback, + destroyedListenerCaptor, + networkObserverCaptor, vendorHalSupported, failureCode); + } + + private void executeAndValidateSetupClientInterface( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, + ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported, + int failureCode) throws Exception { when(mWifiVendorHal.createStaIface(any(), any(), eq(mConcreteClientModeManager))) .thenReturn(ifaceName); executeAndValidateSetupClientInterfaceForScan( - hasStaIface, hasApIface, ifaceName, callback, destroyedListenerCaptor, + hasStaIface, hasApIface, hasP2pIface, ifaceName, callback, destroyedListenerCaptor, networkObserverCaptor, vendorHalSupported, failureCode); executeAndValidateSwitchClientInterfaceToConnectivityMode(hasStaIface, hasApIface, ifaceName, TEST_WORKSOURCE, vendorHalSupported, failureCode); @@ -1425,6 +1511,16 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { String ifaceName, @Mock WifiNative.InterfaceCallback callback, InterfaceDestroyedListener destroyedListener, NetdEventObserver networkObserver) throws Exception { + executeAndValidateTeardownClientInterface(anyOtherStaIface, anyOtherApIface, + false /* anyOtherP2pIface */, ifaceName, callback, destroyedListener, + networkObserver); + } + + private void executeAndValidateTeardownClientInterface( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + InterfaceDestroyedListener destroyedListener, + NetdEventObserver networkObserver) throws Exception { mWifiNative.teardownInterface(ifaceName); mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); @@ -1434,13 +1530,23 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { destroyedListener.onDestroyed(ifaceName); validateOnDestroyedClientInterface( - anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver); + anyOtherStaIface, anyOtherApIface, anyOtherP2pIface, + ifaceName, callback, networkObserver); } private void validateOnDestroyedClientInterface( boolean anyOtherStaIface, boolean anyOtherApIface, String ifaceName, @Mock WifiNative.InterfaceCallback callback, NetdEventObserver networkObserver) throws Exception { + validateOnDestroyedClientInterface( + anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */, + ifaceName, callback, networkObserver); + } + + private void validateOnDestroyedClientInterface( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + NetdEventObserver networkObserver) throws Exception { mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName); if (networkObserver != null) { mInOrder.verify(mNetdWrapper).unregisterObserver(networkObserver); @@ -1452,7 +1558,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { mInOrder.verify(mSupplicantStaIfaceHal).deregisterDeathHandler(); mInOrder.verify(mSupplicantStaIfaceHal).terminate(); } - if (!anyOtherStaIface && !anyOtherApIface) { + if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) { mInOrder.verify(mWificondControl).tearDownInterfaces(); mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); mInOrder.verify(mWifiVendorHal).stopVendorHal(); @@ -1476,6 +1582,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported, int failureCode) throws Exception { + executeAndValidateSetupClientInterfaceForScan(hasStaIface, hasApIface, + false /* hasP2pIface */, ifaceName, callback, + destroyedListenerCaptor, networkObserverCaptor, vendorHalSupported, failureCode); + } + + private void executeAndValidateSetupClientInterfaceForScan( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, + ArgumentCaptor<NetdEventObserver> networkObserverCaptor, + boolean vendorHalSupported, int failureCode) throws Exception { if (failureCode != STA_FAILURE_CODE_CREAT_IFACE) { when(mWifiVendorHal.createStaIface(any(), any(), eq(mConcreteClientModeManager))) .thenReturn(ifaceName); @@ -1485,7 +1602,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { mConcreteClientModeManager)); validateSetupClientInterfaceForScan( - hasStaIface, hasApIface, ifaceName, destroyedListenerCaptor, + hasStaIface, hasApIface, hasP2pIface, ifaceName, destroyedListenerCaptor, networkObserverCaptor, vendorHalSupported, failureCode); } @@ -1510,7 +1627,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported, int failureCode) throws Exception { - validateStartHal(hasStaIface || hasApIface, vendorHalSupported); + validateSetupClientInterfaceForScan(hasStaIface, hasApIface, false /* hasP2pIfacd */, + ifaceName, destroyedListenerCaptor, networkObserverCaptor, vendorHalSupported, + failureCode); + } + + private void validateSetupClientInterfaceForScan( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, + ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean vendorHalSupported, + int failureCode) throws Exception { + validateStartHal(hasStaIface || hasApIface || hasP2pIface, vendorHalSupported); if (vendorHalSupported) { mInOrder.verify(mWifiVendorHal).createStaIface( destroyedListenerCaptor.capture(), eq(TEST_WORKSOURCE), @@ -1557,6 +1684,16 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { String ifaceName, @Mock WifiNative.InterfaceCallback callback, InterfaceDestroyedListener destroyedListener, NetdEventObserver networkObserver) throws Exception { + executeAndValidateTeardownClientInterfaceForScan(anyOtherStaIface, anyOtherApIface, + false /* anyOtherP2pIface */, ifaceName, callback, destroyedListener, + networkObserver); + } + + private void executeAndValidateTeardownClientInterfaceForScan( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + InterfaceDestroyedListener destroyedListener, + NetdEventObserver networkObserver) throws Exception { mWifiNative.teardownInterface(ifaceName); mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); @@ -1566,20 +1703,30 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { destroyedListener.onDestroyed(ifaceName); validateOnDestroyedClientInterfaceForScan( - anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver); + anyOtherStaIface, anyOtherApIface, anyOtherP2pIface, + ifaceName, callback, networkObserver); } private void validateOnDestroyedClientInterfaceForScan( boolean anyOtherStaIface, boolean anyOtherApIface, String ifaceName, @Mock WifiNative.InterfaceCallback callback, NetdEventObserver networkObserver) throws Exception { + validateOnDestroyedClientInterfaceForScan( + anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */, + ifaceName, callback, networkObserver); + } + + private void validateOnDestroyedClientInterfaceForScan( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + NetdEventObserver networkObserver) throws Exception { mInOrder.verify(mWifiMonitor).stopMonitoring(ifaceName); if (networkObserver != null) { mInOrder.verify(mNetdWrapper).unregisterObserver(networkObserver); } mInOrder.verify(mWificondControl).tearDownClientInterface(ifaceName); - if (!anyOtherStaIface && !anyOtherApIface) { + if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) { mInOrder.verify(mWificondControl).tearDownInterfaces(); mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); mInOrder.verify(mWifiVendorHal).stopVendorHal(); @@ -1603,6 +1750,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged, boolean vendorHalSupported, int failureCode) throws Exception { + executeAndValidateSetupSoftApInterface(hasStaIface, hasApIface, false /* hasP2pIface */, + ifaceName, callback, destroyedListenerCaptor, networkObserverCaptor, + isBridged, vendorHalSupported, failureCode); + } + + private void executeAndValidateSetupSoftApInterface( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, + ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged, + boolean vendorHalSupported, int failureCode) throws Exception { when(mWifiVendorHal.createApIface(any(), any(), anyInt(), eq(isBridged), any(), anyList())) .thenReturn(ifaceName); assertEquals(failureCode == 0 ? ifaceName : null, mWifiNative.setupInterfaceForSoftApMode( @@ -1619,7 +1777,17 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged, boolean vendorHalSupported, int failureCode) throws Exception { - validateStartHal(hasStaIface || hasApIface, vendorHalSupported); + validateSetupSoftApInterface(hasStaIface, hasApIface, false /* hasP2pIface */, + ifaceName, destroyedListenerCaptor, + networkObserverCaptor, isBridged, vendorHalSupported, failureCode); + } + + private void validateSetupSoftApInterface( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, ArgumentCaptor<InterfaceDestroyedListener> destroyedListenerCaptor, + ArgumentCaptor<NetdEventObserver> networkObserverCaptor, boolean isBridged, + boolean vendorHalSupported, int failureCode) throws Exception { + validateStartHal(hasStaIface || hasApIface || hasP2pIface, vendorHalSupported); if (!hasApIface) { mInOrder.verify(mHostapdHal).isInitializationStarted(); mInOrder.verify(mHostapdHal).initialize(); @@ -1695,13 +1863,23 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { destroyedListener.onDestroyed(ifaceName); validateOnDestroyedSoftApInterface( - anyOtherStaIface, anyOtherApIface, ifaceName, callback, networkObserver); + anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */, + ifaceName, callback, networkObserver); } private void validateOnDestroyedSoftApInterface( boolean anyOtherStaIface, boolean anyOtherApIface, String ifaceName, @Mock WifiNative.InterfaceCallback callback, NetdEventObserver networkObserver) throws Exception { + validateOnDestroyedSoftApInterface( + anyOtherStaIface, anyOtherApIface, false /* anyOtherP2pIface */, + ifaceName, callback, networkObserver); + } + + private void validateOnDestroyedSoftApInterface( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + String ifaceName, @Mock WifiNative.InterfaceCallback callback, + NetdEventObserver networkObserver) throws Exception { if (networkObserver != null) { mInOrder.verify(mNetdWrapper).unregisterObserver(networkObserver); } @@ -1712,7 +1890,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { mInOrder.verify(mHostapdHal).deregisterDeathHandler(); mInOrder.verify(mHostapdHal).terminate(); } - if (!anyOtherStaIface && !anyOtherApIface) { + if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) { mInOrder.verify(mWificondControl).tearDownInterfaces(); mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); mInOrder.verify(mWifiVendorHal).stopVendorHal(); @@ -1735,4 +1913,62 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest { mLooper.dispatchAll(); mInOrder.verify(mIfaceEventCallback0).onInterfaceAdded(ifaceName); } + + private void executeAndValidateCreateP2pInterface( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, boolean vendorHalSupported, int failureCode) throws Exception { + if (failureCode != P2P_FAILURE_CODE_CREATE_INTERFACE) { + if (vendorHalSupported) { + when(mHalDeviceManager.createP2pIface(any(), any(), any())) + .thenReturn(ifaceName); + } else { + when(mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME)) + .thenReturn(ifaceName); + } + } + mActiveP2pIface = mWifiNative.createP2pIface(mP2pInterfaceDestroyedListener, + mP2pEventHandler, TEST_WORKSOURCE); + if (failureCode == 0) { + assertNotNull(mActiveP2pIface); + assertEquals(mActiveP2pIface.name, ifaceName); + } else { + assertNull(mActiveP2pIface); + } + validateCreateP2pInterface(hasStaIface, hasApIface, hasP2pIface, + ifaceName, vendorHalSupported, failureCode); + } + + private void validateCreateP2pInterface( + boolean hasStaIface, boolean hasApIface, boolean hasP2pIface, + String ifaceName, boolean vendorHalSupported, int failureCode) throws Exception { + validateStartHal(hasStaIface || hasApIface || hasP2pIface, vendorHalSupported); + if (vendorHalSupported) { + verify(mHalDeviceManager).createP2pIface(eq(mP2pInterfaceDestroyedListener), + eq(mP2pEventHandler), eq(TEST_WORKSOURCE)); + if (failureCode == P2P_FAILURE_CODE_CREATE_INTERFACE) { + verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToHal(); + } + } else { + verify(mPropertyService).getString(eq(P2P_INTERFACE_PROPERTY), eq(P2P_IFACE_NAME)); + } + } + + private void executeAndValidateTeardownP2pInterface( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + WifiNative.Iface iface, boolean vendorHalSupported, int failureCode) throws Exception { + mWifiNative.teardownP2pIface(iface.id); + + validateOnDestroyedP2pInterface(anyOtherStaIface, anyOtherApIface, anyOtherP2pIface, + iface, vendorHalSupported, failureCode); + } + + private void validateOnDestroyedP2pInterface( + boolean anyOtherStaIface, boolean anyOtherApIface, boolean anyOtherP2pIface, + WifiNative.Iface iface, boolean vendorHalSupported, int failureCode) throws Exception { + if (!anyOtherStaIface && !anyOtherApIface && !anyOtherP2pIface) { + mInOrder.verify(mWificondControl).tearDownInterfaces(); + mInOrder.verify(mWifiVendorHal).isVendorHalSupported(); + mInOrder.verify(mWifiVendorHal).stopVendorHal(); + } + } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java index cc2456f238..12c40c0494 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeInterfaceManagementTest.java @@ -34,15 +34,18 @@ import android.os.WorkSource; import androidx.test.filters.SmallTest; +import com.android.server.wifi.DeviceConfigFacade; import com.android.server.wifi.HalDeviceManager; 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.WifiBaseTest; +import com.android.server.wifi.WifiInjector; import com.android.server.wifi.WifiMetrics; import com.android.server.wifi.WifiNative; import com.android.server.wifi.WifiVendorHal; import com.android.server.wifi.hal.WifiHal; +import com.android.wifi.flags.FeatureFlags; import org.junit.Before; import org.junit.Test; @@ -55,8 +58,7 @@ import org.mockito.MockitoAnnotations; */ @SmallTest public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest { - private static final String P2P_IFACE_NAME = "p2p0"; - private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface"; + private static final String TEST_P2P_IFACE_NAME = "p2p0"; private static final WorkSource TEST_WS = new WorkSource(); @Mock private SupplicantP2pIfaceHal mSupplicantP2pIfaceHal; @@ -70,6 +72,11 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest { @Mock private WifiNl80211Manager mWifiNl80211Manager; @Mock private WifiNative mWifiNative; @Mock private WifiMetrics mWifiMetrics; + @Mock private WifiNative.Iface mMockP2pIface; + @Mock private WifiInjector mWifiInjector; + @Mock private DeviceConfigFacade mDeviceConfigFacade; + @Mock private FeatureFlags mFeatureFlags; + private WifiP2pNative mWifiP2pNative; private WifiStatus mWifiStatusSuccess; private ManagerStatusListener mManagerStatusListener; @@ -84,31 +91,59 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest { mWifiStatusSuccess.code = WifiStatusCode.SUCCESS; when(mHalDeviceManager.isSupported()).thenReturn(true); + mMockP2pIface.name = TEST_P2P_IFACE_NAME; + when(mWifiNative.createP2pIface(any(InterfaceDestroyedListener.class), + any(Handler.class), any(WorkSource.class))).thenReturn(mMockP2pIface); when(mHalDeviceManager.createP2pIface(any(InterfaceDestroyedListener.class), - any(Handler.class), any(WorkSource.class))).thenReturn(P2P_IFACE_NAME); + any(Handler.class), any(WorkSource.class))).thenReturn(TEST_P2P_IFACE_NAME); 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); - + when(mSupplicantP2pIfaceHal.setupIface(TEST_P2P_IFACE_NAME)).thenReturn(true); + when(mPropertyService.getString( + WifiP2pNative.P2P_INTERFACE_PROPERTY, WifiP2pNative.P2P_IFACE_NAME)) + .thenReturn(TEST_P2P_IFACE_NAME); + when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); + when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags); + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(true); mWifiP2pNative = new WifiP2pNative(mWifiNl80211Manager, mWifiNative, mWifiMetrics, - mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService); + mWifiVendorHal, mSupplicantP2pIfaceHal, mHalDeviceManager, mPropertyService, + mWifiInjector); + } + + /** + * Verifies the setup of a p2p interface. + */ + @Test + public void testSetUpInterfaceByHDM() throws Exception { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetUpInterface(false); } /** * Verifies the setup of a p2p interface. */ @Test - public void testSetUpInterface() throws Exception { - assertEquals(P2P_IFACE_NAME, + public void testSetUpInterfaceByWifiNative() throws Exception { + testSetUpInterface(true); + } + + private void testSetUpInterface(boolean isD2dAloneFeatureEnabled) throws Exception { + assertEquals(TEST_P2P_IFACE_NAME, mWifiP2pNative.setupInterface( mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS)); - - verify(mHalDeviceManager).createP2pIface(any(InterfaceDestroyedListener.class), - eq(mHandler), eq(TEST_WS)); - verify(mSupplicantP2pIfaceHal).setupIface(eq(P2P_IFACE_NAME)); + if (isD2dAloneFeatureEnabled) { + verify(mWifiNative).createP2pIface(any(InterfaceDestroyedListener.class), + eq(mHandler), eq(TEST_WS)); + verify(mHalDeviceManager, never()).createP2pIface(any(InterfaceDestroyedListener.class), + any(), any()); + } else { + verify(mHalDeviceManager).createP2pIface(any(InterfaceDestroyedListener.class), + eq(mHandler), eq(TEST_WS)); + verify(mWifiNative, never()).createP2pIface(any(InterfaceDestroyedListener.class), + any(), any()); + } + verify(mSupplicantP2pIfaceHal).setupIface(eq(TEST_P2P_IFACE_NAME)); } /** @@ -118,13 +153,22 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest { public void testSetUpInterfaceWithNoVendorHal() throws Exception { when(mHalDeviceManager.isSupported()).thenReturn(false); - assertEquals(P2P_IFACE_NAME, mWifiP2pNative.setupInterface( + assertEquals(TEST_P2P_IFACE_NAME, mWifiP2pNative.setupInterface( mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS)); verify(mHalDeviceManager, never()) .createP2pIface(any(InterfaceDestroyedListener.class), any(Handler.class), any(WorkSource.class)); - verify(mSupplicantP2pIfaceHal).setupIface(eq(P2P_IFACE_NAME)); + verify(mSupplicantP2pIfaceHal).setupIface(eq(TEST_P2P_IFACE_NAME)); + } + + /** + * Verifies the teardown of a p2p interface. + */ + @Test + public void testTeardownInterfaceWhenD2dWithoutSTADisabled() throws Exception { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testTeardownInterface(false); } /** @@ -132,14 +176,20 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest { */ @Test public void testTeardownInterface() throws Exception { - assertEquals(P2P_IFACE_NAME, + testTeardownInterface(true); + } + + private void testTeardownInterface(boolean isD2dAloneFeatureEnabled) throws Exception { + assertEquals(TEST_P2P_IFACE_NAME, mWifiP2pNative.setupInterface(mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS)); mWifiP2pNative.teardownInterface(); verify(mHalDeviceManager).removeP2pIface(anyString()); - verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME)); + if (!isD2dAloneFeatureEnabled) { + verify(mSupplicantP2pIfaceHal).teardownIface(eq(TEST_P2P_IFACE_NAME)); + } } /** @@ -147,14 +197,15 @@ public class WifiP2pNativeInterfaceManagementTest extends WifiBaseTest { */ @Test public void testTeardownInterfaceWithNoVendorHal() throws Exception { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); when(mHalDeviceManager.isSupported()).thenReturn(false); - assertEquals(P2P_IFACE_NAME, mWifiP2pNative.setupInterface( + assertEquals(TEST_P2P_IFACE_NAME, mWifiP2pNative.setupInterface( mHalDeviceInterfaceDestroyedListener, mHandler, TEST_WS)); mWifiP2pNative.teardownInterface(); verify(mHalDeviceManager, never()).removeIface(any(WifiHal.WifiInterface.class)); - verify(mSupplicantP2pIfaceHal).teardownIface(eq(P2P_IFACE_NAME)); + verify(mSupplicantP2pIfaceHal).teardownIface(eq(TEST_P2P_IFACE_NAME)); } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java index 41054548d8..88f5b8228a 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java @@ -46,13 +46,16 @@ import android.os.WorkSource; import androidx.test.filters.SmallTest; import com.android.dx.mockito.inline.extended.ExtendedMockito; +import com.android.server.wifi.DeviceConfigFacade; import com.android.server.wifi.HalDeviceManager; import com.android.server.wifi.PropertyService; import com.android.server.wifi.WifiBaseTest; +import com.android.server.wifi.WifiInjector; import com.android.server.wifi.WifiMetrics; import com.android.server.wifi.WifiNative; import com.android.server.wifi.WifiVendorHal; import com.android.server.wifi.hal.WifiHal; +import com.android.wifi.flags.FeatureFlags; import org.junit.After; import org.junit.Before; @@ -104,6 +107,10 @@ public class WifiP2pNativeTest extends WifiBaseTest { @Mock private Handler mHandlerMock; @Mock private WorkSource mWorkSourceMock; @Mock private IWifiP2pIface mIWifiP2pIfaceMock; + @Mock private WifiNative.Iface mMockP2pIface; + @Mock private WifiInjector mWifiInjector; + @Mock private DeviceConfigFacade mDeviceConfigFacade; + @Mock private FeatureFlags mFeatureFlags; private MockitoSession mSession; private WifiP2pNative mWifiP2pNative; @@ -131,10 +138,12 @@ public class WifiP2pNativeTest extends WifiBaseTest { .startMocking(); mWifiClientInterfaceNames.add("wlan0"); mWifiClientInterfaceNames.add("wlan1"); - + when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); + when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags); + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(true); mWifiP2pNative = new WifiP2pNative(mWifiCondManager, mWifiNative, mWifiMetrics, mWifiVendorHalMock, mSupplicantP2pIfaceHalMock, mHalDeviceManagerMock, - mPropertyServiceMock); + mPropertyServiceMock, mWifiInjector); when(mWifiNative.getClientInterfaceNames()).thenReturn(mWifiClientInterfaceNames); @@ -149,7 +158,9 @@ public class WifiP2pNativeTest extends WifiBaseTest { // setup default mock behaviors when(mHalDeviceManagerMock.isSupported()).thenReturn(true); - + mMockP2pIface.name = TEST_IFACE; + when(mWifiNative.createP2pIface(any(HalDeviceManager.InterfaceDestroyedListener.class), + any(Handler.class), any(WorkSource.class))).thenReturn(mMockP2pIface); doAnswer(new AnswerWithArguments() { public boolean answer(WifiP2pGroupList groupList) { for (WifiP2pGroup g : mWifiP2pGroupList.getGroupList()) { @@ -178,13 +189,30 @@ public class WifiP2pNativeTest extends WifiBaseTest { } /** - * Verifies that setupInterface returns correct values when successfully creating P2P Iface. + * Verifies that setupInterface by calling HalDeviceManager returns correct values + * when successfully creating P2P Iface. (Old design, feature is disabled) */ @Test - public void testSetupInterfaceSuccessInCreatingP2pIface() { - when(mHalDeviceManagerMock.createP2pIface( - any(HalDeviceManager.InterfaceDestroyedListener.class), - eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + public void testSetupInterfaceByHDMSuccessInCreatingP2pIface() { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetupInterfaceSuccessInCreatingP2pIface(false); + } + + /** + * Verifies that setupInterface by WifiNative returns correct values + * when successfully creating P2P Iface. (The default behavior) + */ + @Test + public void testSetupInterfaceByWifiNativeSuccessInCreatingP2pIface() { + testSetupInterfaceSuccessInCreatingP2pIface(true); + } + + private void testSetupInterfaceSuccessInCreatingP2pIface(boolean isD2dAloneFeatureEnabled) { + if (!isD2dAloneFeatureEnabled) { + when(mHalDeviceManagerMock.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + } when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true); when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true); when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(true); @@ -213,13 +241,34 @@ public class WifiP2pNativeTest extends WifiBaseTest { } /** - * Verifies that setupInterface returns correct values when failing in creating P2P Iface. + * Verifies that setupInterface returns correct values when failing in creating P2P Iface + * by HDM. */ @Test - public void testSetupInterfaceFailureInCreatingP2pIface() { - when(mHalDeviceManagerMock.createP2pIface( - any(HalDeviceManager.InterfaceDestroyedListener.class), - eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null); + public void testSetupInterfaceFailureInCreatingP2pIfaceByHDM() { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetupInterfaceFailureInCreatingP2pIface(false); + } + + /** + * Verifies that setupInterface returns correct values when failing in creating P2P Iface + * by WifiNative. + */ + @Test + public void testSetupInterfaceFailureInCreatingP2pIfaceByWifiNative() { + testSetupInterfaceFailureInCreatingP2pIface(true); + } + + private void testSetupInterfaceFailureInCreatingP2pIface(boolean isD2dAloneFeatureEnabled) { + if (isD2dAloneFeatureEnabled) { + when(mWifiNative.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null); + } else { + when(mHalDeviceManagerMock.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null); + } when(mHalDeviceManagerMock.isItPossibleToCreateIface( eq(HalDeviceManager.HDM_CREATE_IFACE_P2P), eq(mWorkSourceMock))).thenReturn(true); @@ -236,10 +285,31 @@ public class WifiP2pNativeTest extends WifiBaseTest { * HalDevMgr not possibly creating it. */ @Test - public void testSetupInterfaceFailureInCreatingP2pIfaceWhenHalDevMgrNotPossiblyCreate() { - when(mHalDeviceManagerMock.createP2pIface( - any(HalDeviceManager.InterfaceDestroyedListener.class), - eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null); + public void testSetupInterfaceFailureInHDMCreatingP2pIfaceWhenHalDevMgrNotPossiblyCreate() { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetupInterfaceFailureInCreatingP2pIfaceAndHalDevMgrNotPossiblyCreate(false); + } + + /** + * Verifies that Wi-Fi metrics do correct action when setting up p2p interface failed and + * HalDevMgr not possibly creating it. + */ + @Test + public void testSetupInterfaceFailureInCreatingP2pByWifiNativeAndHalDevMgrNotPossiblyCreate() { + testSetupInterfaceFailureInCreatingP2pIfaceAndHalDevMgrNotPossiblyCreate(true); + } + + private void testSetupInterfaceFailureInCreatingP2pIfaceAndHalDevMgrNotPossiblyCreate( + boolean isD2dAloneFeatureEnabled) { + if (isD2dAloneFeatureEnabled) { + when(mWifiNative.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null); + } else { + when(mHalDeviceManagerMock.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(null); + } when(mHalDeviceManagerMock.isItPossibleToCreateIface( eq(HalDeviceManager.HDM_CREATE_IFACE_P2P), eq(mWorkSourceMock))).thenReturn(false); @@ -252,19 +322,34 @@ public class WifiP2pNativeTest extends WifiBaseTest { * initialization fails. */ @Test - public void testSetupInterfaceFailureInSupplicantConnectionInitialization() { - when(mHalDeviceManagerMock.createP2pIface( - any(HalDeviceManager.InterfaceDestroyedListener.class), - eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + public void testSetupInterfaceByHDMAndFailureInSupplicantConnectionInitialization() { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetupInterfaceFailureInSupplicantConnectionInitialization(false); + } + + /** + * Verifies that setupInterface returns correct values when supplicant connection + * initialization fails. + */ + @Test + public void testSetupInterfaceByWifiNativeAndFailureInSupplicantConnectionInitialization() { + testSetupInterfaceFailureInSupplicantConnectionInitialization(true); + } + + private void testSetupInterfaceFailureInSupplicantConnectionInitialization( + boolean isD2dAloneFeatureEnabled) { + if (!isD2dAloneFeatureEnabled) { + when(mHalDeviceManagerMock.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + } when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(false); when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(false); - - mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock); - verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant(); assertEquals( mWifiP2pNative.setupInterface( mDestroyedListenerMock, mHandlerMock, mWorkSourceMock), null); + verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant(); } /** @@ -272,20 +357,36 @@ public class WifiP2pNativeTest extends WifiBaseTest { * initialization never completes. */ @Test - public void testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted() { - when(mHalDeviceManagerMock.createP2pIface( - any(HalDeviceManager.InterfaceDestroyedListener.class), - eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + public void testSetupInterfaceByHDMAndFailureInSupplicantConnectionInitNotCompleted() { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted(false); + } + + /** + * Verifies that setupInterface returns correct values when supplicant connection + * initialization never completes. + */ + @Test + public void testSetupInterfaceByWifiNativeAndFailureInSupplicantConnectionInitNotCompleted() { + testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted(true); + } + + private void testSetupInterfaceFailureInSupplicantConnectionInitNotCompleted( + boolean isD2dAloneFeatureEnabled) { + if (!isD2dAloneFeatureEnabled) { + when(mHalDeviceManagerMock.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + } when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(true); when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true); when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(false); - mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock); - verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant(); assertEquals( mWifiP2pNative.setupInterface( mDestroyedListenerMock, mHandlerMock, mWorkSourceMock), null); + verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant(); } /** @@ -293,20 +394,35 @@ public class WifiP2pNativeTest extends WifiBaseTest { * for supplicant. */ @Test - public void testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant() { - when(mHalDeviceManagerMock.createP2pIface( - any(HalDeviceManager.InterfaceDestroyedListener.class), - eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + public void testSetupInterfaceByHDMAndFailureInSettingUpP2pIfaceInSupplicant() { + when(mFeatureFlags.d2dUsageWhenWifiOff()).thenReturn(false); + testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant(false); + } + + /** + * Verifies that setupInterface returns correct values when failing in setting up P2P Iface + * for supplicant. + */ + @Test + public void testSetupInterfaceByWifiNativeAndFailureInSettingUpP2pIfaceInSupplicant() { + testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant(true); + } + private void testSetupInterfaceFailureInSettingUpP2pIfaceInSupplicant( + boolean isD2dAloneFeatureEnabled) { + if (!isD2dAloneFeatureEnabled) { + when(mHalDeviceManagerMock.createP2pIface( + any(HalDeviceManager.InterfaceDestroyedListener.class), + eq(mHandlerMock), eq(mWorkSourceMock))).thenReturn(TEST_IFACE); + } when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true); when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true); when(mSupplicantP2pIfaceHalMock.setupIface(eq(TEST_IFACE))).thenReturn(false); - mWifiP2pNative.setupInterface(mDestroyedListenerMock, mHandlerMock, mWorkSourceMock); - verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant(); assertEquals( mWifiP2pNative.setupInterface( mDestroyedListenerMock, mHandlerMock, mWorkSourceMock), null); + verify(mWifiMetrics).incrementNumSetupP2pInterfaceFailureDueToSupplicant(); } /** |