/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.annotation.Nullable; import android.content.Context; import android.content.pm.PackageManager; import android.net.thread.ThreadNetworkManager; import android.util.Log; import com.android.modules.utils.build.SdkLevel; import com.android.networkstack.apishim.ConstantsShim; import com.android.server.connectivity.ConnectivityNativeService; import com.android.server.ethernet.EthernetService; import com.android.server.ethernet.EthernetServiceImpl; import com.android.server.nearby.NearbyService; import com.android.server.thread.ThreadNetworkService; /** * Connectivity service initializer for core networking. This is called by system server to create * a new instance of connectivity services. */ public final class ConnectivityServiceInitializer extends SystemService { private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName(); private final ConnectivityNativeService mConnectivityNative; private final ConnectivityService mConnectivity; private final IpSecService mIpSecService; private final NsdService mNsdService; private final NearbyService mNearbyService; private final EthernetServiceImpl mEthernetServiceImpl; private final ThreadNetworkService mThreadNetworkService; public ConnectivityServiceInitializer(Context context) { super(context); // Load JNI libraries used by ConnectivityService and its dependencies System.loadLibrary("service-connectivity"); mEthernetServiceImpl = createEthernetService(context); mConnectivity = new ConnectivityService(context); mIpSecService = createIpSecService(context); mConnectivityNative = createConnectivityNativeService(context); mNsdService = createNsdService(context); mNearbyService = createNearbyService(context); mThreadNetworkService = createThreadNetworkService(context); } @Override public void onStart() { if (mEthernetServiceImpl != null) { Log.i(TAG, "Registering " + Context.ETHERNET_SERVICE); publishBinderService(Context.ETHERNET_SERVICE, mEthernetServiceImpl, /* allowIsolated= */ false); } Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE); publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity, /* allowIsolated= */ false); if (mIpSecService != null) { Log.i(TAG, "Registering " + Context.IPSEC_SERVICE); publishBinderService(Context.IPSEC_SERVICE, mIpSecService, /* allowIsolated= */ false); } if (mConnectivityNative != null) { Log.i(TAG, "Registering " + ConnectivityNativeService.SERVICE_NAME); publishBinderService(ConnectivityNativeService.SERVICE_NAME, mConnectivityNative, /* allowIsolated= */ false); } if (mNsdService != null) { Log.i(TAG, "Registering " + Context.NSD_SERVICE); publishBinderService(Context.NSD_SERVICE, mNsdService, /* allowIsolated= */ false); } if (mNearbyService != null) { Log.i(TAG, "Registering " + ConstantsShim.NEARBY_SERVICE); publishBinderService(ConstantsShim.NEARBY_SERVICE, mNearbyService, /* allowIsolated= */ false); } if (mThreadNetworkService != null) { Log.i(TAG, "Registering " + ThreadNetworkManager.SERVICE_NAME); publishBinderService(ThreadNetworkManager.SERVICE_NAME, mThreadNetworkService, /* allowIsolated= */ false); } } @Override public void onBootPhase(int phase) { if (mNearbyService != null) { mNearbyService.onBootPhase(phase); } if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && mEthernetServiceImpl != null) { mEthernetServiceImpl.start(); } if (mThreadNetworkService != null) { mThreadNetworkService.onBootPhase(phase); } } /** * Return IpSecService instance, or null if current SDK is lower than T. */ private IpSecService createIpSecService(final Context context) { if (!SdkLevel.isAtLeastT()) return null; return new IpSecService(context); } /** * Return ConnectivityNativeService instance, or null if current SDK is lower than T. */ private ConnectivityNativeService createConnectivityNativeService(final Context context) { if (!SdkLevel.isAtLeastT()) return null; try { return new ConnectivityNativeService(context); } catch (UnsupportedOperationException e) { Log.d(TAG, "Unable to get ConnectivityNative service", e); return null; } } /** Return NsdService instance or null if current SDK is lower than T */ private NsdService createNsdService(final Context context) { if (!SdkLevel.isAtLeastT()) return null; return NsdService.create(context); } /** Return Nearby service instance or null if current SDK is lower than T */ private NearbyService createNearbyService(final Context context) { if (!SdkLevel.isAtLeastT()) return null; try { return new NearbyService(context); } catch (UnsupportedOperationException e) { // Nearby is not yet supported in all branches // TODO: remove catch clause when it is available. Log.i(TAG, "Skipping unsupported service " + ConstantsShim.NEARBY_SERVICE); return null; } } /** * Return EthernetServiceImpl instance or null if current SDK is lower than T or Ethernet * service isn't necessary. */ private EthernetServiceImpl createEthernetService(final Context context) { if (!SdkLevel.isAtLeastT() || !mConnectivity.deviceSupportsEthernet(context)) { return null; } return EthernetService.create(context); } /** * Returns Thread network service instance if supported. * Thread is supported if all of below are satisfied: * 1. the FEATURE_THREAD_NETWORK is available * 2. the SDK level is V+, or SDK level is U and the device is a TV */ @Nullable private ThreadNetworkService createThreadNetworkService(final Context context) { final PackageManager pm = context.getPackageManager(); if (!pm.hasSystemFeature(ThreadNetworkManager.FEATURE_NAME)) { return null; } if (!SdkLevel.isAtLeastU()) { return null; } if (!SdkLevel.isAtLeastV() && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) { return null; } return new ThreadNetworkService(context); } }