diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index dcf3b5cae7..f13c5867fe 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -898,6 +898,18 @@ public class ConnectivityManager { } } + /** + * @hide + * TODO: Expose for SystemServer when becomes a module. + */ + public void systemReady() { + try { + mService.systemReady(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Checks if a given type uses the cellular data connection. * This should be replaced in the future by a network property. diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index d7f178cd0a..059ec28298 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -233,4 +233,6 @@ interface IConnectivityManager void simulateDataStall(int detectionMethod, long timestampMillis, in Network network, in PersistableBundle extras); + + void systemReady(); } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index bb9f6d2c83..fc6abc8d2d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2301,10 +2301,21 @@ public class ConnectivityService extends IConnectivityManager.Stub } /** - * Called when the system is ready and ConnectivityService can initialize remaining components. + * Called by SystemServer through ConnectivityManager when the system is ready. + */ + @Override + public void systemReady() { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Calling Uid is not system uid."); + } + systemReadyInternal(); + } + + /** + * Called when ConnectivityService can initialize remaining components. */ @VisibleForTesting - public void systemReady() { + public void systemReadyInternal() { // Let PermissionMonitor#startMonitoring() running in the beginning of the systemReady // before MultipathPolicyTracker.start(). Since mApps in PermissionMonitor needs to be // populated first to ensure that listening network request which is sent by diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java new file mode 100644 index 0000000000..2bc8925be0 --- /dev/null +++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java @@ -0,0 +1,66 @@ +/* + * 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 static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; +import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; + +import android.content.Context; +import android.net.INetworkPolicyManager; +import android.net.INetworkStatsService; +import android.os.INetworkManagementService; +import android.os.ServiceManager; +import android.util.Log; + +/** + * Connectivity service initializer for core networking. This is called by system server to create + * a new instance of ConnectivityService. + */ +public final class ConnectivityServiceInitializer extends SystemService { + private static final String TAG = ConnectivityServiceInitializer.class.getSimpleName(); + private final ConnectivityService mConnectivity; + + public ConnectivityServiceInitializer(Context context) { + super(context); + // TODO: Define formal APIs to get the needed services. + mConnectivity = new ConnectivityService(context, getNetworkManagementService(), + getNetworkStatsService(), getNetworkPolicyManager()); + } + + @Override + public void onStart() { + Log.i(TAG, "Registering " + Context.CONNECTIVITY_SERVICE); + publishBinderService(Context.CONNECTIVITY_SERVICE, mConnectivity, + /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); + } + + private INetworkManagementService getNetworkManagementService() { + return INetworkManagementService.Stub.asInterface( + ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); + } + + private INetworkStatsService getNetworkStatsService() { + return INetworkStatsService.Stub.asInterface( + ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); + } + + private INetworkPolicyManager getNetworkPolicyManager() { + return INetworkPolicyManager.Stub.asInterface( + ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); + } + +} diff --git a/tests/net/Android.bp b/tests/net/Android.bp index 0fe84abcbc..cd2dc0403b 100644 --- a/tests/net/Android.bp +++ b/tests/net/Android.bp @@ -59,6 +59,7 @@ android_test { "mockito-target-minus-junit4", "net-tests-utils", "platform-test-annotations", + "service-connectivity", "services.core", "services.net", ], diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt index bc069e148b..dba1856ea6 100644 --- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt @@ -167,7 +167,7 @@ class ConnectivityServiceIntegrationTest { cm = ConnectivityManager(context, service) context.addMockSystemService(Context.CONNECTIVITY_SERVICE, cm) - service.systemReady() + service.systemReadyInternal() } private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService( diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 862e552811..998aee43f8 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -1246,7 +1246,7 @@ public class ConnectivityServiceTest { // Create local CM before sending system ready so that we can answer // getSystemService() correctly. mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService); - mService.systemReady(); + mService.systemReadyInternal(); mockVpn(Process.myUid()); mCm.bindProcessToNetwork(null);