diff options
author | Roshan Pius <rpius@google.com> | 2018-03-01 10:40:39 -0800 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2018-03-01 14:19:16 -0800 |
commit | 6607224c87aa75ad0f8a12b599fff837f82d0095 (patch) | |
tree | 3c62e71736919ce38a88b14abc10997c3f85d90c | |
parent | 554a9c0136e1bb7612ced93fb1ec60bc55484dcb (diff) |
WifiP2pNative: Handle stale interface destroyed invocation
When the P2P interface is destroyed by the WifiP2pService, we don't need
to process the associated interface destroyed invocation. This listener will
otherwise trigger a second cleanup. We need to handle the destroyed
callback only if the HalDeviceManager removed the interface on it's own (
i.e if AP or Aware interface was brought up & we need to destroy P2P interface).
Also, added some extra logs to help in debugging issues in this area.
The problem with links camera OTA update:
a) links camera closes the P2P channel -> WifiP2pManager.close()
b) This triggers WifiP2pNative.teardownInterface()
c) links camera then reopens the P2P channel ->
WifiP2pManager.initialize()
d) This triggers WifiP2pNative.setupInterface()
e) The |InterfaceDestroyedListener.onDestroyed| callback for the teardown
initiated in (b) comes in at this stage and triggers a cleanup of the iface
setup in (d).
f) The |InterfaceAvailableForRequestListener.onAvailabilityChanged|
callback then sees IWifiP2pIface == null and declares that the interface
is not available.
With this fix, step (e) will now become a no-op.
Bug: 73787760
Test: Ran CtsVerifier tests
Test: Verified that links camera's P2P connection still works.
Test: Need to verify if this fixes the OTA issue seen by links camera
(Not able to repro locally)
Change-Id: I3db40baa898234e9bc4297e57c18f839c52e9f4e
-rw-r--r-- | service/java/com/android/server/wifi/p2p/WifiP2pNative.java | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java index f558b337e..07ee11e3b 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java @@ -40,6 +40,7 @@ public class WifiP2pNative { private final HalDeviceManager mHalDeviceManager; private IWifiP2pIface mIWifiP2pIface; private InterfaceAvailableListenerInternal mInterfaceAvailableListener; + private InterfaceDestroyedListenerInternal mInterfaceDestroyedListener; // Internal callback registered to HalDeviceManager. private class InterfaceAvailableListenerInternal implements @@ -53,6 +54,7 @@ public class WifiP2pNative { @Override public void onAvailabilityChanged(boolean isAvailable) { + Log.d(TAG, "P2P InterfaceAvailableListener " + isAvailable); // We need another level of abstraction here. When a P2P interface is created, // we should mask the availability change callback from WifiP2pService. // This is because when the P2P interface is created, we'll get a callback @@ -67,6 +69,36 @@ public class WifiP2pNative { } } + // Internal callback registered to HalDeviceManager. + private class InterfaceDestroyedListenerInternal implements + HalDeviceManager.InterfaceDestroyedListener { + private final HalDeviceManager.InterfaceDestroyedListener mExternalListener; + private boolean mValid; + + InterfaceDestroyedListenerInternal( + HalDeviceManager.InterfaceDestroyedListener externalListener) { + mExternalListener = externalListener; + mValid = true; + } + + public void teardownAndInvalidate(@NonNull String ifaceName) { + mSupplicantP2pIfaceHal.teardownIface(ifaceName); + mIWifiP2pIface = 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; + } + teardownAndInvalidate(ifaceName); + mExternalListener.onDestroyed(ifaceName); + } + } + public WifiP2pNative(SupplicantP2pIfaceHal p2pIfaceHal, HalDeviceManager halDeviceManager) { mSupplicantP2pIfaceHal = p2pIfaceHal; mHalDeviceManager = halDeviceManager; @@ -145,15 +177,10 @@ public class WifiP2pNative { public String setupInterface( @NonNull HalDeviceManager.InterfaceDestroyedListener destroyedListener, Handler handler) { + Log.d(TAG, "Setup P2P interface"); if (mIWifiP2pIface == null) { - HalDeviceManager.InterfaceDestroyedListener internalDestroyedListener = - (@NonNull String ifaceName) -> { - Log.i(TAG, "IWifiP2pIface destroyedListener"); - mSupplicantP2pIfaceHal.teardownIface(ifaceName); - mIWifiP2pIface = null; - destroyedListener.onDestroyed(ifaceName); - }; - mIWifiP2pIface = mHalDeviceManager.createP2pIface(internalDestroyedListener, handler); + mInterfaceDestroyedListener = new InterfaceDestroyedListenerInternal(destroyedListener); + mIWifiP2pIface = mHalDeviceManager.createP2pIface(mInterfaceDestroyedListener, handler); if (mIWifiP2pIface == null) { Log.e(TAG, "Failed to create P2p iface in HalDeviceManager"); return null; @@ -168,6 +195,7 @@ public class WifiP2pNative { teardownInterface(); return null; } + Log.i(TAG, "P2P interface setup completed"); } return HalDeviceManager.getName(mIWifiP2pIface); } @@ -176,9 +204,12 @@ public class WifiP2pNative { * Teardown P2p interface. */ public void teardownInterface() { + Log.d(TAG, "Teardown P2P interface"); if (mIWifiP2pIface != null) { + String ifaceName = HalDeviceManager.getName(mIWifiP2pIface); mHalDeviceManager.removeIface(mIWifiP2pIface); - mIWifiP2pIface = null; + mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName); + Log.i(TAG, "P2P interface teardown completed"); } } |