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.thread.ThreadNetworkService; 32 33 /** 34 * Connectivity service initializer for core networking. This is called by system server to create 35 * a new instance of connectivity services. 36 */ 37 public final class ConnectivityServiceInitializer extends SystemService { 38 private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName(); 39 private final ConnectivityNativeService mConnectivityNative; 40 private final ConnectivityService mConnectivity; 41 private final IpSecService mIpSecService; 42 private final NsdService mNsdService; 43 private final NearbyService mNearbyService; 44 private final EthernetServiceImpl mEthernetServiceImpl; 45 private final ThreadNetworkService mThreadNetworkService; 46 ConnectivityServiceInitializer(Context context)47 public ConnectivityServiceInitializer(Context context) { 48 super(context); 49 // Load JNI libraries used by ConnectivityService and its dependencies 50 System.loadLibrary("service-connectivity"); 51 mEthernetServiceImpl = createEthernetService(context); 52 mConnectivity = new ConnectivityService(context); 53 mIpSecService = createIpSecService(context); 54 mConnectivityNative = createConnectivityNativeService(context); 55 mNsdService = createNsdService(context); 56 mNearbyService = createNearbyService(context); 57 mThreadNetworkService = createThreadNetworkService(context); 58 } 59 60 @Override onStart()61 public void onStart() { 62 if (mEthernetServiceImpl != null) { 63 Log.i(TAG, "Registering " + Context.ETHERNET_SERVICE); 64 publishBinderService(Context.ETHERNET_SERVICE, mEthernetServiceImpl, 65 /* allowIsolated= */ false); 66 } 67 68 Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE); 69 publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity, 70 /* allowIsolated= */ false); 71 72 if (mIpSecService != null) { 73 Log.i(TAG, "Registering " + Context.IPSEC_SERVICE); 74 publishBinderService(Context.IPSEC_SERVICE, mIpSecService, /* allowIsolated= */ false); 75 } 76 77 if (mConnectivityNative != null) { 78 Log.i(TAG, "Registering " + ConnectivityNativeService.SERVICE_NAME); 79 publishBinderService(ConnectivityNativeService.SERVICE_NAME, mConnectivityNative, 80 /* allowIsolated= */ false); 81 } 82 83 if (mNsdService != null) { 84 Log.i(TAG, "Registering " + Context.NSD_SERVICE); 85 publishBinderService(Context.NSD_SERVICE, mNsdService, /* allowIsolated= */ false); 86 } 87 88 if (mNearbyService != null) { 89 Log.i(TAG, "Registering " + ConstantsShim.NEARBY_SERVICE); 90 publishBinderService(ConstantsShim.NEARBY_SERVICE, mNearbyService, 91 /* allowIsolated= */ false); 92 } 93 94 if (mThreadNetworkService != null) { 95 Log.i(TAG, "Registering " + ThreadNetworkManager.SERVICE_NAME); 96 publishBinderService(ThreadNetworkManager.SERVICE_NAME, mThreadNetworkService, 97 /* allowIsolated= */ false); 98 } 99 } 100 101 @Override onBootPhase(int phase)102 public void onBootPhase(int phase) { 103 if (mNearbyService != null) { 104 mNearbyService.onBootPhase(phase); 105 } 106 107 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && mEthernetServiceImpl != null) { 108 mEthernetServiceImpl.start(); 109 } 110 111 if (mThreadNetworkService != null) { 112 mThreadNetworkService.onBootPhase(phase); 113 } 114 } 115 116 /** 117 * Return IpSecService instance, or null if current SDK is lower than T. 118 */ createIpSecService(final Context context)119 private IpSecService createIpSecService(final Context context) { 120 if (!SdkLevel.isAtLeastT()) return null; 121 122 return new IpSecService(context); 123 } 124 125 /** 126 * Return ConnectivityNativeService instance, or null if current SDK is lower than T. 127 */ createConnectivityNativeService(final Context context)128 private ConnectivityNativeService createConnectivityNativeService(final Context context) { 129 if (!SdkLevel.isAtLeastT()) return null; 130 try { 131 return new ConnectivityNativeService(context); 132 } catch (UnsupportedOperationException e) { 133 Log.d(TAG, "Unable to get ConnectivityNative service", e); 134 return null; 135 } 136 } 137 138 /** Return NsdService instance or null if current SDK is lower than T */ createNsdService(final Context context)139 private NsdService createNsdService(final Context context) { 140 if (!SdkLevel.isAtLeastT()) return null; 141 142 return NsdService.create(context); 143 } 144 145 /** Return Nearby service instance or null if current SDK is lower than T */ createNearbyService(final Context context)146 private NearbyService createNearbyService(final Context context) { 147 if (!SdkLevel.isAtLeastT()) return null; 148 try { 149 return new NearbyService(context); 150 } catch (UnsupportedOperationException e) { 151 // Nearby is not yet supported in all branches 152 // TODO: remove catch clause when it is available. 153 Log.i(TAG, "Skipping unsupported service " + ConstantsShim.NEARBY_SERVICE); 154 return null; 155 } 156 } 157 158 /** 159 * Return EthernetServiceImpl instance or null if current SDK is lower than T or Ethernet 160 * service isn't necessary. 161 */ createEthernetService(final Context context)162 private EthernetServiceImpl createEthernetService(final Context context) { 163 if (!SdkLevel.isAtLeastT() || !mConnectivity.deviceSupportsEthernet(context)) { 164 return null; 165 } 166 return EthernetService.create(context); 167 } 168 169 /** 170 * Returns Thread network service instance if supported. 171 * Thread is supported if all of below are satisfied: 172 * 1. the FEATURE_THREAD_NETWORK is available 173 * 2. the SDK level is V+, or SDK level is U and the device is a TV 174 */ 175 @Nullable createThreadNetworkService(final Context context)176 private ThreadNetworkService createThreadNetworkService(final Context context) { 177 final PackageManager pm = context.getPackageManager(); 178 if (!pm.hasSystemFeature(ThreadNetworkManager.FEATURE_NAME)) { 179 return null; 180 } 181 if (!SdkLevel.isAtLeastU()) { 182 return null; 183 } 184 if (!SdkLevel.isAtLeastV() && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) { 185 return null; 186 } 187 return new ThreadNetworkService(context); 188 } 189 } 190