diff options
author | 2023-11-21 13:59:29 -0800 | |
---|---|---|
committer | 2024-02-14 23:54:09 +0000 | |
commit | d183a0e3aeeb3be3ce48ba9e8c6a8082c3243345 (patch) | |
tree | 331b5afc7de83c037bddfdb406dc34f7113304f2 | |
parent | 97d66af67bb39fc688186240c03f6ef5597360ff (diff) |
Add new p2p listener APIs
Bug: 312521671
Test: atest WifiP2pServiveImplTest
Change-Id: I44029c0b4b95a747530dfec59735ce51e7132e02
9 files changed, 756 insertions, 12 deletions
diff --git a/framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl b/framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl new file mode 100644 index 0000000000..eb52254a5a --- /dev/null +++ b/framework/aidl-export/android/net/wifi/p2p/WifiP2pGroupList.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.p2p; + +parcelable WifiP2pGroupList; diff --git a/framework/api/current.txt b/framework/api/current.txt index 8f0efa2ffe..ab684fd3f9 100644 --- a/framework/api/current.txt +++ b/framework/api/current.txt @@ -1382,6 +1382,7 @@ package android.net.wifi.p2p { method public boolean isGroupClientRemovalSupported(); method public boolean isGroupOwnerIPv6LinkLocalAddressProvided(); method public boolean isSetVendorElementsSupported(); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_WIFI_STATE}, conditional=true) public void registerWifiP2pListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.p2p.WifiP2pManager.WifiP2pListener); method public void removeClient(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.MacAddress, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); method @RequiresPermission(android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION) public void removeExternalApprover(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @NonNull android.net.MacAddress, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); method public void removeGroup(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener); @@ -1404,6 +1405,7 @@ package android.net.wifi.p2p { method @RequiresPermission(allOf={android.Manifest.permission.NEARBY_WIFI_DEVICES, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public void startListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); method public void stopListening(@NonNull android.net.wifi.p2p.WifiP2pManager.Channel, @Nullable android.net.wifi.p2p.WifiP2pManager.ActionListener); method public void stopPeerDiscovery(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public void unregisterWifiP2pListener(@NonNull android.net.wifi.p2p.WifiP2pManager.WifiP2pListener); field public static final String ACTION_WIFI_P2P_LISTEN_STATE_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_LISTEN_STATE_CHANGED"; field public static final String ACTION_WIFI_P2P_REQUEST_RESPONSE_CHANGED = "android.net.wifi.p2p.action.WIFI_P2P_REQUEST_RESPONSE_CHANGED"; field public static final int BUSY = 2; // 0x2 @@ -1511,6 +1513,22 @@ package android.net.wifi.p2p { method public void onUpnpServiceAvailable(java.util.List<java.lang.String>, android.net.wifi.p2p.WifiP2pDevice); } + @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static interface WifiP2pManager.WifiP2pListener { + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onDeviceConfigurationChanged(@Nullable android.net.wifi.p2p.WifiP2pDevice); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onDiscoveryStateChanged(boolean); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onFrequencyChanged(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupCreated(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupCreating(); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupCreationFailed(); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupNegotiationRejectedByUser(); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onGroupRemoved(); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onListenStateChanged(boolean); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPeerClientDisconnected(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPeerClientJoined(@NonNull android.net.wifi.p2p.WifiP2pInfo, @NonNull android.net.wifi.p2p.WifiP2pGroup); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPeerListChanged(@NonNull android.net.wifi.p2p.WifiP2pDeviceList); + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onStateChanged(boolean); + } + public final class WifiP2pWfdInfo implements android.os.Parcelable { ctor public WifiP2pWfdInfo(); ctor public WifiP2pWfdInfo(@Nullable android.net.wifi.p2p.WifiP2pWfdInfo); diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt index 21fbe6f461..d645f7d494 100644 --- a/framework/api/system-current.txt +++ b/framework/api/system-current.txt @@ -1643,6 +1643,10 @@ package android.net.wifi.p2p { method public void onPersistentGroupInfoAvailable(@NonNull android.net.wifi.p2p.WifiP2pGroupList); } + @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public static interface WifiP2pManager.WifiP2pListener { + method @FlaggedApi("com.android.wifi.flags.android_v_wifi_api") public default void onPersistentGroupsChanged(@NonNull android.net.wifi.p2p.WifiP2pGroupList); + } + } package android.net.wifi.rtt { diff --git a/framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl b/framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl new file mode 100644 index 0000000000..4f9467101e --- /dev/null +++ b/framework/java/android/net/wifi/p2p/IWifiP2pListener.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.p2p; + +import android.net.wifi.p2p.WifiP2pDevice; +import android.net.wifi.p2p.WifiP2pDeviceList; +import android.net.wifi.p2p.WifiP2pInfo; +import android.net.wifi.p2p.WifiP2pGroup; +import android.net.wifi.p2p.WifiP2pGroupList; + +/** + * Interface for Wi-Fi p2p listener. + * @hide + */ +oneway interface IWifiP2pListener +{ + void onStateChanged(boolean p2pEnabled); + void onDiscoveryStateChanged(boolean started); + void onListenStateChanged(boolean started); + void onDeviceConfigurationChanged(in WifiP2pDevice p2pDevice); + void onPeerListChanged(in WifiP2pDeviceList p2pDeviceList); + void onPersistentGroupsChanged(in WifiP2pGroupList p2pGroupList); + void onGroupCreating(); + void onGroupNegotiationRejectedByUser(); + void onGroupCreationFailed(); + void onGroupCreated(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup); + void onPeerClientJoined(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup); + void onPeerClientDisconnected(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup); + void onFrequencyChanged(in WifiP2pInfo p2pInfo, in WifiP2pGroup p2pGroup); + void onGroupRemoved(); +} diff --git a/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl index f29a9b3c3a..088ead4927 100644 --- a/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl +++ b/framework/java/android/net/wifi/p2p/IWifiP2pManager.aidl @@ -16,6 +16,8 @@ package android.net.wifi.p2p; +import android.net.wifi.p2p.IWifiP2pListener; + import android.os.Bundle; import android.os.Messenger; @@ -32,5 +34,7 @@ interface IWifiP2pManager void setMiracastMode(int mode); void checkConfigureWifiDisplayPermission(); long getSupportedFeatures(); + void registerWifiP2pListener(in IWifiP2pListener listener, in String packageName, in Bundle extras); + void unregisterWifiP2pListener(in IWifiP2pListener listener); } diff --git a/framework/java/android/net/wifi/p2p/WifiP2pManager.java b/framework/java/android/net/wifi/p2p/WifiP2pManager.java index 4129a5bd84..3600f74b14 100644 --- a/framework/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/framework/java/android/net/wifi/p2p/WifiP2pManager.java @@ -51,6 +51,7 @@ import android.os.RemoteException; import android.text.TextUtils; import android.util.CloseGuard; import android.util.Log; +import android.util.SparseArray; import android.view.Display; import androidx.annotation.RequiresApi; @@ -588,6 +589,8 @@ public class WifiP2pManager { */ private static final int WIFI_P2P_VENDOR_ELEMENTS_MAXIMUM_LENGTH = 512; + private Context mContext; + IWifiP2pManager mService; private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; @@ -861,6 +864,7 @@ public class WifiP2pManager { /** @hide */ public static final int RESPONSE_GET_LISTEN_STATE = BASE + 118; + private static final SparseArray<IWifiP2pListener> sWifiP2pListenerMap = new SparseArray<>(); /** * Create a new WifiP2pManager instance. Applications use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve @@ -1247,6 +1251,316 @@ public class WifiP2pManager { void onPinGenerated(@NonNull MacAddress deviceAddress, @NonNull String pin); } + /** + * Interface used to listen to Wi-Fi p2p various changes such as device state change, + * discovery started/stopped, connection change, etc. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + public interface WifiP2pListener { + /** + * Called when Wi-Fi p2p has been enabled or disabled. + * @see #WIFI_P2P_STATE_CHANGED_ACTION + * @see #requestP2pState(Channel, P2pStateListener) + * + * @param p2pEnabled indicates whether Wi-Fi p2p is enabled or disabled. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onStateChanged(boolean p2pEnabled) { + } + + /** + * Called when peer discovery has either started or stopped. + * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION + * @see #requestDiscoveryState(Channel, DiscoveryStateListener) + * + * @param started indicates whether discovery has started or stopped. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onDiscoveryStateChanged(boolean started) { + } + + /** + * Called when peer listen has either started or stopped. + * @see #ACTION_WIFI_P2P_LISTEN_STATE_CHANGED + * @see #getListenState(Channel, Executor, Consumer) + * + * @param started indicates whether listen has started or stopped. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onListenStateChanged(boolean started) { + } + + /** + * Called when this device details have changed. + * @see #WIFI_P2P_THIS_DEVICE_CHANGED_ACTION + * @see #requestDeviceInfo(Channel, DeviceInfoListener) + * + * @param p2pDevice provides this device details. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onDeviceConfigurationChanged(@Nullable WifiP2pDevice p2pDevice) { + } + + /** + * Called when the available peer list has changed. This can be sent as a result of peers + * being found, lost or updated. + * @see #WIFI_P2P_PEERS_CHANGED_ACTION + * @see #requestPeers(Channel, PeerListListener) + * + * @param p2pDeviceList provides the full list of current peers. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onPeerListChanged(@NonNull WifiP2pDeviceList p2pDeviceList) { + } + + /** + * Called when remembered persistent groups have changed. + * @see #ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED + * @see #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener) + * + * @param p2pGroupList provides the full list of p2p group. + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onPersistentGroupsChanged(@NonNull WifiP2pGroupList p2pGroupList) { + } + + /** + * Called when either group owner or group client is creating p2p group. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onGroupCreating() { + } + + /** + * Called when group negotiation has been rejected by user. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onGroupNegotiationRejectedByUser() { + } + + /** + * Called when group creation has failed. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onGroupCreationFailed() { + } + + /** + * Called when either group owner or group client has created p2p group successfully. + * + * @param p2pInfo provides the p2p connection info. + * @param p2pGroup provides the details of the group. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onGroupCreated(@NonNull WifiP2pInfo p2pInfo, + @NonNull WifiP2pGroup p2pGroup) { + } + + /** + * Called to indicate group owner that a group client has joined p2p group successfully. + * + * @param p2pInfo provides the p2p connection info. + * @param p2pGroup provides the details of the group. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onPeerClientJoined(@NonNull WifiP2pInfo p2pInfo, + @NonNull WifiP2pGroup p2pGroup) { + } + + /** + * Called to indicate group owner that a group client has disconnected. + * + * @param p2pInfo provides the p2p connection info. + * @param p2pGroup provides the details of the group. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onPeerClientDisconnected(@NonNull WifiP2pInfo p2pInfo, + @NonNull WifiP2pGroup p2pGroup) { + } + + /** + * Called when the frequency of a formed group has been changed. + * + * @param p2pInfo provides the p2p connection info. + * @param p2pGroup provides the details of the group. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onFrequencyChanged(@NonNull WifiP2pInfo p2pInfo, + @NonNull WifiP2pGroup p2pGroup) { + } + + /** + * Called when p2p group has been removed. + */ + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + default void onGroupRemoved() { + } + } + + /** + * Helper class to support wifi p2p listener. + */ + private static class OnWifiP2pListenerProxy extends IWifiP2pListener.Stub { + @NonNull + private Executor mExecutor; + @NonNull + private WifiP2pListener mListener; + + OnWifiP2pListenerProxy(@NonNull Executor executor, + @NonNull WifiP2pListener listener) { + Objects.requireNonNull(executor); + Objects.requireNonNull(listener); + mExecutor = executor; + mListener = listener; + } + + @Override + public void onStateChanged(boolean p2pEnabled) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onStateChanged(p2pEnabled)); + } + + @Override + public void onDiscoveryStateChanged(boolean started) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onDiscoveryStateChanged(started)); + } + + @Override + public void onListenStateChanged(boolean started) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onListenStateChanged(started)); + } + + @Override + public void onDeviceConfigurationChanged(WifiP2pDevice p2pDevice) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onDeviceConfigurationChanged(p2pDevice)); + } + + @Override + public void onPeerListChanged(WifiP2pDeviceList p2pDeviceList) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onPeerListChanged(p2pDeviceList)); + } + + @Override + public void onPersistentGroupsChanged(WifiP2pGroupList p2pGroupList) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onPersistentGroupsChanged(p2pGroupList)); + } + + @Override + public void onGroupCreating() { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onGroupCreating()); + } + + @Override + public void onGroupNegotiationRejectedByUser() { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onGroupNegotiationRejectedByUser()); + } + + @Override + public void onGroupCreationFailed() { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onGroupCreationFailed()); + } + + @Override + public void onGroupCreated(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onGroupCreated(p2pInfo, p2pGroup)); + } + + @Override + public void onPeerClientJoined(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onPeerClientJoined(p2pInfo, p2pGroup)); + } + + @Override + public void onPeerClientDisconnected(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onPeerClientDisconnected(p2pInfo, p2pGroup)); + } + + @Override + public void onFrequencyChanged(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onFrequencyChanged(p2pInfo, p2pGroup)); + } + + @Override + public void onGroupRemoved() { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> mListener.onGroupRemoved()); + } + } + + /** + * Add a listener to listen to Wi-Fi p2p various changes. + * + * @param executor the Executor on which to execute the callbacks. + * @param listener listener for the Wi-Fi p2p connection changes. + * @throws SecurityException if the caller is missing required permissions. + * @throws IllegalArgumentException if incorrect input arguments are provided. + */ + @RequiresPermission(allOf = { + android.Manifest.permission.NEARBY_WIFI_DEVICES, + android.Manifest.permission.ACCESS_WIFI_STATE + }, conditional = true) + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + public void registerWifiP2pListener(@NonNull @CallbackExecutor Executor executor, + @NonNull WifiP2pListener listener) { + Log.d(TAG, "registerWifiP2pListener: listener=" + listener + ", executor=" + executor); + final int listenerIdentifier = System.identityHashCode(listener); + synchronized (sWifiP2pListenerMap) { + try { + IWifiP2pListener.Stub listenerProxy = new OnWifiP2pListenerProxy(executor, + listener); + sWifiP2pListenerMap.put(listenerIdentifier, listenerProxy); + Bundle extras = prepareExtrasBundleWithAttributionSource(mContext); + mService.registerWifiP2pListener(listenerProxy, mContext.getOpPackageName(), + extras); + } catch (RemoteException e) { + sWifiP2pListenerMap.remove(listenerIdentifier); + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Remove a listener added using + * {@link #registerWifiP2pListener(Executor, WifiP2pListener)} + * + * @param listener the listener to be removed. + * @throws IllegalArgumentException if incorrect input arguments are provided. + */ + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) + public void unregisterWifiP2pListener(@NonNull WifiP2pListener listener) { + Log.d(TAG, "unregisterWifiP2pListener: listener=" + listener); + final int listenerIdentifier = System.identityHashCode(listener); + synchronized (sWifiP2pListenerMap) { + try { + if (!sWifiP2pListenerMap.contains(listenerIdentifier)) { + Log.w(TAG, "Unknown external listener " + listenerIdentifier); + return; + } + mService.unregisterWifiP2pListener(sWifiP2pListenerMap.get(listenerIdentifier)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } finally { + sWifiP2pListenerMap.remove(listenerIdentifier); + } + } + } /** * A channel that connects the application to the Wifi p2p framework. @@ -1646,6 +1960,7 @@ public class WifiP2pManager { extras.putInt(EXTRA_PARAM_KEY_DISPLAY_ID, displayId); Channel channel = initializeChannel(srcContext, srcLooper, listener, getMessenger(binder, srcContext.getOpPackageName(), extras), binder); + mContext = srcContext; return channel; } diff --git a/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java b/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java index 15116ebb47..21c42d8760 100644 --- a/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java +++ b/framework/tests/src/android/net/wifi/p2p/WifiP2pManagerTest.java @@ -34,6 +34,7 @@ import static org.mockito.Mockito.when; import android.content.AttributionSource; import android.content.Context; import android.net.wifi.ScanResult; +import android.net.wifi.SynchronousExecutor; import android.os.Bundle; import android.os.test.TestLooper; import android.view.Display; @@ -267,4 +268,17 @@ public class WifiP2pManagerTest { WifiP2pManager.FEATURE_GROUP_OWNER_IPV6_LINK_LOCAL_ADDRESS_PROVIDED); assertTrue(mDut.isGroupOwnerIPv6LinkLocalAddressProvided()); } + + @Test + public void testWifiP2pListener() throws Exception { + assumeTrue(SdkLevel.isAtLeastT()); + SynchronousExecutor executor = mock(SynchronousExecutor.class); + WifiP2pManager.WifiP2pListener listener = mock(WifiP2pManager.WifiP2pListener.class); + mDut.initialize(mContextMock, mTestLooper.getLooper(), null); + mDut.registerWifiP2pListener(executor, listener); + verify(mP2pServiceMock).registerWifiP2pListener(any(IWifiP2pListener.Stub.class), + eq(PACKAGE_NAME), any(Bundle.class)); + mDut.unregisterWifiP2pListener(listener); + verify(mP2pServiceMock).unregisterWifiP2pListener(any(IWifiP2pListener.Stub.class)); + } } diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java index d8439f7152..f82807e486 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java @@ -65,6 +65,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WpsInfo; +import android.net.wifi.p2p.IWifiP2pListener; import android.net.wifi.p2p.IWifiP2pManager; import android.net.wifi.p2p.WifiP2pConfig; import android.net.wifi.p2p.WifiP2pDevice; @@ -93,6 +94,7 @@ import android.os.Message; import android.os.Messenger; import android.os.ParcelFileDescriptor; import android.os.Process; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -172,6 +174,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; import java.util.stream.Collectors; /** @@ -458,6 +461,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { @VisibleForTesting static final String GO_EAPOL_IP_RANGE_DEFAULT_END_ADDRESS = "192.168.49.254"; + private final RemoteCallbackList<IWifiP2pListener> mWifiP2pListeners = + new RemoteCallbackList<>(); + /** * Error code definition. * see the Table.8 in the WiFi Direct specification for the detail. @@ -1094,6 +1100,208 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { return mWifiNative.getSupportedFeatures(); } + /** + * See {@link WifiP2pManager#registerWifiP2pListener(Executor, WifiP2pManager.WifiP2pListener)} + */ + @Override + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public void registerWifiP2pListener(IWifiP2pListener listener, String packageName, + Bundle extras) { + if (!SdkLevel.isAtLeastT()) { + throw new UnsupportedOperationException(); + } + if (listener == null) { + throw new IllegalArgumentException("listener should not be null"); + } + mWifiPermissionsUtil.enforceNearbyDevicesPermission( + extras.getParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE), false, + TAG + " registerWifiP2pListener"); + Log.i(TAG, "registerWifiP2pListener uid=" + Binder.getCallingUid()); + mWifiP2pListeners.register(listener); + } + + /** + * See {@link WifiP2pManager#unregisterWifiP2pListener(WifiP2pManager.WifiP2pListener)} + */ + @Override + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public void unregisterWifiP2pListener(IWifiP2pListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + Log.i(TAG, "unregisterWifiP2pListener uid=" + Binder.getCallingUid()); + mWifiP2pListeners.unregister(listener); + } + + private void onStateChanged(boolean p2pEnabled) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onStateChanged(p2pEnabled); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onStateChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onDiscoveryStateChanged(boolean started) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onDiscoveryStateChanged(started); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onDiscoveryStateChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onListenStateChanged(boolean started) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onListenStateChanged(started); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onListenStateChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onDeviceConfigurationChanged(WifiP2pDevice p2pDevice) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onDeviceConfigurationChanged(p2pDevice); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onDeviceConfigurationChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onPeerListChanged(WifiP2pDeviceList p2pDeviceList) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onPeerListChanged(p2pDeviceList); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onPeerListChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onPersistentGroupsChanged(WifiP2pGroupList p2pGroupList) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onPersistentGroupsChanged(p2pGroupList); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onPersistentGroupsChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onGroupCreating() { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onGroupCreating(); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onGroupCreating" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onGroupNegotiationRejectedByUser() { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onGroupNegotiationRejectedByUser(); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onGroupNegotiationRejectedByUser" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onGroupCreationFailed() { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onGroupCreationFailed(); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onGroupCreationFailed" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onGroupCreated(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onGroupCreated(p2pInfo, p2pGroup); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onGroupCreated" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onPeerClientJoined(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onPeerClientJoined(p2pInfo, p2pGroup); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onPeerClientJoined" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onPeerClientDisconnected(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onPeerClientDisconnected(p2pInfo, + p2pGroup); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onPeerClientDisconnected" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onFrequencyChanged(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onFrequencyChanged(p2pInfo, p2pGroup); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onFrequencyChanged" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + + private void onGroupRemoved() { + int numCallbacks = mWifiP2pListeners.beginBroadcast(); + for (int i = 0; i < numCallbacks; i++) { + try { + mWifiP2pListeners.getBroadcastItem(i).onGroupRemoved(); + } catch (RemoteException e) { + Log.e(TAG, "Failure calling onGroupRemoved" + e); + } + } + mWifiP2pListeners.finishBroadcast(); + } + private boolean getWfdPermission(int uid) { WifiPermissionsWrapper wifiPermissionsWrapper = mWifiInjector.getWifiPermissionsWrapper(); return wifiPermissionsWrapper.getUidPermission( @@ -3879,6 +4087,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { public void enterImpl() { logSmStateName(this.getName(), getCurrentState() != null ? getCurrentState().getName() : ""); + onGroupCreating(); if (SdkLevel.isAtLeastT()) { mDetailedState = NetworkInfo.DetailedState.CONNECTING; sendP2pConnectionChangedBroadcast(); @@ -4057,6 +4266,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { int delay = sendP2pRejection(); mDetailedState = NetworkInfo.DetailedState.DISCONNECTED; + onGroupNegotiationRejectedByUser(); sendP2pConnectionChangedBroadcast(); mSavedPeerConfig.invalidate(); transitionTo(mP2pRejectWaitState); @@ -4780,6 +4990,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { // In case of a negotiation group, connection changed is sent // after a client joins. For autonomous, send now if (mAutonomousGroup) { + onGroupCreated(new WifiP2pInfo(mWifiP2pInfo), eraseOwnDeviceAddress(mGroup)); sendP2pConnectionChangedBroadcast(); } @@ -4824,6 +5035,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { } else { loge("Connect on null device address, ignore"); } + onPeerClientJoined(new WifiP2pInfo(mWifiP2pInfo), + eraseOwnDeviceAddress(mGroup)); sendP2pConnectionChangedBroadcast(); break; } @@ -4846,6 +5059,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { // We end up sending connection changed broadcast // when this happens at exit() } else { + onPeerClientDisconnected(new WifiP2pInfo(mWifiP2pInfo), + eraseOwnDeviceAddress(mGroup)); // Notify when a client disconnects from group sendP2pConnectionChangedBroadcast(); } @@ -4935,6 +5150,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { } catch (Exception e) { loge("Failed to add iface to local network " + e); } + onGroupCreated(new WifiP2pInfo(mWifiP2pInfo), + eraseOwnDeviceAddress(mGroup)); sendP2pConnectionChangedBroadcast(); break; case IPC_PROVISIONING_SUCCESS: @@ -4959,6 +5176,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { byte[] goInterfaceMacAddress = mGroup.interfaceAddress; if (goInterfaceMacAddress == null) { setWifiP2pInfoOnGroupFormationWithInetAddress(null); + onGroupCreated(new WifiP2pInfo(mWifiP2pInfo), + eraseOwnDeviceAddress(mGroup)); sendP2pConnectionChangedBroadcast(); break; } @@ -4969,6 +5188,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { InetAddress goIp = Inet6Address.getByAddress(null, goIpv6Address, NetworkInterface.getByName(mGroup.getInterface())); setWifiP2pInfoOnGroupFormationWithInetAddress(goIp); + onGroupCreated(new WifiP2pInfo(mWifiP2pInfo), + eraseOwnDeviceAddress(mGroup)); sendP2pConnectionChangedBroadcast(); } catch (UnknownHostException | SocketException e) { loge("Unable to retrieve link-local IPv6 address of group owner " @@ -5195,6 +5416,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { case WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT: if (mGroup != null) { mGroup.setFrequency(message.arg1); + onFrequencyChanged(new WifiP2pInfo(mWifiP2pInfo), + eraseOwnDeviceAddress(mGroup)); sendP2pConnectionChangedBroadcast(); } break; @@ -5245,6 +5468,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { updateThisDevice(WifiP2pDevice.AVAILABLE); resetWifiP2pInfo(); mDetailedState = NetworkInfo.DetailedState.DISCONNECTED; + onGroupRemoved(); sendP2pConnectionChangedBroadcast(); if (!SdkLevel.isAtLeastU()) { // Ensure tethering service to stop tethering. @@ -5428,6 +5652,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { } private void sendP2pStateChangedBroadcast(boolean enabled) { + onStateChanged(enabled); final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); if (enabled) { @@ -5445,6 +5670,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { mDiscoveryStarted = started; if (mVerboseLoggingEnabled) logd("discovery change broadcast " + started); + onDiscoveryStateChanged(started); final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); @@ -5459,6 +5685,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { mListenStarted = started; if (mVerboseLoggingEnabled) logd("wifi p2p listen change broadcast " + started); + onListenStateChanged(started); final Intent intent = new Intent(WifiP2pManager.ACTION_WIFI_P2P_LISTEN_STATE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); @@ -5516,16 +5743,21 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { } private void sendThisDeviceChangedBroadcast() { + WifiP2pDevice p2pDevice = eraseOwnDeviceAddress(mThisDevice); + onDeviceConfigurationChanged(p2pDevice); + final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, - eraseOwnDeviceAddress(mThisDevice)); + intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, p2pDevice); sendBroadcastWithExcludedPermissions(intent, null); } private void sendPeersChangedBroadcast() { + WifiP2pDeviceList p2pDeviceList = new WifiP2pDeviceList(mPeers); + onPeerListChanged(p2pDeviceList); + final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); - intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, new WifiP2pDeviceList(mPeers)); + intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, p2pDeviceList); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); sendBroadcastWithExcludedPermissions(intent, null); } @@ -5671,6 +5903,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { } private void sendP2pPersistentGroupsChangedBroadcast() { + onPersistentGroupsChanged(new WifiP2pGroupList(mGroups, null)); if (mVerboseLoggingEnabled) logd("sending p2p persistent groups changed broadcast"); Intent intent = new Intent(WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); @@ -6702,6 +6935,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { } resetWifiP2pInfo(); mDetailedState = NetworkInfo.DetailedState.FAILED; + onGroupCreationFailed(); sendP2pConnectionChangedBroadcast(); // Remove only the peer we failed to connect to so that other devices discovered diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java index 49ea05c2fa..e04f92fd84 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java @@ -94,6 +94,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiScanner; import android.net.wifi.WpsInfo; +import android.net.wifi.p2p.IWifiP2pListener; import android.net.wifi.p2p.WifiP2pConfig; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; @@ -111,10 +112,12 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; +import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.PersistableBundle; import android.os.Process; +import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; @@ -199,6 +202,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { private static final String thisDeviceName = "thisDeviceName"; private static final String ANONYMIZED_DEVICE_ADDRESS = "02:00:00:00:00:00"; private static final String TEST_PACKAGE_NAME = "com.p2p.test"; + private static final String TEST_NETWORK_NAME = "DIRECT-xy-NEW"; private static final String TEST_ANDROID_ID = "314Deadbeef"; private static final String[] TEST_REQUIRED_PERMISSIONS_T = new String[] { @@ -246,6 +250,8 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { private ArgumentCaptor<TetheringManager.TetheringEventCallback> mTetheringEventCallbackCaptor = ArgumentCaptor.forClass(TetheringManager.TetheringEventCallback.class); private TetheringManager.TetheringEventCallback mTetheringEventCallback; + private Bundle mExtras = new Bundle(); + private IWifiP2pListener mP2pListener = mock(IWifiP2pListener.class); private ArgumentCaptor<WifiSettingsConfigStore.OnSettingsChangedListener> mD2DAllowedSettingsCallbackCaptor = ArgumentCaptor.forClass(WifiSettingsConfigStore.OnSettingsChangedListener.class); @@ -327,7 +333,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { // for general group started event mTestWifiP2pNewPersistentGoGroup = new WifiP2pGroup(); mTestWifiP2pNewPersistentGoGroup.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - mTestWifiP2pNewPersistentGoGroup.setNetworkName("DIRECT-xy-NEW"); + mTestWifiP2pNewPersistentGoGroup.setNetworkName(TEST_NETWORK_NAME); mTestWifiP2pNewPersistentGoGroup.setOwner(new WifiP2pDevice(thisDeviceMac)); mTestWifiP2pNewPersistentGoGroup.setIsGroupOwner(true); mTestWifiP2pNewPersistentGoGroup.setInterface(IFACE_NAME_P2P); @@ -1272,7 +1278,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { /** * Check the broadcast of WIFI_P2P_THIS_DEVICE_CHANGED_ACTION is sent as expected. */ - private void checkSendThisDeviceChangedBroadcast() { + private void checkSendThisDeviceChangedBroadcast() throws RemoteException { ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); String[] permission_gold; if (mWifiPermissionsUtil.isLocationModeEnabled()) { @@ -1314,6 +1320,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { } verifyDeviceChangedBroadcastIntent(intentCaptor.getValue()); } + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener, atLeastOnce()).onDeviceConfigurationChanged(any()); + } } /** @@ -1507,6 +1516,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { when(mWifiInjector.getWifiHandlerLocalLog()).thenReturn(mLocalLog); when(mDeviceConfigFacade.isP2pFailureBugreportEnabled()).thenReturn(false); when(mContext.getSystemService(TetheringManager.class)).thenReturn(mTetheringManager); + when(mP2pListener.asBinder()).thenReturn(mock(IBinder.class)); mWifiP2pServiceImpl = new WifiP2pServiceImpl(mContext, mWifiInjector); if (supported) { @@ -1567,6 +1577,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { mClient2 = new Binder(); when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext); mWifiP2pServiceImpl.handleBootCompleted(); + if (SdkLevel.isAtLeastT()) { + mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener, TEST_PACKAGE_NAME, mExtras); + } } @After @@ -1619,7 +1632,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { forceP2pEnabled(mClient1); WifiP2pGroup group = new WifiP2pGroup(); group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - group.setNetworkName("DIRECT-xy-NEW"); + group.setNetworkName(TEST_NETWORK_NAME); group.setOwner(new WifiP2pDevice("thisDeviceMac")); group.setIsGroupOwner(true); group.setInterface(IFACE_NAME_P2P); @@ -1773,6 +1786,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { inOrder.verify(mContext).sendStickyBroadcastAsUser(argThat( new WifiP2pServiceImplTest.P2pStateChangedIntentMatcher( WifiP2pManager.WIFI_P2P_STATE_ENABLED)), any()); + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener).onStateChanged(eq(true)); + } // disabled broadcast sent when user restriction is set simulateUserRestrictionChange(true); @@ -1780,6 +1796,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { inOrder.verify(mContext).sendStickyBroadcastAsUser(argThat( new WifiP2pServiceImplTest.P2pStateChangedIntentMatcher( WifiP2pManager.WIFI_P2P_STATE_DISABLED)), any()); + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener).onStateChanged(eq(false)); + } // no disabled broadcast sent when Wi-Fi is disabled since broadcast already sent simulateWifiStateChange(false); @@ -2248,6 +2267,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { assertTrue(mClientHandler.hasMessages(WifiP2pManager.DISCOVER_PEERS_SUCCEEDED)); verify(mLastCallerInfoManager).put(eq(WifiManager.API_P2P_DISCOVER_PEERS), anyInt(), anyInt(), anyInt(), anyString(), eq(true)); + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener).onDiscoveryStateChanged(eq(true)); + } } /** @@ -2813,6 +2835,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { verify(mWifiPermissionsUtil).checkCanAccessWifiDirect(eq(TEST_PACKAGE_NAME), eq("testFeature"), anyInt(), eq(true)); } + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener).onListenStateChanged(eq(true)); + } } /** @@ -3416,7 +3441,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { WifiP2pGroup group = new WifiP2pGroup(); group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - group.setNetworkName("DIRECT-xy-NEW"); + group.setNetworkName(TEST_NETWORK_NAME); group.setOwner(new WifiP2pDevice("thisDeviceMac")); group.setIsGroupOwner(true); group.setInterface(IFACE_NAME_P2P); @@ -3722,7 +3747,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { WifiP2pServiceImpl.P2pStatus.NO_COMMON_CHANNEL); WifiP2pGroup group = new WifiP2pGroup(); group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - group.setNetworkName("DIRECT-xy-NEW"); + group.setNetworkName(TEST_NETWORK_NAME); group.setOwner(new WifiP2pDevice("thisDeviceMac")); group.setIsGroupOwner(true); group.setInterface(IFACE_NAME_P2P); @@ -5323,6 +5348,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { when(mWifiNative.p2pListNetworks(any())).thenReturn(true); sendSimpleMsg(mClientMessenger, WifiP2pManager.FACTORY_RESET); checkSendP2pPersistentGroupsChangedBroadcast(); + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener, atLeastOnce()).onPersistentGroupsChanged(any()); + } verify(mWifiInjector).getUserManager(); verify(mPackageManager).getNameForUid(anyInt()); verify(mWifiPermissionsUtil).checkNetworkSettingsPermission(anyInt()); @@ -6476,7 +6504,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { WifiP2pGroup group = new WifiP2pGroup(); group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - group.setNetworkName("DIRECT-xy-NEW"); + group.setNetworkName(TEST_NETWORK_NAME); group.setOwner(new WifiP2pDevice("thisDeviceMac")); group.setIsGroupOwner(true); group.setInterface(IFACE_NAME_P2P); @@ -6659,7 +6687,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { forceP2pEnabled(mClient1); WifiP2pGroup group = new WifiP2pGroup(); group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - group.setNetworkName("DIRECT-xy-NEW"); + group.setNetworkName(TEST_NETWORK_NAME); group.setOwner(new WifiP2pDevice("thisDeviceMac")); group.setIsGroupOwner(true); group.setInterface(IFACE_NAME_P2P); @@ -7437,7 +7465,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { WifiP2pMonitor.PROV_DISC_STATUS_REJECTED, pdEvent); verify(mWifiNative).p2pCancelConnect(); - + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener).onGroupCreationFailed(); + } } /** @@ -7468,6 +7498,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { sendSimpleMsg(null, WifiP2pServiceImpl.PEER_CONNECTION_USER_REJECT); verify(mWifiNative).p2pReject(eq(mTestWifiP2pDevice.deviceAddress)); + if (SdkLevel.isAtLeastT()) { + verify(mP2pListener).onGroupNegotiationRejectedByUser(); + } } /** @@ -7695,7 +7728,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { forceP2pEnabled(mClient1); WifiP2pGroup group = new WifiP2pGroup(); group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); - group.setNetworkName("DIRECT-xy-NEW"); + group.setNetworkName(TEST_NETWORK_NAME); group.setOwner(new WifiP2pDevice("thisDeviceMac")); group.setIsGroupOwner(true); group.setInterface(IFACE_NAME_P2P); @@ -8037,6 +8070,64 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { new WorkSource(mClient1.getCallingUid(), TEST_PACKAGE_NAME)); } + @Test + public void testWifiP2pListener() throws Exception { + assumeTrue(SdkLevel.isAtLeastT()); + forceP2pEnabled(mClient1); + when(mWifiNative.p2pGroupAdd(any(), eq(false))).thenReturn(true); + WifiP2pGroup p2pGroup = new WifiP2pGroup(); + p2pGroup.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT); + p2pGroup.setNetworkName(TEST_NETWORK_NAME); + p2pGroup.setOwner(new WifiP2pDevice("thisDeviceMac")); + p2pGroup.setIsGroupOwner(true); + p2pGroup.setInterface(IFACE_NAME_P2P); + + sendCreateGroupMsgWithConfigValidAsGroup(mClientMessenger); + sendGroupStartedMsg(p2pGroup); + simulateTetherReady(); + verify(mP2pListener).onGroupCreating(); + ArgumentCaptor<WifiP2pInfo> p2pInfoCaptor = ArgumentCaptor.forClass(WifiP2pInfo.class); + ArgumentCaptor<WifiP2pGroup> p2pGroupCaptor = ArgumentCaptor.forClass(WifiP2pGroup.class); + verify(mP2pListener).onGroupCreated(p2pInfoCaptor.capture(), p2pGroupCaptor.capture()); + assertEquals(TEST_NETWORK_NAME, p2pGroupCaptor.getValue().getNetworkName()); + assertTrue(p2pGroupCaptor.getValue().isClientListEmpty()); + assertTrue(p2pInfoCaptor.getValue().groupFormed); + + WifiP2pDevice peerClientDevice = new WifiP2pDevice(); + peerClientDevice.deviceName = "peerClientDeviceName"; + peerClientDevice.deviceAddress = "11:22:33:aa:bb:cc"; + peerClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS)); + sendSimpleMsg(null, WifiP2pMonitor.AP_STA_CONNECTED_EVENT, peerClientDevice); + verify(mP2pListener).onPeerClientJoined(p2pInfoCaptor.capture(), + p2pGroupCaptor.capture()); + assertFalse(p2pGroupCaptor.getValue().isClientListEmpty()); + assertTrue(p2pInfoCaptor.getValue().groupFormed); + + sendSimpleMsg(null, WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT, peerClientDevice); + verify(mP2pListener).onPeerClientDisconnected(p2pInfoCaptor.capture(), + p2pGroupCaptor.capture()); + assertTrue(p2pGroupCaptor.getValue().isClientListEmpty()); + assertTrue(p2pInfoCaptor.getValue().groupFormed); + verify(mP2pListener, atLeastOnce()).onPeerListChanged(any()); + + sendSimpleMsg(null, WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT, TEST_GROUP_FREQUENCY); + verify(mP2pListener).onFrequencyChanged(p2pInfoCaptor.capture(), + p2pGroupCaptor.capture()); + assertEquals(TEST_GROUP_FREQUENCY, p2pGroupCaptor.getValue().getFrequency()); + + sendGroupRemovedMsg(); + mockEnterDisabledState(); + mLooper.dispatchAll(); + verify(mP2pListener).onGroupRemoved(); + + mWifiP2pServiceImpl.unregisterWifiP2pListener(mP2pListener); + doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceNearbyDevicesPermission( + any(), anyBoolean(), any()); + assertThrows(SecurityException.class, + () -> mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener, TEST_PACKAGE_NAME, + mExtras)); + } + /** * Verify that p2p disable when the D2d allowed value changes to false */ |