diff options
Diffstat (limited to 'thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java')
-rw-r--r-- | thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java | 321 |
1 files changed, 212 insertions, 109 deletions
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java index 60c97bfe35..cd59e4e94a 100644 --- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java +++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java @@ -36,7 +36,6 @@ import static android.net.thread.ThreadNetworkException.ERROR_RESOURCE_EXHAUSTED import static android.net.thread.ThreadNetworkException.ERROR_RESPONSE_BAD_FORMAT; import static android.net.thread.ThreadNetworkException.ERROR_TIMEOUT; import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_CHANNEL; -import static android.net.thread.ThreadNetworkException.ErrorCode; import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_PRIVILEGED; import static com.android.server.thread.openthread.IOtDaemon.ErrorCode.OT_ERROR_ABORT; @@ -53,14 +52,17 @@ import static com.android.server.thread.openthread.IOtDaemon.TUN_IF_NAME; import android.Manifest.permission; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.TargetApi; import android.content.Context; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.LocalNetworkConfig; -import android.net.MulticastRoutingConfig; import android.net.LocalNetworkInfo; +import android.net.MulticastRoutingConfig; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkAgentConfig; @@ -69,6 +71,7 @@ import android.net.NetworkProvider; import android.net.NetworkRequest; import android.net.NetworkScore; import android.net.RouteInfo; +import android.net.TestNetworkSpecifier; import android.net.thread.ActiveOperationalDataset; import android.net.thread.ActiveOperationalDataset.SecurityPolicy; import android.net.thread.IActiveOperationalDatasetReceiver; @@ -80,6 +83,8 @@ import android.net.thread.OperationalDatasetTimestamp; import android.net.thread.PendingOperationalDataset; import android.net.thread.ThreadNetworkController; import android.net.thread.ThreadNetworkController.DeviceRole; +import android.net.thread.ThreadNetworkException.ErrorCode; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -91,12 +96,12 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.ServiceManagerWrapper; +import com.android.server.thread.openthread.BorderRouterConfigurationParcel; import com.android.server.thread.openthread.IOtDaemon; import com.android.server.thread.openthread.IOtDaemonCallback; import com.android.server.thread.openthread.IOtStatusReceiver; import com.android.server.thread.openthread.Ipv6AddressInfo; import com.android.server.thread.openthread.OtDaemonState; -import com.android.server.thread.openthread.BorderRouterConfigurationParcel; import java.io.IOException; import java.net.Inet6Address; @@ -115,10 +120,11 @@ import java.util.function.Supplier; * * <p>Threading model: This class is not Thread-safe and should only be accessed from the * ThreadNetworkService class. Additional attention should be paid to handle the threading code - * correctly: 1. All member fields other than `mHandler` and `mContext` MUST be accessed from - * `mHandlerThread` 2. In the @Override methods, the actual work MUST be dispatched to the + * correctly: 1. All member fields other than `mHandler` and `mContext` MUST be accessed from the + * thread of `mHandler` 2. In the @Override methods, the actual work MUST be dispatched to the * HandlerThread except for arguments or permissions checking */ +@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) final class ThreadNetworkControllerService extends IThreadNetworkController.Stub { private static final String TAG = "ThreadNetworkService"; @@ -127,57 +133,52 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub private final Context mContext; private final Handler mHandler; - // Below member fields can only be accessed from the handler thread (`mHandlerThread`). In + // Below member fields can only be accessed from the handler thread (`mHandler`). In // particular, the constructor does not run on the handler thread, so it must not touch any of // the non-final fields, nor must it mutate any of the non-final fields inside these objects. - private final HandlerThread mHandlerThread; private final NetworkProvider mNetworkProvider; private final Supplier<IOtDaemon> mOtDaemonSupplier; private final ConnectivityManager mConnectivityManager; private final TunInterfaceController mTunIfController; + private final InfraInterfaceController mInfraIfController; private final LinkProperties mLinkProperties = new LinkProperties(); private final OtDaemonCallbackProxy mOtDaemonCallbackProxy = new OtDaemonCallbackProxy(); // TODO(b/308310823): read supported channel from Thread dameon private final int mSupportedChannelMask = 0x07FFF800; // from channel 11 to 26 - private IOtDaemon mOtDaemon; - private NetworkAgent mNetworkAgent; + @Nullable private IOtDaemon mOtDaemon; + @Nullable private NetworkAgent mNetworkAgent; + @Nullable private NetworkAgent mTestNetworkAgent; + private MulticastRoutingConfig mUpstreamMulticastRoutingConfig = CONFIG_FORWARD_NONE; private MulticastRoutingConfig mDownstreamMulticastRoutingConfig = CONFIG_FORWARD_NONE; private Network mUpstreamNetwork; - private final NetworkRequest mUpstreamNetworkRequest; + private NetworkRequest mUpstreamNetworkRequest; + private UpstreamNetworkCallback mUpstreamNetworkCallback; + private TestNetworkSpecifier mUpstreamTestNetworkSpecifier; private final HashMap<Network, String> mNetworkToInterface; - private final LocalNetworkConfig mLocalNetworkConfig; private BorderRouterConfigurationParcel mBorderRouterConfig; @VisibleForTesting ThreadNetworkControllerService( Context context, - HandlerThread handlerThread, + Handler handler, NetworkProvider networkProvider, Supplier<IOtDaemon> otDaemonSupplier, ConnectivityManager connectivityManager, - TunInterfaceController tunIfController) { + TunInterfaceController tunIfController, + InfraInterfaceController infraIfController) { mContext = context; - mHandlerThread = handlerThread; - mHandler = new Handler(handlerThread.getLooper()); + mHandler = handler; mNetworkProvider = networkProvider; mOtDaemonSupplier = otDaemonSupplier; mConnectivityManager = connectivityManager; mTunIfController = tunIfController; - mUpstreamNetworkRequest = - new NetworkRequest.Builder() - .clearCapabilities() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) - .build(); - mLocalNetworkConfig = - new LocalNetworkConfig.Builder() - .setUpstreamSelector(mUpstreamNetworkRequest) - .build(); + mInfraIfController = infraIfController; + mUpstreamNetworkRequest = newUpstreamNetworkRequest(); mNetworkToInterface = new HashMap<Network, String>(); mBorderRouterConfig = new BorderRouterConfigurationParcel(); } @@ -190,19 +191,12 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub return new ThreadNetworkControllerService( context, - handlerThread, + new Handler(handlerThread.getLooper()), networkProvider, () -> IOtDaemon.Stub.asInterface(ServiceManagerWrapper.waitForService("ot_daemon")), context.getSystemService(ConnectivityManager.class), - new TunInterfaceController(TUN_IF_NAME)); - } - - private static NetworkCapabilities newNetworkCapabilities() { - return new NetworkCapabilities.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_THREAD) - .addCapability(NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK) - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) - .build(); + new TunInterfaceController(TUN_IF_NAME), + new InfraInterfaceController()); } private static Inet6Address bytesToInet6Address(byte[] addressBytes) { @@ -237,6 +231,60 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub LinkAddress.LIFETIME_PERMANENT /* expirationTime */); } + private NetworkRequest newUpstreamNetworkRequest() { + NetworkRequest.Builder builder = new NetworkRequest.Builder().clearCapabilities(); + + if (mUpstreamTestNetworkSpecifier != null) { + return builder.addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(mUpstreamTestNetworkSpecifier) + .build(); + } + return builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + } + + private LocalNetworkConfig newLocalNetworkConfig() { + return new LocalNetworkConfig.Builder() + .setUpstreamMulticastRoutingConfig(mUpstreamMulticastRoutingConfig) + .setDownstreamMulticastRoutingConfig(mDownstreamMulticastRoutingConfig) + .setUpstreamSelector(mUpstreamNetworkRequest) + .build(); + } + + @Override + public void setTestNetworkAsUpstream( + @Nullable String testNetworkInterfaceName, @NonNull IOperationReceiver receiver) { + enforceAllPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); + + Log.i(TAG, "setTestNetworkAsUpstream: " + testNetworkInterfaceName); + mHandler.post(() -> setTestNetworkAsUpstreamInternal(testNetworkInterfaceName, receiver)); + } + + private void setTestNetworkAsUpstreamInternal( + @Nullable String testNetworkInterfaceName, @NonNull IOperationReceiver receiver) { + checkOnHandlerThread(); + + TestNetworkSpecifier testNetworkSpecifier = null; + if (testNetworkInterfaceName != null) { + testNetworkSpecifier = new TestNetworkSpecifier(testNetworkInterfaceName); + } + + if (!Objects.equals(mUpstreamTestNetworkSpecifier, testNetworkSpecifier)) { + cancelRequestUpstreamNetwork(); + mUpstreamTestNetworkSpecifier = testNetworkSpecifier; + mUpstreamNetworkRequest = newUpstreamNetworkRequest(); + requestUpstreamNetwork(); + sendLocalNetworkConfig(); + } + try { + receiver.onSuccess(); + } catch (RemoteException ignored) { + // do nothing if the client is dead + } + } + private void initializeOtDaemon() { try { getOtDaemon(); @@ -246,6 +294,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub } private IOtDaemon getOtDaemon() throws RemoteException { + checkOnHandlerThread(); + if (mOtDaemon != null) { return mOtDaemon; } @@ -254,9 +304,9 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub if (otDaemon == null) { throw new RemoteException("Internal error: failed to start OT daemon"); } - otDaemon.asBinder().linkToDeath(() -> mHandler.post(this::onOtDaemonDied), 0); otDaemon.initialize(mTunIfController.getTunFd()); otDaemon.registerStateCallback(mOtDaemonCallbackProxy, -1); + otDaemon.asBinder().linkToDeath(() -> mHandler.post(this::onOtDaemonDied), 0); mOtDaemon = otDaemon; return mOtDaemon; } @@ -283,51 +333,70 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub mLinkProperties.setMtu(TunInterfaceController.MTU); mConnectivityManager.registerNetworkProvider(mNetworkProvider); requestUpstreamNetwork(); + requestThreadNetwork(); initializeOtDaemon(); }); } private void requestUpstreamNetwork() { + if (mUpstreamNetworkCallback != null) { + throw new AssertionError("The upstream network request is already there."); + } + mUpstreamNetworkCallback = new UpstreamNetworkCallback(); mConnectivityManager.registerNetworkCallback( - mUpstreamNetworkRequest, - new ConnectivityManager.NetworkCallback() { - @Override - public void onAvailable(@NonNull Network network) { - Log.i(TAG, "onAvailable: " + network); - } + mUpstreamNetworkRequest, mUpstreamNetworkCallback, mHandler); + } - @Override - public void onLost(@NonNull Network network) { - Log.i(TAG, "onLost: " + network); - } + private void cancelRequestUpstreamNetwork() { + if (mUpstreamNetworkCallback == null) { + throw new AssertionError("The upstream network request null."); + } + mNetworkToInterface.clear(); + mConnectivityManager.unregisterNetworkCallback(mUpstreamNetworkCallback); + mUpstreamNetworkCallback = null; + } - @Override - public void onLinkPropertiesChanged( - @NonNull Network network, @NonNull LinkProperties linkProperties) { - Log.i( - TAG, - String.format( - "onLinkPropertiesChanged: {network: %s, interface: %s}", - network, linkProperties.getInterfaceName())); - mNetworkToInterface.put(network, linkProperties.getInterfaceName()); - if (network.equals(mUpstreamNetwork)) { - enableBorderRouting(mNetworkToInterface.get(mUpstreamNetwork)); - } - } - }, - mHandler); + private final class UpstreamNetworkCallback extends ConnectivityManager.NetworkCallback { + @Override + public void onAvailable(@NonNull Network network) { + checkOnHandlerThread(); + Log.i(TAG, "onAvailable: " + network); + } + + @Override + public void onLost(@NonNull Network network) { + checkOnHandlerThread(); + Log.i(TAG, "onLost: " + network); + } + + @Override + public void onLinkPropertiesChanged( + @NonNull Network network, @NonNull LinkProperties linkProperties) { + checkOnHandlerThread(); + Log.i( + TAG, + String.format( + "onLinkPropertiesChanged: {network: %s, interface: %s}", + network, linkProperties.getInterfaceName())); + mNetworkToInterface.put(network, linkProperties.getInterfaceName()); + if (network.equals(mUpstreamNetwork)) { + enableBorderRouting(mNetworkToInterface.get(mUpstreamNetwork)); + } + } } private final class ThreadNetworkCallback extends ConnectivityManager.NetworkCallback { @Override public void onAvailable(@NonNull Network network) { + checkOnHandlerThread(); Log.i(TAG, "onAvailable: Thread network Available"); } @Override public void onLocalNetworkInfoChanged( @NonNull Network network, @NonNull LocalNetworkInfo localNetworkInfo) { + checkOnHandlerThread(); Log.i(TAG, "onLocalNetworkInfoChanged: " + localNetworkInfo); if (localNetworkInfo.getUpstreamNetwork() == null) { mUpstreamNetwork = null; @@ -345,35 +414,54 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub private void requestThreadNetwork() { mConnectivityManager.registerNetworkCallback( new NetworkRequest.Builder() + // clearCapabilities() is needed to remove forbidden capabilities and UID + // requirement. .clearCapabilities() .addTransportType(NetworkCapabilities.TRANSPORT_THREAD) - .removeForbiddenCapability(NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK) .build(), new ThreadNetworkCallback(), mHandler); } - private void registerThreadNetwork() { - if (mNetworkAgent != null) { - return; + /** Injects a {@link NetworkAgent} for testing. */ + @VisibleForTesting + void setTestNetworkAgent(@Nullable NetworkAgent testNetworkAgent) { + mTestNetworkAgent = testNetworkAgent; + } + + private NetworkAgent newNetworkAgent() { + if (mTestNetworkAgent != null) { + return mTestNetworkAgent; } - NetworkCapabilities netCaps = newNetworkCapabilities(); - NetworkScore score = + + final NetworkCapabilities netCaps = + new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_THREAD) + .addCapability(NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK) + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) + .build(); + final NetworkScore score = new NetworkScore.Builder() .setKeepConnectedReason(NetworkScore.KEEP_CONNECTED_LOCAL_NETWORK) .build(); - requestThreadNetwork(); - mNetworkAgent = - new NetworkAgent( - mContext, - mHandlerThread.getLooper(), - TAG, - netCaps, - mLinkProperties, - mLocalNetworkConfig, - score, - new NetworkAgentConfig.Builder().build(), - mNetworkProvider) {}; + return new NetworkAgent( + mContext, + mHandler.getLooper(), + TAG, + netCaps, + mLinkProperties, + newLocalNetworkConfig(), + score, + new NetworkAgentConfig.Builder().build(), + mNetworkProvider) {}; + } + + private void registerThreadNetwork() { + if (mNetworkAgent != null) { + return; + } + + mNetworkAgent = newNetworkAgent(); mNetworkAgent.register(); mNetworkAgent.markConnected(); Log.i(TAG, "Registered Thread network"); @@ -524,29 +612,29 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub return -1; } - private void enforceAllCallingPermissionsGranted(String... permissions) { + private void enforceAllPermissionsGranted(String... permissions) { for (String permission : permissions) { - mContext.enforceCallingPermission( + mContext.enforceCallingOrSelfPermission( permission, "Permission " + permission + " is missing"); } } @Override public void registerStateCallback(IStateCallback stateCallback) throws RemoteException { - enforceAllCallingPermissionsGranted(permission.ACCESS_NETWORK_STATE); + enforceAllPermissionsGranted(permission.ACCESS_NETWORK_STATE); mHandler.post(() -> mOtDaemonCallbackProxy.registerStateCallback(stateCallback)); } @Override public void unregisterStateCallback(IStateCallback stateCallback) throws RemoteException { - enforceAllCallingPermissionsGranted(permission.ACCESS_NETWORK_STATE); + enforceAllPermissionsGranted(permission.ACCESS_NETWORK_STATE); mHandler.post(() -> mOtDaemonCallbackProxy.unregisterStateCallback(stateCallback)); } @Override public void registerOperationalDatasetCallback(IOperationalDatasetCallback callback) throws RemoteException { - enforceAllCallingPermissionsGranted( + enforceAllPermissionsGranted( permission.ACCESS_NETWORK_STATE, PERMISSION_THREAD_NETWORK_PRIVILEGED); mHandler.post(() -> mOtDaemonCallbackProxy.registerDatasetCallback(callback)); } @@ -554,13 +642,13 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub @Override public void unregisterOperationalDatasetCallback(IOperationalDatasetCallback callback) throws RemoteException { - enforceAllCallingPermissionsGranted( + enforceAllPermissionsGranted( permission.ACCESS_NETWORK_STATE, PERMISSION_THREAD_NETWORK_PRIVILEGED); mHandler.post(() -> mOtDaemonCallbackProxy.unregisterDatasetCallback(callback)); } private void checkOnHandlerThread() { - if (Looper.myLooper() != mHandlerThread.getLooper()) { + if (Looper.myLooper() != mHandler.getLooper()) { Log.wtf(TAG, "Must be on the handler thread!"); } } @@ -609,7 +697,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub @Override public void join( @NonNull ActiveOperationalDataset activeDataset, @NonNull IOperationReceiver receiver) { - enforceAllCallingPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); + enforceAllPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); OperationReceiverWrapper receiverWrapper = new OperationReceiverWrapper(receiver); mHandler.post(() -> joinInternal(activeDataset, receiverWrapper)); @@ -633,7 +721,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub public void scheduleMigration( @NonNull PendingOperationalDataset pendingDataset, @NonNull IOperationReceiver receiver) { - enforceAllCallingPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); + enforceAllPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); OperationReceiverWrapper receiverWrapper = new OperationReceiverWrapper(receiver); mHandler.post(() -> scheduleMigrationInternal(pendingDataset, receiverWrapper)); @@ -656,7 +744,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub @Override public void leave(@NonNull IOperationReceiver receiver) throws RemoteException { - enforceAllCallingPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); + enforceAllPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); mHandler.post(() -> leaveInternal(new OperationReceiverWrapper(receiver))); } @@ -672,6 +760,32 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub } } + /** + * Sets the country code. + * + * @param countryCode 2 characters string country code (as defined in ISO 3166) to set. + * @param receiver the receiver to receive result of this operation + */ + @RequiresPermission(PERMISSION_THREAD_NETWORK_PRIVILEGED) + public void setCountryCode(@NonNull String countryCode, @NonNull IOperationReceiver receiver) { + enforceAllPermissionsGranted(PERMISSION_THREAD_NETWORK_PRIVILEGED); + + OperationReceiverWrapper receiverWrapper = new OperationReceiverWrapper(receiver); + mHandler.post(() -> setCountryCodeInternal(countryCode, receiverWrapper)); + } + + private void setCountryCodeInternal( + String countryCode, @NonNull OperationReceiverWrapper receiver) { + checkOnHandlerThread(); + + try { + getOtDaemon().setCountryCode(countryCode, newOtStatusReceiver(receiver)); + } catch (RemoteException e) { + Log.e(TAG, "otDaemon.setCountryCode failed", e); + receiver.onError(ERROR_INTERNAL_ERROR, "Thread stack error"); + } + } + private void enableBorderRouting(String infraIfName) { if (mBorderRouterConfig.isBorderRoutingEnabled && infraIfName.equals(mBorderRouterConfig.infraInterfaceName)) { @@ -681,7 +795,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub try { mBorderRouterConfig.infraInterfaceName = infraIfName; mBorderRouterConfig.infraInterfaceIcmp6Socket = - InfraInterfaceController.createIcmp6Socket(infraIfName); + mInfraIfController.createIcmp6Socket(infraIfName); mBorderRouterConfig.isBorderRoutingEnabled = true; mOtDaemon.configureBorderRouter( @@ -754,20 +868,9 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub if (mNetworkAgent == null) { return; } - final LocalNetworkConfig.Builder configBuilder = new LocalNetworkConfig.Builder(); - LocalNetworkConfig localNetworkConfig = - configBuilder - .setUpstreamMulticastRoutingConfig(mUpstreamMulticastRoutingConfig) - .setDownstreamMulticastRoutingConfig(mDownstreamMulticastRoutingConfig) - .setUpstreamSelector(mUpstreamNetworkRequest) - .build(); + final LocalNetworkConfig localNetworkConfig = newLocalNetworkConfig(); mNetworkAgent.sendLocalNetworkConfig(localNetworkConfig); - Log.d( - TAG, - "Sent localNetworkConfig with upstreamConfig " - + mUpstreamMulticastRoutingConfig - + " downstreamConfig" - + mDownstreamMulticastRoutingConfig); + Log.d(TAG, "Sent localNetworkConfig: " + localNetworkConfig); } private void handleMulticastForwardingStateChanged(boolean isEnabled) { @@ -800,8 +903,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub MulticastRoutingConfig newDownstreamConfig; MulticastRoutingConfig.Builder builder; - if (mDownstreamMulticastRoutingConfig.getForwardingMode() != - MulticastRoutingConfig.FORWARD_SELECTED) { + if (mDownstreamMulticastRoutingConfig.getForwardingMode() + != MulticastRoutingConfig.FORWARD_SELECTED) { Log.e( TAG, "Ignore multicast listening address updates when downstream multicast " @@ -809,8 +912,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub // Don't update the address set if downstream multicast forwarding is disabled. return; } - if (isAdded == - mDownstreamMulticastRoutingConfig.getListeningAddresses().contains(address)) { + if (isAdded + == mDownstreamMulticastRoutingConfig.getListeningAddresses().contains(address)) { return; } @@ -861,8 +964,8 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub } /** - * Handles and forwards Thread daemon callbacks. This class must be accessed from the {@code - * mHandlerThread}. + * Handles and forwards Thread daemon callbacks. This class must be accessed from the thread of + * {@code mHandler}. */ private final class OtDaemonCallbackProxy extends IOtDaemonCallback.Stub { private final Map<IStateCallback, CallbackMetadata> mStateCallbacks = new HashMap<>(); |