Loading services/core/java/com/android/server/VcnManagementService.java +49 −2 Original line number Diff line number Diff line Loading @@ -20,10 +20,18 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkProvider; import android.net.NetworkRequest; import android.net.vcn.IVcnManagementService; import android.net.vcn.VcnConfig; import android.os.HandlerThread; import android.os.Looper; import android.os.ParcelUuid; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; /** * VcnManagementService manages Virtual Carrier Network profiles and lifecycles. * Loading Loading @@ -88,9 +96,16 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final Context mContext; @NonNull private final Dependencies mDeps; private VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) { @NonNull private final Looper mLooper; @NonNull private final VcnNetworkProvider mNetworkProvider; @VisibleForTesting(visibility = Visibility.PRIVATE) VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) { mContext = requireNonNull(context, "Missing context"); mDeps = requireNonNull(deps, "Missing dependencies"); mLooper = mDeps.getLooper(); mNetworkProvider = new VcnNetworkProvider(mContext, mLooper); } // Package-visibility for SystemServer to create instances. Loading @@ -98,11 +113,31 @@ public class VcnManagementService extends IVcnManagementService.Stub { return new VcnManagementService(context, new Dependencies()); } private static class Dependencies {} /** External dependencies used by VcnManagementService, for injection in tests */ @VisibleForTesting(visibility = Visibility.PRIVATE) public static class Dependencies { private HandlerThread mHandlerThread; /** Retrieves a looper for the VcnManagementService */ public Looper getLooper() { if (mHandlerThread == null) { synchronized (this) { if (mHandlerThread == null) { mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); } } } return mHandlerThread.getLooper(); } } /** Notifies the VcnManagementService that external dependencies can be set up. */ public void systemReady() { // TODO: Retrieve existing profiles from KeyStore mContext.getSystemService(ConnectivityManager.class) .registerNetworkProvider(mNetworkProvider); } /** Loading @@ -129,4 +164,16 @@ public class VcnManagementService extends IVcnManagementService.Stub { // TODO: Clear VCN configuration, trigger teardown as necessary } @VisibleForTesting(visibility = Visibility.PRIVATE) class VcnNetworkProvider extends NetworkProvider { VcnNetworkProvider(@NonNull Context context, @NonNull Looper looper) { super(context, looper, VcnNetworkProvider.class.getSimpleName()); } @Override public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) { // TODO: Handle network requests - Ensure VCN started, and start appropriate tunnels. } } } tests/vcn/java/com/android/server/VcnManagementServiceTest.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * 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 org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.content.Context; import android.net.ConnectivityManager; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; /** Tests for {@link VcnManagementService}. */ @RunWith(AndroidJUnit4.class) @SmallTest public class VcnManagementServiceTest { private final Context mMockContext = mock(Context.class); private final VcnManagementService.Dependencies mMockDeps = mock(VcnManagementService.Dependencies.class); private final TestLooper mTestLooper = new TestLooper(); private final ConnectivityManager mConnMgr = mock(ConnectivityManager.class); private final VcnManagementService mVcnMgmtSvc; public VcnManagementServiceTest() { doReturn(Context.CONNECTIVITY_SERVICE) .when(mMockContext) .getSystemServiceName(ConnectivityManager.class); doReturn(mConnMgr).when(mMockContext).getSystemService(Context.CONNECTIVITY_SERVICE); doReturn(mTestLooper.getLooper()).when(mMockDeps).getLooper(); mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps); } @Test public void testSystemReady() throws Exception { mVcnMgmtSvc.systemReady(); verify(mConnMgr) .registerNetworkProvider(any(VcnManagementService.VcnNetworkProvider.class)); } } Loading
services/core/java/com/android/server/VcnManagementService.java +49 −2 Original line number Diff line number Diff line Loading @@ -20,10 +20,18 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkProvider; import android.net.NetworkRequest; import android.net.vcn.IVcnManagementService; import android.net.vcn.VcnConfig; import android.os.HandlerThread; import android.os.Looper; import android.os.ParcelUuid; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; /** * VcnManagementService manages Virtual Carrier Network profiles and lifecycles. * Loading Loading @@ -88,9 +96,16 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final Context mContext; @NonNull private final Dependencies mDeps; private VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) { @NonNull private final Looper mLooper; @NonNull private final VcnNetworkProvider mNetworkProvider; @VisibleForTesting(visibility = Visibility.PRIVATE) VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) { mContext = requireNonNull(context, "Missing context"); mDeps = requireNonNull(deps, "Missing dependencies"); mLooper = mDeps.getLooper(); mNetworkProvider = new VcnNetworkProvider(mContext, mLooper); } // Package-visibility for SystemServer to create instances. Loading @@ -98,11 +113,31 @@ public class VcnManagementService extends IVcnManagementService.Stub { return new VcnManagementService(context, new Dependencies()); } private static class Dependencies {} /** External dependencies used by VcnManagementService, for injection in tests */ @VisibleForTesting(visibility = Visibility.PRIVATE) public static class Dependencies { private HandlerThread mHandlerThread; /** Retrieves a looper for the VcnManagementService */ public Looper getLooper() { if (mHandlerThread == null) { synchronized (this) { if (mHandlerThread == null) { mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); } } } return mHandlerThread.getLooper(); } } /** Notifies the VcnManagementService that external dependencies can be set up. */ public void systemReady() { // TODO: Retrieve existing profiles from KeyStore mContext.getSystemService(ConnectivityManager.class) .registerNetworkProvider(mNetworkProvider); } /** Loading @@ -129,4 +164,16 @@ public class VcnManagementService extends IVcnManagementService.Stub { // TODO: Clear VCN configuration, trigger teardown as necessary } @VisibleForTesting(visibility = Visibility.PRIVATE) class VcnNetworkProvider extends NetworkProvider { VcnNetworkProvider(@NonNull Context context, @NonNull Looper looper) { super(context, looper, VcnNetworkProvider.class.getSimpleName()); } @Override public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) { // TODO: Handle network requests - Ensure VCN started, and start appropriate tunnels. } } }
tests/vcn/java/com/android/server/VcnManagementServiceTest.java 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * 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 org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.content.Context; import android.net.ConnectivityManager; import android.os.test.TestLooper; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; /** Tests for {@link VcnManagementService}. */ @RunWith(AndroidJUnit4.class) @SmallTest public class VcnManagementServiceTest { private final Context mMockContext = mock(Context.class); private final VcnManagementService.Dependencies mMockDeps = mock(VcnManagementService.Dependencies.class); private final TestLooper mTestLooper = new TestLooper(); private final ConnectivityManager mConnMgr = mock(ConnectivityManager.class); private final VcnManagementService mVcnMgmtSvc; public VcnManagementServiceTest() { doReturn(Context.CONNECTIVITY_SERVICE) .when(mMockContext) .getSystemServiceName(ConnectivityManager.class); doReturn(mConnMgr).when(mMockContext).getSystemService(Context.CONNECTIVITY_SERVICE); doReturn(mTestLooper.getLooper()).when(mMockDeps).getLooper(); mVcnMgmtSvc = new VcnManagementService(mMockContext, mMockDeps); } @Test public void testSystemReady() throws Exception { mVcnMgmtSvc.systemReady(); verify(mConnMgr) .registerNetworkProvider(any(VcnManagementService.VcnNetworkProvider.class)); } }