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
This commit is contained in:
@@ -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);
|
||||
@@ -454,6 +463,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -460,6 +460,34 @@ public class VcnManagementServiceTest {
|
||||
verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
|
||||
}
|
||||
|
||||
@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();
|
||||
@@ -502,6 +530,17 @@ public class VcnManagementServiceTest {
|
||||
verify(mConfigReadWriteHelper).writeToDisk(any(PersistableBundle.class));
|
||||
}
|
||||
|
||||
@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.
|
||||
|
||||
Reference in New Issue
Block a user