summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody Kesting <ckesting@google.com>2021-03-01 11:39:18 -0800
committerCody Kesting <ckesting@google.com>2021-03-08 11:14:25 -0800
commit212c06aaa6437183d7ff38aaf9b1069d4a2d56c3 (patch)
treeb6772c7285876fe10da719c58048e591cd5eef5c
parent055977a3c956458b1b44d27d6e14e7466bf744c0 (diff)
Notify VcnStatusCallbacks for VCN start/stop.
This CL updates VcnManagementService to notify VcnStatusCallbacks when a VCN is started or stopped. VcnStatusCallbacks will also be notified for config changes that cause a VCN to exit Safe Mode. Bug: 180659281 Test: atest FrameworksVcnTests Change-Id: I4168c868185880621333855dfcb51e46cb662741
-rw-r--r--services/core/java/com/android/server/VcnManagementService.java53
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java39
2 files changed, 81 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index ad2f52401e93..0eca09e8d8ec 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -16,6 +16,9 @@
package com.android.server;
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_INACTIVE;
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED;
import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
@@ -37,6 +40,7 @@ import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnManager.VcnErrorCode;
+import android.net.vcn.VcnManager.VcnStatusCode;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.net.wifi.WifiInfo;
import android.os.Binder;
@@ -421,6 +425,11 @@ public class VcnManagementService extends IVcnManagementService.Stub {
// Carrier App manually removing/adding a VcnConfig.
if (mVcns.get(uuidToTeardown) == instanceToTeardown) {
stopVcnLocked(uuidToTeardown);
+
+ // TODO(b/181789060): invoke asynchronously after Vcn notifies
+ // through VcnCallback
+ notifyAllPermissionedStatusCallbacksLocked(
+ uuidToTeardown, VCN_STATUS_CODE_INACTIVE);
}
}
}, instanceToTeardown, CARRIER_PRIVILEGES_LOST_TEARDOWN_DELAY_MS);
@@ -455,6 +464,17 @@ public class VcnManagementService extends IVcnManagementService.Stub {
}
@GuardedBy("mLock")
+ private void notifyAllPermissionedStatusCallbacksLocked(
+ @NonNull ParcelUuid subGroup, @VcnStatusCode int statusCode) {
+ for (final VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) {
+ if (isCallbackPermissioned(cbInfo, subGroup)) {
+ Binder.withCleanCallingIdentity(
+ () -> cbInfo.mCallback.onVcnStatusChanged(statusCode));
+ }
+ }
+ }
+
+ @GuardedBy("mLock")
private void startVcnLocked(@NonNull ParcelUuid subscriptionGroup, @NonNull VcnConfig config) {
Slog.v(TAG, "Starting VCN config for subGrp: " + subscriptionGroup);
@@ -470,6 +490,9 @@ public class VcnManagementService extends IVcnManagementService.Stub {
// Now that a new VCN has started, notify all registered listeners to refresh their
// UnderlyingNetworkPolicy.
notifyAllPolicyListenersLocked();
+
+ // TODO(b/181789060): invoke asynchronously after Vcn notifies through VcnCallback
+ notifyAllPermissionedStatusCallbacksLocked(subscriptionGroup, VCN_STATUS_CODE_ACTIVE);
}
@GuardedBy("mLock")
@@ -478,7 +501,16 @@ public class VcnManagementService extends IVcnManagementService.Stub {
Slog.v(TAG, "Starting or updating VCN config for subGrp: " + subscriptionGroup);
if (mVcns.containsKey(subscriptionGroup)) {
- mVcns.get(subscriptionGroup).updateConfig(config);
+ final Vcn vcn = mVcns.get(subscriptionGroup);
+ final boolean isActive = vcn.isActive();
+ vcn.updateConfig(config);
+
+ // Only notify VcnStatusCallbacks if this VCN was previously in Safe Mode
+ if (!isActive) {
+ // TODO(b/181789060): invoke asynchronously after Vcn notifies through VcnCallback
+ notifyAllPermissionedStatusCallbacksLocked(
+ subscriptionGroup, VCN_STATUS_CODE_ACTIVE);
+ }
} else {
startVcnLocked(subscriptionGroup, config);
}
@@ -531,9 +563,17 @@ public class VcnManagementService extends IVcnManagementService.Stub {
Binder.withCleanCallingIdentity(() -> {
synchronized (mLock) {
mConfigs.remove(subscriptionGroup);
+ final boolean vcnExists = mVcns.containsKey(subscriptionGroup);
stopVcnLocked(subscriptionGroup);
+ if (vcnExists) {
+ // TODO(b/181789060): invoke asynchronously after Vcn notifies through
+ // VcnCallback
+ notifyAllPermissionedStatusCallbacksLocked(
+ subscriptionGroup, VCN_STATUS_CODE_NOT_CONFIGURED);
+ }
+
writeConfigsToDiskLocked();
}
});
@@ -857,16 +897,7 @@ public class VcnManagementService extends IVcnManagementService.Stub {
}
notifyAllPolicyListenersLocked();
-
- // Notify all registered StatusCallbacks for this subGroup
- for (VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) {
- if (isCallbackPermissioned(cbInfo, mSubGroup)) {
- Binder.withCleanCallingIdentity(
- () ->
- cbInfo.mCallback.onVcnStatusChanged(
- VCN_STATUS_CODE_SAFE_MODE));
- }
- }
+ notifyAllPermissionedStatusCallbacksLocked(mSubGroup, VCN_STATUS_CODE_SAFE_MODE);
}
}
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 73a6b88e29ed..11498dec8165 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -461,6 +461,34 @@ public class VcnManagementServiceTest {
}
@Test
+ public void testSetVcnConfigNotifiesStatusCallback() throws Exception {
+ mVcnMgmtSvc.systemReady();
+ doReturn(true)
+ .when(mLocationPermissionChecker)
+ .checkLocationPermission(eq(TEST_PACKAGE_NAME), any(), eq(TEST_UID), any());
+ triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
+
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+
+ // Use a different UUID to simulate a new VCN config.
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+ }
+
+ @Test
+ public void testSetVcnConfigInSafeModeNotifiesStatusCallback() throws Exception {
+ setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, false /* isActive */);
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
+
+ mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+ }
+
+ @Test
public void testClearVcnConfigRequiresNonSystemServer() throws Exception {
doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid();
@@ -503,6 +531,17 @@ public class VcnManagementServiceTest {
}
@Test
+ public void testClearVcnConfigNotifiesStatusCallback() throws Exception {
+ setupSubscriptionAndStartVcn(TEST_SUBSCRIPTION_ID, TEST_UUID_2, true /* isActive */);
+ mVcnMgmtSvc.registerVcnStatusCallback(TEST_UUID_2, mMockStatusCallback, TEST_PACKAGE_NAME);
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_ACTIVE);
+
+ mVcnMgmtSvc.clearVcnConfig(TEST_UUID_2);
+
+ verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_NOT_CONFIGURED);
+ }
+
+ @Test
public void testSetVcnConfigClearVcnConfigStartsUpdatesAndTeardsDownVcns() throws Exception {
// Use a different UUID to simulate a new VCN config.
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);