Use direct callback for tethering p2p localonly interface state change
Bug: 263198976
Test: atest com.android.server.wifi.p2p.WifiP2pServiceImplTest
Test: manual test with p2p test app and nearby
Change-Id: I37defe3d8a3ca266548292e494a59328ead40525
Merged-In: I37defe3d8a3ca266548292e494a59328ead40525
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 6434672..22fa00d 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -41,7 +41,9 @@
import android.net.MacAddress;
import android.net.NetworkInfo;
import android.net.NetworkStack;
+import android.net.TetheringInterface;
import android.net.TetheringManager;
+import android.net.TetheringManager.TetheringEventCallback;
import android.net.ip.IIpClient;
import android.net.ip.IpClientCallbacks;
import android.net.ip.IpClientUtil;
@@ -216,6 +218,7 @@
private WifiGlobals mWifiGlobals;
private UserManager mUserManager;
private InterfaceConflictManager mInterfaceConflictManager;
+ private TetheringManager mTetheringManager = null;
private WifiP2pNative mWifiNative;
private static final Boolean JOIN_GROUP = true;
@@ -307,8 +310,8 @@
private static final int IPC_DHCP_RESULTS = BASE + 32;
private static final int IPC_PROVISIONING_SUCCESS = BASE + 33;
private static final int IPC_PROVISIONING_FAILURE = BASE + 34;
-
- private static final int TETHER_INTERFACE_STATE_CHANGED = BASE + 35;
+ @VisibleForTesting
+ static final int TETHER_INTERFACE_STATE_CHANGED = BASE + 35;
private static final int UPDATE_P2P_DISALLOWED_CHANNELS = BASE + 36;
@@ -649,6 +652,10 @@
public void handleBootCompleted() {
updateVerboseLoggingEnabled();
mIsBootComplete = true;
+ mTetheringManager = mContext.getSystemService(TetheringManager.class);
+ if (mTetheringManager == null) {
+ Log.wtf(TAG, "Tethering manager is null when WifiP2pServiceImp handles boot completed");
+ }
}
private void updateVerboseLoggingEnabled() {
@@ -1024,6 +1031,21 @@
private WifiP2pMonitor mWifiMonitor = mWifiInjector.getWifiP2pMonitor();
private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
private String mInterfaceName;
+ private TetheringEventCallback mTetheringEventCallback =
+ new TetheringManager.TetheringEventCallback() {
+ @Override
+ public void onLocalOnlyInterfacesChanged(Set<TetheringInterface> interfaces) {
+ ArrayList<String> ifaceList = interfaces.stream().map(
+ p -> p.getInterface()).collect(
+ Collectors.toCollection(ArrayList::new));
+ if (interfaces.stream().anyMatch(
+ p -> p.getType() == TetheringManager.TETHERING_WIFI_P2P)) {
+ logd(getName() + " Tethering localOnlyInterfacesChanged"
+ + " callback for ifaceList: " + ifaceList);
+ sendMessage(TETHER_INTERFACE_STATE_CHANGED, ifaceList);
+ }
+ }
+ };
private List<CoexUnsafeChannel> mCoexUnsafeChannels = new ArrayList<>();
private int mUserListenChannel = 0;
@@ -1132,16 +1154,6 @@
}
}
}, new IntentFilter(LocationManager.MODE_CHANGED_ACTION));
- // Register for tethering state
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final ArrayList<String> interfaces = intent.getStringArrayListExtra(
- TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY);
-
- sendMessage(TETHER_INTERFACE_STATE_CHANGED, interfaces);
- }
- }, new IntentFilter(TetheringManager.ACTION_TETHER_STATE_CHANGED));
mSettingsConfigStore.registerChangeListener(
WIFI_VERBOSE_LOGGING_ENABLED,
(key, newValue) -> enableVerboseLogging(newValue),
@@ -2415,6 +2427,10 @@
sendP2pConnectionChangedBroadcast();
initializeP2pSettings();
+ if (mTetheringManager != null) {
+ mTetheringManager.registerTetheringEventCallback(getHandler()::post,
+ mTetheringEventCallback);
+ }
}
@Override
@@ -2817,6 +2833,9 @@
mUserListenChannel = 0;
mUserOperatingChannel = 0;
mCoexUnsafeChannels.clear();
+ if (mTetheringManager != null) {
+ mTetheringManager.unregisterTetheringEventCallback(mTetheringEventCallback);
+ }
}
}
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 d5f3ea3..a5ff227 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
@@ -77,6 +77,7 @@
import android.net.InetAddresses;
import android.net.MacAddress;
import android.net.NetworkInfo;
+import android.net.TetheringInterface;
import android.net.TetheringManager;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
@@ -110,6 +111,7 @@
import android.os.test.TestLooper;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
@@ -162,6 +164,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Unit test harness for WifiP2pServiceImpl.
@@ -200,7 +203,6 @@
private BroadcastReceiver mLocationModeReceiver;
private BroadcastReceiver mWifiStateChangedReceiver;
- private BroadcastReceiver mTetherStateReceiver;
private BroadcastReceiver mUserRestrictionReceiver;
private Handler mClientHandler;
private Messenger mP2pStateMachineMessenger;
@@ -219,6 +221,9 @@
private ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class);
private MockitoSession mStaticMockSession = null;
private Bundle mAttribution = new Bundle();
+ private ArgumentCaptor<TetheringManager.TetheringEventCallback> mTetheringEventCallbackCaptor =
+ ArgumentCaptor.forClass(TetheringManager.TetheringEventCallback.class);
+ private TetheringManager.TetheringEventCallback mTetheringEventCallback;
@Mock Bundle mBundle;
@Mock Context mContext;
@@ -258,6 +263,7 @@
@Mock AsyncChannel mAsyncChannel;
CoexManager.CoexListener mCoexListener;
@Mock DeviceConfigFacade mDeviceConfigFacade;
+ @Mock TetheringManager mTetheringManager;
private void generatorTestData() {
mTestWifiP2pGroup = new WifiP2pGroup();
@@ -345,20 +351,11 @@
/**
* Simulate tethering flow is completed
*/
- private void simulateTetherReady() {
- ArrayList<String> availableList = new ArrayList<>();
- ArrayList<String> localOnlyList = new ArrayList<>();
- localOnlyList.add(IFACE_NAME_P2P);
- ArrayList<String> tetherList = new ArrayList<>();
- ArrayList<String> erroredList = new ArrayList<>();
-
- Intent intent = new Intent(TetheringManager.ACTION_TETHER_STATE_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putStringArrayListExtra(TetheringManager.EXTRA_AVAILABLE_TETHER, availableList);
- intent.putStringArrayListExtra(TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY, localOnlyList);
- intent.putStringArrayListExtra(TetheringManager.EXTRA_ACTIVE_TETHER, tetherList);
- intent.putStringArrayListExtra(TetheringManager.EXTRA_ERRORED_TETHER, erroredList);
- mTetherStateReceiver.onReceive(mContext, intent);
+ private void simulateTetherReady() throws Exception {
+ mTetheringEventCallback.onLocalOnlyInterfacesChanged(Collections.unmodifiableSet(
+ (new ArraySet(new TetheringInterface[]{
+ new TetheringInterface(TetheringManager.TETHERING_WIFI_P2P,
+ IFACE_NAME_P2P)}))));
mLooper.dispatchAll();
}
@@ -995,6 +992,9 @@
simulateLocationModeChange(true);
checkIsP2pInitWhenClientConnected(true, clientBinder,
new WorkSource(clientBinder.getCallingUid(), TEST_PACKAGE_NAME));
+ verify(mTetheringManager).registerTetheringEventCallback(any(Executor.class),
+ mTetheringEventCallbackCaptor.capture());
+ mTetheringEventCallback = mTetheringEventCallbackCaptor.getValue();
verify(mContext).sendBroadcastWithMultiplePermissions(
argThat(new WifiP2pServiceImplTest
.P2pConnectionChangedIntentMatcherForNetworkState(IDLE)), any());
@@ -1307,25 +1307,24 @@
when(mCoexManager.getCoexUnsafeChannels()).thenReturn(Collections.emptyList());
when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
when(mDeviceConfigFacade.isP2pFailureBugreportEnabled()).thenReturn(false);
+ when(mContext.getSystemService(TetheringManager.class)).thenReturn(mTetheringManager);
mWifiP2pServiceImpl = new WifiP2pServiceImpl(mContext, mWifiInjector);
if (supported) {
// register these event:
- // * WifiManager.WIFI_STATE_CHANGED_ACTION
- // * LocationManager.MODE_CHANGED_ACTION
- // * TetheringManager.ACTION_TETHER_STATE_CHANGED
- // * UserManager.ACTION_USER_RESTRICTIONS_CHANGED
+ // * WifiManager.WIFI_STATE_CHANGED_ACTION -- always
+ // * LocationManager.MODE_CHANGED_ACTION -- always
+ // * UserManager.ACTION_USER_RESTRICTIONS_CHANGED -- >= T
if (SdkLevel.isAtLeastT()) {
- verify(mContext, times(4)).registerReceiver(mBcastRxCaptor.capture(),
- any(IntentFilter.class));
- mUserRestrictionReceiver = mBcastRxCaptor.getAllValues().get(3);
- } else {
verify(mContext, times(3)).registerReceiver(mBcastRxCaptor.capture(),
any(IntentFilter.class));
+ mUserRestrictionReceiver = mBcastRxCaptor.getAllValues().get(2);
+ } else {
+ verify(mContext, times(2)).registerReceiver(mBcastRxCaptor.capture(),
+ any(IntentFilter.class));
}
mWifiStateChangedReceiver = mBcastRxCaptor.getAllValues().get(0);
mLocationModeReceiver = mBcastRxCaptor.getAllValues().get(1);
- mTetherStateReceiver = mBcastRxCaptor.getAllValues().get(2);
}
verify(mWifiPermissionsUtil, never()).isLocationModeEnabled();
@@ -2367,7 +2366,6 @@
reset(mClientHandler);
sendGroupStartedMsg(mTestWifiP2pGroup);
- simulateTetherReady();
sendRequestGroupInfoMsg(mClientMessenger);
verify(mClientHandler).sendMessage(mMessageCaptor.capture());
assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
@@ -7049,4 +7047,29 @@
assertEquals(WifiP2pManager.RESPONSE_CONNECTION_INFO, mMessageCaptor.getValue().what);
assertFalse(((WifiP2pInfo) mMessageCaptor.getValue().obj).groupFormed);
}
+
+ @Test
+ public void testGroupStartedTetheringDirectCallback() throws Exception {
+ setTargetSdkGreaterThanT();
+ forceP2pEnabled(mClient1);
+ verify(mTetheringManager).registerTetheringEventCallback(any(), any());
+
+ //create/start/remove group
+ when(mWifiNative.p2pGroupAdd(any(), eq(false))).thenReturn(true);
+ sendCreateGroupMsgWithConfigValidAsGroup(mClientMessenger);
+ assertTrue(mClientHandler.hasMessages(WifiP2pManager.CREATE_GROUP_SUCCEEDED));
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkName("DIRECT-test");
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+ verify(mWifiP2pMetrics).startGroupEvent(group);
+ sendGroupRemovedMsg();
+
+ //force to back disabled state
+ mockEnterDisabledState();
+ verify(mTetheringManager).unregisterTetheringEventCallback(any());
+ }
}