summaryrefslogtreecommitdiff
path: root/framework-t/src
diff options
context:
space:
mode:
Diffstat (limited to 'framework-t/src')
-rw-r--r--framework-t/src/android/net/nsd/NsdManager.java61
1 files changed, 39 insertions, 22 deletions
diff --git a/framework-t/src/android/net/nsd/NsdManager.java b/framework-t/src/android/net/nsd/NsdManager.java
index 33b44c8210..f19bf4a6fb 100644
--- a/framework-t/src/android/net/nsd/NsdManager.java
+++ b/framework-t/src/android/net/nsd/NsdManager.java
@@ -312,9 +312,12 @@ public final class NsdManager {
@Override
public void onAvailable(@NonNull Network network) {
final DelegatingDiscoveryListener wrappedListener = new DelegatingDiscoveryListener(
- network, mBaseListener);
+ network, mBaseListener, mBaseExecutor);
mPerNetworkListeners.put(network, wrappedListener);
- discoverServices(mServiceType, mProtocolType, network, mBaseExecutor,
+ // Run discovery callbacks inline on the service handler thread, which is the
+ // same thread used by this NetworkCallback, but DelegatingDiscoveryListener will
+ // use the base executor to run the wrapped callbacks.
+ discoverServices(mServiceType, mProtocolType, network, Runnable::run,
wrappedListener);
}
@@ -334,7 +337,8 @@ public final class NsdManager {
public void start(@NonNull NetworkRequest request) {
final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
cm.registerNetworkCallback(request, mNetworkCb, mHandler);
- mHandler.post(() -> mBaseListener.onDiscoveryStarted(mServiceType));
+ mHandler.post(() -> mBaseExecutor.execute(() ->
+ mBaseListener.onDiscoveryStarted(mServiceType)));
}
/**
@@ -351,7 +355,7 @@ public final class NsdManager {
final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
cm.unregisterNetworkCallback(mNetworkCb);
if (mPerNetworkListeners.size() == 0) {
- mBaseListener.onDiscoveryStopped(mServiceType);
+ mBaseExecutor.execute(() -> mBaseListener.onDiscoveryStopped(mServiceType));
return;
}
for (int i = 0; i < mPerNetworkListeners.size(); i++) {
@@ -399,14 +403,23 @@ public final class NsdManager {
}
}
+ /**
+ * A listener wrapping calls to an app-provided listener, while keeping track of found
+ * services, so they can all be reported lost when the underlying network is lost.
+ *
+ * This should be registered to run on the service handler.
+ */
private class DelegatingDiscoveryListener implements DiscoveryListener {
private final Network mNetwork;
private final DiscoveryListener mWrapped;
+ private final Executor mWrappedExecutor;
private final ArraySet<TrackedNsdInfo> mFoundInfo = new ArraySet<>();
- private DelegatingDiscoveryListener(Network network, DiscoveryListener listener) {
+ private DelegatingDiscoveryListener(Network network, DiscoveryListener listener,
+ Executor executor) {
mNetwork = network;
mWrapped = listener;
+ mWrappedExecutor = executor;
}
void notifyAllServicesLost() {
@@ -415,7 +428,7 @@ public final class NsdManager {
final NsdServiceInfo serviceInfo = new NsdServiceInfo(
trackedInfo.mServiceName, trackedInfo.mServiceType);
serviceInfo.setNetwork(mNetwork);
- mWrapped.onServiceLost(serviceInfo);
+ mWrappedExecutor.execute(() -> mWrapped.onServiceLost(serviceInfo));
}
}
@@ -444,7 +457,7 @@ public final class NsdManager {
// Do not report onStopDiscoveryFailed when some underlying listeners failed:
// this does not mean that all listeners did, and onStopDiscoveryFailed is not
// actionable anyway. Just report that discovery stopped.
- mWrapped.onDiscoveryStopped(serviceType);
+ mWrappedExecutor.execute(() -> mWrapped.onDiscoveryStopped(serviceType));
}
}
@@ -452,20 +465,20 @@ public final class NsdManager {
public void onDiscoveryStopped(String serviceType) {
mPerNetworkListeners.remove(mNetwork);
if (mStopRequested && mPerNetworkListeners.size() == 0) {
- mWrapped.onDiscoveryStopped(serviceType);
+ mWrappedExecutor.execute(() -> mWrapped.onDiscoveryStopped(serviceType));
}
}
@Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
mFoundInfo.add(new TrackedNsdInfo(serviceInfo));
- mWrapped.onServiceFound(serviceInfo);
+ mWrappedExecutor.execute(() -> mWrapped.onServiceFound(serviceInfo));
}
@Override
public void onServiceLost(NsdServiceInfo serviceInfo) {
mFoundInfo.remove(new TrackedNsdInfo(serviceInfo));
- mWrapped.onServiceLost(serviceInfo);
+ mWrappedExecutor.execute(() -> mWrapped.onServiceLost(serviceInfo));
}
}
}
@@ -648,8 +661,12 @@ public final class NsdManager {
@Override
public void handleMessage(Message message) {
+ // Do not use message in the executor lambdas, as it will be recycled once this method
+ // returns. Keep references to its content instead.
final int what = message.what;
+ final int errorCode = message.arg1;
final int key = message.arg2;
+ final Object obj = message.obj;
final Object listener;
final NsdServiceInfo ns;
final Executor executor;
@@ -659,7 +676,7 @@ public final class NsdManager {
executor = mExecutorMap.get(key);
}
if (listener == null) {
- Log.d(TAG, "Stale key " + message.arg2);
+ Log.d(TAG, "Stale key " + key);
return;
}
if (DBG) {
@@ -667,28 +684,28 @@ public final class NsdManager {
}
switch (what) {
case DISCOVER_SERVICES_STARTED:
- final String s = getNsdServiceInfoType((NsdServiceInfo) message.obj);
+ final String s = getNsdServiceInfoType((NsdServiceInfo) obj);
executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStarted(s));
break;
case DISCOVER_SERVICES_FAILED:
removeListener(key);
executor.execute(() -> ((DiscoveryListener) listener).onStartDiscoveryFailed(
- getNsdServiceInfoType(ns), message.arg1));
+ getNsdServiceInfoType(ns), errorCode));
break;
case SERVICE_FOUND:
executor.execute(() -> ((DiscoveryListener) listener).onServiceFound(
- (NsdServiceInfo) message.obj));
+ (NsdServiceInfo) obj));
break;
case SERVICE_LOST:
executor.execute(() -> ((DiscoveryListener) listener).onServiceLost(
- (NsdServiceInfo) message.obj));
+ (NsdServiceInfo) obj));
break;
case STOP_DISCOVERY_FAILED:
// TODO: failure to stop discovery should be internal and retried internally, as
// the effect for the client is indistinguishable from STOP_DISCOVERY_SUCCEEDED
removeListener(key);
executor.execute(() -> ((DiscoveryListener) listener).onStopDiscoveryFailed(
- getNsdServiceInfoType(ns), message.arg1));
+ getNsdServiceInfoType(ns), errorCode));
break;
case STOP_DISCOVERY_SUCCEEDED:
removeListener(key);
@@ -698,33 +715,33 @@ public final class NsdManager {
case REGISTER_SERVICE_FAILED:
removeListener(key);
executor.execute(() -> ((RegistrationListener) listener).onRegistrationFailed(
- ns, message.arg1));
+ ns, errorCode));
break;
case REGISTER_SERVICE_SUCCEEDED:
executor.execute(() -> ((RegistrationListener) listener).onServiceRegistered(
- (NsdServiceInfo) message.obj));
+ (NsdServiceInfo) obj));
break;
case UNREGISTER_SERVICE_FAILED:
removeListener(key);
executor.execute(() -> ((RegistrationListener) listener).onUnregistrationFailed(
- ns, message.arg1));
+ ns, errorCode));
break;
case UNREGISTER_SERVICE_SUCCEEDED:
// TODO: do not unregister listener until service is unregistered, or provide
// alternative way for unregistering ?
- removeListener(message.arg2);
+ removeListener(key);
executor.execute(() -> ((RegistrationListener) listener).onServiceUnregistered(
ns));
break;
case RESOLVE_SERVICE_FAILED:
removeListener(key);
executor.execute(() -> ((ResolveListener) listener).onResolveFailed(
- ns, message.arg1));
+ ns, errorCode));
break;
case RESOLVE_SERVICE_SUCCEEDED:
removeListener(key);
executor.execute(() -> ((ResolveListener) listener).onServiceResolved(
- (NsdServiceInfo) message.obj));
+ (NsdServiceInfo) obj));
break;
default:
Log.d(TAG, "Ignored " + message);