1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import android.annotation.Nullable; 20 import android.content.Context; 21 import android.content.pm.PackageManager; 22 import android.net.thread.ThreadNetworkManager; 23 import android.util.Log; 24 25 import com.android.modules.utils.build.SdkLevel; 26 import com.android.networkstack.apishim.ConstantsShim; 27 import com.android.server.connectivity.ConnectivityNativeService; 28 import com.android.server.ethernet.EthernetService; 29 import com.android.server.ethernet.EthernetServiceImpl; 30 import com.android.server.nearby.NearbyService; 31 import com.android.server.net.ct.CertificateTransparencyService; 32 import com.android.server.thread.ThreadNetworkService; 33 import com.android.server.vcn.VcnLocation; 34 35 import java.lang.reflect.Constructor; 36 37 /** 38 * Connectivity service initializer for core networking. This is called by system server to create 39 * a new instance of connectivity services. 40 */ 41 public final class ConnectivityServiceInitializer extends SystemService { 42 private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName(); 43 private static final String CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS = 44 "com.android.server.ConnectivityServiceInitializerB"; 45 46 private final ConnectivityNativeService mConnectivityNative; 47 private final ConnectivityService mConnectivity; 48 private final IpSecService mIpSecService; 49 private final NsdService mNsdService; 50 private final NearbyService mNearbyService; 51 private final EthernetServiceImpl mEthernetServiceImpl; 52 private final ThreadNetworkService mThreadNetworkService; 53 private final CertificateTransparencyService mCertificateTransparencyService; 54 private final SystemService mConnectivityServiceInitializerB; 55 ConnectivityServiceInitializer(Context context)56 public ConnectivityServiceInitializer(Context context) { 57 super(context); 58 // Load JNI libraries used by ConnectivityService and its dependencies 59 System.loadLibrary("service-connectivity"); 60 mEthernetServiceImpl = createEthernetService(context); 61 mConnectivity = new ConnectivityService(context); 62 mIpSecService = createIpSecService(context); 63 mConnectivityNative = createConnectivityNativeService(context); 64 mNsdService = createNsdService(context); 65 mNearbyService = createNearbyService(context); 66 mThreadNetworkService = createThreadNetworkService(context); 67 mCertificateTransparencyService = createCertificateTransparencyService(context); 68 mConnectivityServiceInitializerB = createConnectivityServiceInitializerB(context); 69 } 70 71 @Override onStart()72 public void onStart() { 73 if (mEthernetServiceImpl != null) { 74 Log.i(TAG, "Registering " + Context.ETHERNET_SERVICE); 75 publishBinderService(Context.ETHERNET_SERVICE, mEthernetServiceImpl, 76 /* allowIsolated= */ false); 77 } 78 79 Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE); 80 publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity, 81 /* allowIsolated= */ false); 82 83 if (mIpSecService != null) { 84 Log.i(TAG, "Registering " + Context.IPSEC_SERVICE); 85 publishBinderService(Context.IPSEC_SERVICE, mIpSecService, /* allowIsolated= */ false); 86 } 87 88 if (mConnectivityNative != null) { 89 Log.i(TAG, "Registering " + ConnectivityNativeService.SERVICE_NAME); 90 publishBinderService(ConnectivityNativeService.SERVICE_NAME, mConnectivityNative, 91 /* allowIsolated= */ false); 92 } 93 94 if (mNsdService != null) { 95 Log.i(TAG, "Registering " + Context.NSD_SERVICE); 96 publishBinderService(Context.NSD_SERVICE, mNsdService, /* allowIsolated= */ false); 97 } 98 99 if (mNearbyService != null) { 100 Log.i(TAG, "Registering " + ConstantsShim.NEARBY_SERVICE); 101 publishBinderService(ConstantsShim.NEARBY_SERVICE, mNearbyService, 102 /* allowIsolated= */ false); 103 } 104 105 if (mThreadNetworkService != null) { 106 Log.i(TAG, "Registering " + ThreadNetworkManager.SERVICE_NAME); 107 publishBinderService(ThreadNetworkManager.SERVICE_NAME, mThreadNetworkService, 108 /* allowIsolated= */ false); 109 } 110 111 if (mConnectivityServiceInitializerB != null) { 112 Log.i(TAG, "ConnectivityServiceInitializerB#onStart"); 113 mConnectivityServiceInitializerB.onStart(); 114 } 115 } 116 117 @Override onBootPhase(int phase)118 public void onBootPhase(int phase) { 119 if (mNearbyService != null) { 120 mNearbyService.onBootPhase(phase); 121 } 122 123 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && mEthernetServiceImpl != null) { 124 mEthernetServiceImpl.start(); 125 } 126 127 if (mThreadNetworkService != null) { 128 mThreadNetworkService.onBootPhase(phase); 129 } 130 131 if (SdkLevel.isAtLeastV() && mCertificateTransparencyService != null) { 132 mCertificateTransparencyService.onBootPhase(phase); 133 } 134 135 if (mConnectivityServiceInitializerB != null) { 136 mConnectivityServiceInitializerB.onBootPhase(phase); 137 } 138 } 139 140 /** 141 * Return IpSecService instance, or null if current SDK is lower than T. 142 */ createIpSecService(final Context context)143 private IpSecService createIpSecService(final Context context) { 144 if (!SdkLevel.isAtLeastT()) return null; 145 146 return new IpSecService(context); 147 } 148 149 /** 150 * Return ConnectivityNativeService instance, or null if current SDK is lower than T. 151 */ createConnectivityNativeService(final Context context)152 private ConnectivityNativeService createConnectivityNativeService(final Context context) { 153 if (!SdkLevel.isAtLeastT()) return null; 154 try { 155 return new ConnectivityNativeService(context); 156 } catch (UnsupportedOperationException e) { 157 Log.d(TAG, "Unable to get ConnectivityNative service", e); 158 return null; 159 } 160 } 161 162 /** Return NsdService instance or null if current SDK is lower than T */ createNsdService(final Context context)163 private NsdService createNsdService(final Context context) { 164 if (!SdkLevel.isAtLeastT()) return null; 165 166 return NsdService.create(context); 167 } 168 169 /** Return Nearby service instance or null if current SDK is lower than T */ createNearbyService(final Context context)170 private NearbyService createNearbyService(final Context context) { 171 if (!SdkLevel.isAtLeastT()) return null; 172 try { 173 return new NearbyService(context); 174 } catch (UnsupportedOperationException e) { 175 // Nearby is not yet supported in all branches 176 // TODO: remove catch clause when it is available. 177 Log.i(TAG, "Skipping unsupported service " + ConstantsShim.NEARBY_SERVICE); 178 return null; 179 } 180 } 181 182 /** 183 * Return EthernetServiceImpl instance or null if current SDK is lower than T or Ethernet 184 * service isn't necessary. 185 */ createEthernetService(final Context context)186 private EthernetServiceImpl createEthernetService(final Context context) { 187 if (!SdkLevel.isAtLeastT() || !mConnectivity.deviceSupportsEthernet(context)) { 188 return null; 189 } 190 return EthernetService.create(context); 191 } 192 193 /** 194 * Returns Thread network service instance if supported. 195 * Thread is supported if all of below are satisfied: 196 * 1. the FEATURE_THREAD_NETWORK is available 197 * 2. the SDK level is V+, or SDK level is U and the device is a TV 198 */ 199 @Nullable createThreadNetworkService(final Context context)200 private ThreadNetworkService createThreadNetworkService(final Context context) { 201 final PackageManager pm = context.getPackageManager(); 202 if (!pm.hasSystemFeature(ThreadNetworkManager.FEATURE_NAME)) { 203 return null; 204 } 205 if (!SdkLevel.isAtLeastU()) { 206 return null; 207 } 208 if (!SdkLevel.isAtLeastV() && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) { 209 return null; 210 } 211 return new ThreadNetworkService(context); 212 } 213 214 /** Return CertificateTransparencyService instance if enable, otherwise null. */ 215 @Nullable createCertificateTransparencyService( final Context context)216 private CertificateTransparencyService createCertificateTransparencyService( 217 final Context context) { 218 return SdkLevel.isAtLeastV() && CertificateTransparencyService.enabled(context) 219 ? new CertificateTransparencyService(context) 220 : null; 221 } 222 223 // TODO: b/374174952 After VCN code is moved to the Connectivity folder, merge 224 // ConnectivityServiceInitializerB into ConnectivityServiceInitializer and directly create and 225 // register VcnManagementService in ConnectivityServiceInitializer 226 /** Return ConnectivityServiceInitializerB instance if enable, otherwise null. */ 227 @Nullable createConnectivityServiceInitializerB(Context context)228 private SystemService createConnectivityServiceInitializerB(Context context) { 229 if (!VcnLocation.IS_VCN_IN_MAINLINE || !SdkLevel.isAtLeastB()) { 230 return null; 231 } 232 233 try { 234 final Class<?> connectivityServiceInitializerBClass = 235 Class.forName(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS); 236 final Constructor constructor = 237 connectivityServiceInitializerBClass.getConstructor(Context.class); 238 239 return (SystemService) constructor.newInstance(context); 240 } catch (Exception e) { 241 Log.e(TAG, "Fail to load ConnectivityServiceInitializerB " + e); 242 } 243 244 return null; 245 } 246 } 247