Loading services/core/java/com/android/server/VcnManagementService.java +27 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,10 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.NetworkCapabilities; Loading Loading @@ -158,6 +161,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb; @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker; @NonNull private final VcnContext mVcnContext; @NonNull private final BroadcastReceiver mPkgChangeReceiver; /** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */ @Nullable private LocationPermissionChecker mLocationPermissionChecker; Loading Loading @@ -203,6 +207,29 @@ public class VcnManagementService extends IVcnManagementService.Stub { mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE); mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider); mPkgChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_PACKAGE_ADDED.equals(action) || Intent.ACTION_PACKAGE_REPLACED.equals(action) || Intent.ACTION_PACKAGE_REMOVED.equals(action)) { mTelephonySubscriptionTracker.handleSubscriptionsChanged(); } else { Log.wtf(TAG, "received unexpected intent: " + action); } } }; final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); mContext.registerReceiver( mPkgChangeReceiver, intentFilter, null /* broadcastPermission */, mHandler); // Run on handler to ensure I/O does not block system server startup mHandler.post(() -> { PersistableBundle configBundle = null; Loading tests/vcn/java/com/android/server/VcnManagementServiceTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -49,7 +49,9 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.NetworkCapabilities; Loading Loading @@ -336,6 +338,13 @@ public class VcnManagementServiceTest { return captor.getValue(); } private BroadcastReceiver getPackageChangeReceiver() { final ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); verify(mMockContext).registerReceiver(captor.capture(), any(), any(), any()); return captor.getValue(); } private Vcn startAndGetVcnInstance(ParcelUuid uuid) { mVcnMgmtSvc.setVcnConfig(uuid, TEST_VCN_CONFIG, TEST_PACKAGE_NAME); return mVcnMgmtSvc.getAllVcns().get(uuid); Loading Loading @@ -411,6 +420,42 @@ public class VcnManagementServiceTest { verify(newInstance, never()).teardownAsynchronously(); } @Test public void testPackageChangeListenerRegistered() throws Exception { verify(mMockContext).registerReceiver(any(BroadcastReceiver.class), argThat(filter -> { return filter.hasAction(Intent.ACTION_PACKAGE_ADDED) && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED) && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); } @Test public void testPackageChangeListener_packageAdded() throws Exception { final BroadcastReceiver receiver = getPackageChangeReceiver(); verify(mMockContext).registerReceiver(any(), argThat(filter -> { return filter.hasAction(Intent.ACTION_PACKAGE_ADDED) && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED) && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_ADDED)); verify(mSubscriptionTracker).handleSubscriptionsChanged(); } @Test public void testPackageChangeListener_packageRemoved() throws Exception { final BroadcastReceiver receiver = getPackageChangeReceiver(); verify(mMockContext).registerReceiver(any(), argThat(filter -> { return filter.hasAction(Intent.ACTION_PACKAGE_REMOVED) && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_REMOVED)); verify(mSubscriptionTracker).handleSubscriptionsChanged(); } @Test public void testSetVcnConfigRequiresNonSystemServer() throws Exception { doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid(); Loading Loading
services/core/java/com/android/server/VcnManagementService.java +27 −0 Original line number Diff line number Diff line Loading @@ -29,7 +29,10 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.NetworkCapabilities; Loading Loading @@ -158,6 +161,7 @@ public class VcnManagementService extends IVcnManagementService.Stub { @NonNull private final TelephonySubscriptionTrackerCallback mTelephonySubscriptionTrackerCb; @NonNull private final TelephonySubscriptionTracker mTelephonySubscriptionTracker; @NonNull private final VcnContext mVcnContext; @NonNull private final BroadcastReceiver mPkgChangeReceiver; /** Can only be assigned when {@link #systemReady()} is called, since it uses AppOpsManager. */ @Nullable private LocationPermissionChecker mLocationPermissionChecker; Loading Loading @@ -203,6 +207,29 @@ public class VcnManagementService extends IVcnManagementService.Stub { mConfigDiskRwHelper = mDeps.newPersistableBundleLockingReadWriteHelper(VCN_CONFIG_FILE); mVcnContext = mDeps.newVcnContext(mContext, mLooper, mNetworkProvider); mPkgChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_PACKAGE_ADDED.equals(action) || Intent.ACTION_PACKAGE_REPLACED.equals(action) || Intent.ACTION_PACKAGE_REMOVED.equals(action)) { mTelephonySubscriptionTracker.handleSubscriptionsChanged(); } else { Log.wtf(TAG, "received unexpected intent: " + action); } } }; final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); mContext.registerReceiver( mPkgChangeReceiver, intentFilter, null /* broadcastPermission */, mHandler); // Run on handler to ensure I/O does not block system server startup mHandler.post(() -> { PersistableBundle configBundle = null; Loading
tests/vcn/java/com/android/server/VcnManagementServiceTest.java +45 −0 Original line number Diff line number Diff line Loading @@ -49,7 +49,9 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.NetworkCapabilities; Loading Loading @@ -336,6 +338,13 @@ public class VcnManagementServiceTest { return captor.getValue(); } private BroadcastReceiver getPackageChangeReceiver() { final ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); verify(mMockContext).registerReceiver(captor.capture(), any(), any(), any()); return captor.getValue(); } private Vcn startAndGetVcnInstance(ParcelUuid uuid) { mVcnMgmtSvc.setVcnConfig(uuid, TEST_VCN_CONFIG, TEST_PACKAGE_NAME); return mVcnMgmtSvc.getAllVcns().get(uuid); Loading Loading @@ -411,6 +420,42 @@ public class VcnManagementServiceTest { verify(newInstance, never()).teardownAsynchronously(); } @Test public void testPackageChangeListenerRegistered() throws Exception { verify(mMockContext).registerReceiver(any(BroadcastReceiver.class), argThat(filter -> { return filter.hasAction(Intent.ACTION_PACKAGE_ADDED) && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED) && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); } @Test public void testPackageChangeListener_packageAdded() throws Exception { final BroadcastReceiver receiver = getPackageChangeReceiver(); verify(mMockContext).registerReceiver(any(), argThat(filter -> { return filter.hasAction(Intent.ACTION_PACKAGE_ADDED) && filter.hasAction(Intent.ACTION_PACKAGE_REPLACED) && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_ADDED)); verify(mSubscriptionTracker).handleSubscriptionsChanged(); } @Test public void testPackageChangeListener_packageRemoved() throws Exception { final BroadcastReceiver receiver = getPackageChangeReceiver(); verify(mMockContext).registerReceiver(any(), argThat(filter -> { return filter.hasAction(Intent.ACTION_PACKAGE_REMOVED) && filter.hasAction(Intent.ACTION_PACKAGE_REMOVED); }), any(), any()); receiver.onReceive(mMockContext, new Intent(Intent.ACTION_PACKAGE_REMOVED)); verify(mSubscriptionTracker).handleSubscriptionsChanged(); } @Test public void testSetVcnConfigRequiresNonSystemServer() throws Exception { doReturn(Process.SYSTEM_UID).when(mMockDeps).getBinderCallingUid(); Loading