Merge "Keep the native mdns daemon alive for pre-S application"
This commit is contained in:
@@ -23,6 +23,9 @@ import static com.android.internal.util.Preconditions.checkStringNotEmpty;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.annotation.SystemService;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
@@ -125,6 +128,24 @@ public final class NsdManager {
|
||||
private static final String TAG = NsdManager.class.getSimpleName();
|
||||
private static final boolean DBG = false;
|
||||
|
||||
/**
|
||||
* When enabled, apps targeting < Android 12 are considered legacy for
|
||||
* the NSD native daemon.
|
||||
* The platform will only keep the daemon running as long as there are
|
||||
* any legacy apps connected.
|
||||
*
|
||||
* After Android 12, directly communicate with native daemon might not
|
||||
* work since the native damon won't always stay alive.
|
||||
* Use the NSD APIs from NsdManager as the replacement is recommended.
|
||||
* An another alternative could be bundling your own mdns solutions instead of
|
||||
* depending on the system mdns native daemon.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S)
|
||||
public static final long RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS = 191844585L;
|
||||
|
||||
/**
|
||||
* Broadcast intent action to indicate whether network service discovery is
|
||||
* enabled or disabled. An extra {@link #EXTRA_NSD_STATE} provides the state
|
||||
@@ -202,6 +223,9 @@ public final class NsdManager {
|
||||
/** @hide */
|
||||
public static final int DAEMON_CLEANUP = BASE + 21;
|
||||
|
||||
/** @hide */
|
||||
public static final int DAEMON_STARTUP = BASE + 22;
|
||||
|
||||
/** @hide */
|
||||
public static final int ENABLE = BASE + 24;
|
||||
/** @hide */
|
||||
@@ -232,6 +256,8 @@ public final class NsdManager {
|
||||
EVENT_NAMES.put(RESOLVE_SERVICE, "RESOLVE_SERVICE");
|
||||
EVENT_NAMES.put(RESOLVE_SERVICE_FAILED, "RESOLVE_SERVICE_FAILED");
|
||||
EVENT_NAMES.put(RESOLVE_SERVICE_SUCCEEDED, "RESOLVE_SERVICE_SUCCEEDED");
|
||||
EVENT_NAMES.put(DAEMON_CLEANUP, "DAEMON_CLEANUP");
|
||||
EVENT_NAMES.put(DAEMON_STARTUP, "DAEMON_STARTUP");
|
||||
EVENT_NAMES.put(ENABLE, "ENABLE");
|
||||
EVENT_NAMES.put(DISABLE, "DISABLE");
|
||||
EVENT_NAMES.put(NATIVE_DAEMON_EVENT, "NATIVE_DAEMON_EVENT");
|
||||
@@ -494,6 +520,12 @@ public final class NsdManager {
|
||||
} catch (InterruptedException e) {
|
||||
fatal("Interrupted wait at init");
|
||||
}
|
||||
if (CompatChanges.isChangeEnabled(RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS)) {
|
||||
return;
|
||||
}
|
||||
// Only proactively start the daemon if the target SDK < S, otherwise the internal service
|
||||
// would automatically start/stop the native daemon as needed.
|
||||
mAsyncChannel.sendMessage(DAEMON_STARTUP);
|
||||
}
|
||||
|
||||
private static void fatal(String msg) {
|
||||
|
||||
@@ -82,6 +82,8 @@ public class NsdService extends INsdManager.Stub {
|
||||
|
||||
private static final int INVALID_ID = 0;
|
||||
private int mUniqueId = 1;
|
||||
// The count of the connected legacy clients.
|
||||
private int mLegacyClientCount = 0;
|
||||
|
||||
private class NsdStateMachine extends StateMachine {
|
||||
|
||||
@@ -107,7 +109,9 @@ public class NsdService extends INsdManager.Stub {
|
||||
sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs);
|
||||
}
|
||||
private void maybeScheduleStop() {
|
||||
if (!isAnyRequestActive()) {
|
||||
// The native daemon should stay alive and can't be cleanup
|
||||
// if any legacy client connected.
|
||||
if (!isAnyRequestActive() && mLegacyClientCount == 0) {
|
||||
scheduleStop();
|
||||
}
|
||||
}
|
||||
@@ -175,11 +179,11 @@ public class NsdService extends INsdManager.Stub {
|
||||
if (cInfo != null) {
|
||||
cInfo.expungeAllRequests();
|
||||
mClients.remove(msg.replyTo);
|
||||
if (cInfo.isLegacy()) {
|
||||
mLegacyClientCount -= 1;
|
||||
}
|
||||
//Last client
|
||||
if (mClients.size() == 0) {
|
||||
scheduleStop();
|
||||
}
|
||||
maybeScheduleStop();
|
||||
break;
|
||||
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
|
||||
AsyncChannel ac = new AsyncChannel();
|
||||
@@ -208,6 +212,17 @@ public class NsdService extends INsdManager.Stub {
|
||||
case NsdManager.DAEMON_CLEANUP:
|
||||
mDaemon.maybeStop();
|
||||
break;
|
||||
// This event should be only sent by the legacy (target SDK < S) clients.
|
||||
// Mark the sending client as legacy.
|
||||
case NsdManager.DAEMON_STARTUP:
|
||||
cInfo = mClients.get(msg.replyTo);
|
||||
if (cInfo != null) {
|
||||
cancelStop();
|
||||
cInfo.setLegacy();
|
||||
mLegacyClientCount += 1;
|
||||
maybeStartDaemon();
|
||||
}
|
||||
break;
|
||||
case NsdManager.NATIVE_DAEMON_EVENT:
|
||||
default:
|
||||
Slog.e(TAG, "Unhandled " + msg);
|
||||
@@ -863,6 +878,9 @@ public class NsdService extends INsdManager.Stub {
|
||||
/* A map from client id to the type of the request we had received */
|
||||
private final SparseIntArray mClientRequests = new SparseIntArray();
|
||||
|
||||
// The target SDK of this client < Build.VERSION_CODES.S
|
||||
private boolean mIsLegacy = false;
|
||||
|
||||
private ClientInfo(AsyncChannel c, Messenger m) {
|
||||
mChannel = c;
|
||||
mMessenger = m;
|
||||
@@ -875,6 +893,7 @@ public class NsdService extends INsdManager.Stub {
|
||||
sb.append("mChannel ").append(mChannel).append("\n");
|
||||
sb.append("mMessenger ").append(mMessenger).append("\n");
|
||||
sb.append("mResolvedService ").append(mResolvedService).append("\n");
|
||||
sb.append("mIsLegacy ").append(mIsLegacy).append("\n");
|
||||
for(int i = 0; i< mClientIds.size(); i++) {
|
||||
int clientID = mClientIds.keyAt(i);
|
||||
sb.append("clientId ").append(clientID).
|
||||
@@ -884,6 +903,14 @@ public class NsdService extends INsdManager.Stub {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean isLegacy() {
|
||||
return mIsLegacy;
|
||||
}
|
||||
|
||||
private void setLegacy() {
|
||||
mIsLegacy = true;
|
||||
}
|
||||
|
||||
// Remove any pending requests from the global map when we get rid of a client,
|
||||
// and send cancellations to the daemon.
|
||||
private void expungeAllRequests() {
|
||||
|
||||
Reference in New Issue
Block a user