From 192e66ef4e382aae3d4021a8175ad3ab5c75e229 Mon Sep 17 00:00:00 2001 From: Binh Nguyen Date: Mon, 19 Sep 2022 21:33:04 -0700 Subject: Add a feature flag for AdServices System Service receiver registration - Add Flags and PhFlags that uses DeviceConfig - Define a flag to enable the AdServiceSystemServiceBroadcastReceiver - This will make sure that when the flag is disabled, we will not register any Receiver. Bug: 247581193 Test: presubmit Change-Id: I24582e19909241001f1665c73eab36b31e89fea4 --- .../tests/unittest/system-service/Android.bp | 1 + .../adservices/AdServicesManagerServiceTest.java | 138 ++++++++++++++++++--- .../com/android/server/adservices/PhFlagsTest.java | 55 ++++++++ 3 files changed, 174 insertions(+), 20 deletions(-) create mode 100644 adservices/tests/unittest/system-service/src/com/android/server/adservices/PhFlagsTest.java (limited to 'adservices/tests/unittest/system-service') diff --git a/adservices/tests/unittest/system-service/Android.bp b/adservices/tests/unittest/system-service/Android.bp index 8d69bff677..a3757ad410 100644 --- a/adservices/tests/unittest/system-service/Android.bp +++ b/adservices/tests/unittest/system-service/Android.bp @@ -22,6 +22,7 @@ android_test { "src/com/android/server/adservices/*.java", "src/**/*.java", ], + defaults: ["modules-utils-testable-device-config-defaults"], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", static_libs: [ diff --git a/adservices/tests/unittest/system-service/src/com/android/server/adservices/AdServicesManagerServiceTest.java b/adservices/tests/unittest/system-service/src/com/android/server/adservices/AdServicesManagerServiceTest.java index aab7236ed4..9e168b124c 100644 --- a/adservices/tests/unittest/system-service/src/com/android/server/adservices/AdServicesManagerServiceTest.java +++ b/adservices/tests/unittest/system-service/src/com/android/server/adservices/AdServicesManagerServiceTest.java @@ -16,23 +16,39 @@ package com.android.server.adservices; +import static com.android.server.adservices.PhFlags.KEY_ADSERVICES_SYSTEM_SERVICE_ENABLED; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; + import android.Manifest; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.net.Uri; +import android.os.Handler; import android.os.UserHandle; +import android.provider.DeviceConfig; import androidx.test.platform.app.InstrumentationRegistry; -import com.google.common.truth.Truth; +import com.android.modules.utils.testing.TestableDeviceConfig; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; /** Tests for {@link AdServicesManagerService} */ public class AdServicesManagerServiceTest { + @Rule + public final TestableDeviceConfig.TestableDeviceConfigRule mDeviceConfigRule = + new TestableDeviceConfig.TestableDeviceConfigRule(); + private AdServicesManagerService mService; private Context mSpyContext; private static final String PACKAGE_NAME = "com.package.example"; @@ -45,18 +61,100 @@ public class AdServicesManagerServiceTest { @Before public void setup() { + MockitoAnnotations.initMocks(this); + Context context = InstrumentationRegistry.getInstrumentation().getContext(); mSpyContext = Mockito.spy(context); InstrumentationRegistry.getInstrumentation() .getUiAutomation() .adoptShellPermissionIdentity(Manifest.permission.INTERACT_ACROSS_USERS_FULL); + } + @Test + public void testAdServicesSystemService_enabled_then_disabled() { + // First enable the flag. + DeviceConfig.setProperty( + DeviceConfig.NAMESPACE_ADSERVICES, + KEY_ADSERVICES_SYSTEM_SERVICE_ENABLED, + Boolean.toString(Boolean.TRUE), + /* makeDefault */ false); + + // This will trigger the registration of the Receiver. mService = new AdServicesManagerService(mSpyContext); + + ArgumentCaptor argumentReceiver = + ArgumentCaptor.forClass(BroadcastReceiver.class); + ArgumentCaptor argumentIntentFilter = + ArgumentCaptor.forClass(IntentFilter.class); + ArgumentCaptor argumentPermission = ArgumentCaptor.forClass(String.class); + ArgumentCaptor argumentHandler = ArgumentCaptor.forClass(Handler.class); + + // Calling the second time will not register again. + mService.registerPackagedChangedBroadcastReceivers(); + + // The flag is enabled so we call registerReceiverForAllUsers + Mockito.verify(mSpyContext, Mockito.times(1)) + .registerReceiverForAllUsers( + argumentReceiver.capture(), + argumentIntentFilter.capture(), + argumentPermission.capture(), + argumentHandler.capture()); + + BroadcastReceiver receiver = argumentReceiver.getValue(); + assertThat(receiver).isNotNull(); + + assertThat(argumentIntentFilter.getValue().getAction(0)) + .isEqualTo(Intent.ACTION_PACKAGE_FULLY_REMOVED); + assertThat(argumentIntentFilter.getValue().getAction(1)) + .isEqualTo(Intent.ACTION_PACKAGE_DATA_CLEARED); + assertThat(argumentIntentFilter.getValue().getAction(2)) + .isEqualTo(Intent.ACTION_PACKAGE_ADDED); + assertThat(argumentIntentFilter.getValue().getDataScheme(0)).isEqualTo("package"); + + assertThat(argumentPermission.getValue()).isNull(); + assertThat(argumentHandler.getValue()).isNotNull(); + + // Now disable the flag. + DeviceConfig.setProperty( + DeviceConfig.NAMESPACE_ADSERVICES, + KEY_ADSERVICES_SYSTEM_SERVICE_ENABLED, + Boolean.toString(Boolean.FALSE), + /* makeDefault */ false); + + // Calling when the flag is disabled will unregister the Receiver! + mService.registerPackagedChangedBroadcastReceivers(); + Mockito.verify(mSpyContext, Mockito.times(1)) + .unregisterReceiver(argumentReceiver.capture()); + + // The unregistered is called on the same receiver when registered above. + assertThat(argumentReceiver.getValue()).isSameInstanceAs(receiver); + } + + @Test + public void testAdServicesSystemService_disabled() { + // Disable the flag. + DeviceConfig.setProperty( + DeviceConfig.NAMESPACE_ADSERVICES, + KEY_ADSERVICES_SYSTEM_SERVICE_ENABLED, + Boolean.toString(Boolean.FALSE), + /* makeDefault */ false); + + mService = new AdServicesManagerService(mSpyContext); + + // The flag is disabled so there is no registerReceiverForAllUsers + Mockito.verify(mSpyContext, Mockito.times(0)) + .registerReceiverForAllUsers( + any(BroadcastReceiver.class), + any(IntentFilter.class), + any(String.class), + any(Handler.class)); } @Test public void testSendBroadcastForPackageFullyRemoved() { + mService = new AdServicesManagerService(mSpyContext); + Intent i = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED); i.setData(Uri.parse("package:" + PACKAGE_NAME)); i.putExtra(Intent.EXTRA_UID, PACKAGE_UID); @@ -70,18 +168,19 @@ public class AdServicesManagerServiceTest { Mockito.verify(mSpyContext, Mockito.times(1)) .sendBroadcastAsUser(argumentIntent.capture(), argumentUser.capture()); - Truth.assertThat(argumentIntent.getValue().getAction()) - .isEqualTo(PACKAGE_CHANGED_BROADCAST); - Truth.assertThat(argumentIntent.getValue().getData()).isEqualTo(i.getData()); - Truth.assertThat(argumentIntent.getValue().getStringExtra("action")) + assertThat(argumentIntent.getValue().getAction()).isEqualTo(PACKAGE_CHANGED_BROADCAST); + assertThat(argumentIntent.getValue().getData()).isEqualTo(i.getData()); + assertThat(argumentIntent.getValue().getStringExtra("action")) .isEqualTo(PACKAGE_FULLY_REMOVED); - Truth.assertThat(argumentIntent.getValue().getIntExtra(Intent.EXTRA_UID, -1)) + assertThat(argumentIntent.getValue().getIntExtra(Intent.EXTRA_UID, -1)) .isEqualTo(PACKAGE_UID); - Truth.assertThat(argumentUser.getValue()).isEqualTo(mSpyContext.getUser()); + assertThat(argumentUser.getValue()).isEqualTo(mSpyContext.getUser()); } @Test public void testSendBroadcastForPackageAdded() { + mService = new AdServicesManagerService(mSpyContext); + Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED); i.setData(Uri.parse("package:" + PACKAGE_NAME)); i.putExtra(Intent.EXTRA_UID, PACKAGE_UID); @@ -96,18 +195,18 @@ public class AdServicesManagerServiceTest { Mockito.verify(mSpyContext, Mockito.times(1)) .sendBroadcastAsUser(argumentIntent.capture(), argumentUser.capture()); - Truth.assertThat(argumentIntent.getValue().getAction()) - .isEqualTo(PACKAGE_CHANGED_BROADCAST); - Truth.assertThat(argumentIntent.getValue().getData()).isEqualTo(i.getData()); - Truth.assertThat(argumentIntent.getValue().getStringExtra("action")) - .isEqualTo(PACKAGE_ADDED); - Truth.assertThat(argumentIntent.getValue().getIntExtra(Intent.EXTRA_UID, -1)) + assertThat(argumentIntent.getValue().getAction()).isEqualTo(PACKAGE_CHANGED_BROADCAST); + assertThat(argumentIntent.getValue().getData()).isEqualTo(i.getData()); + assertThat(argumentIntent.getValue().getStringExtra("action")).isEqualTo(PACKAGE_ADDED); + assertThat(argumentIntent.getValue().getIntExtra(Intent.EXTRA_UID, -1)) .isEqualTo(PACKAGE_UID); - Truth.assertThat(argumentUser.getValue()).isEqualTo(mSpyContext.getUser()); + assertThat(argumentUser.getValue()).isEqualTo(mSpyContext.getUser()); } @Test public void testSendBroadcastForPackageDataCleared() { + mService = new AdServicesManagerService(mSpyContext); + Intent i = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED); i.setData(Uri.parse("package:" + PACKAGE_NAME)); i.putExtra(Intent.EXTRA_UID, PACKAGE_UID); @@ -121,13 +220,12 @@ public class AdServicesManagerServiceTest { Mockito.verify(mSpyContext, Mockito.times(1)) .sendBroadcastAsUser(argumentIntent.capture(), argumentUser.capture()); - Truth.assertThat(argumentIntent.getValue().getAction()) - .isEqualTo(PACKAGE_CHANGED_BROADCAST); - Truth.assertThat(argumentIntent.getValue().getData()).isEqualTo(i.getData()); - Truth.assertThat(argumentIntent.getValue().getStringExtra("action")) + assertThat(argumentIntent.getValue().getAction()).isEqualTo(PACKAGE_CHANGED_BROADCAST); + assertThat(argumentIntent.getValue().getData()).isEqualTo(i.getData()); + assertThat(argumentIntent.getValue().getStringExtra("action")) .isEqualTo(PACKAGE_DATA_CLEARED); - Truth.assertThat(argumentIntent.getValue().getIntExtra(Intent.EXTRA_UID, -1)) + assertThat(argumentIntent.getValue().getIntExtra(Intent.EXTRA_UID, -1)) .isEqualTo(PACKAGE_UID); - Truth.assertThat(argumentUser.getValue()).isEqualTo(mSpyContext.getUser()); + assertThat(argumentUser.getValue()).isEqualTo(mSpyContext.getUser()); } } diff --git a/adservices/tests/unittest/system-service/src/com/android/server/adservices/PhFlagsTest.java b/adservices/tests/unittest/system-service/src/com/android/server/adservices/PhFlagsTest.java new file mode 100644 index 0000000000..dfd8b80b0a --- /dev/null +++ b/adservices/tests/unittest/system-service/src/com/android/server/adservices/PhFlagsTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 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.adservices; + +import static com.android.server.adservices.Flags.ADSERVICES_SYSTEM_SERVICE_ENABLED; +import static com.android.server.adservices.PhFlags.KEY_ADSERVICES_SYSTEM_SERVICE_ENABLED; + +import android.provider.DeviceConfig; + +import com.android.modules.utils.testing.TestableDeviceConfig; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Rule; +import org.junit.Test; + +public class PhFlagsTest { + + @Rule + public final TestableDeviceConfig.TestableDeviceConfigRule mDeviceConfigRule = + new TestableDeviceConfig.TestableDeviceConfigRule(); + + @Test + public void testAdServicesSystemServiceEnabled() { + // Without any overriding, the value is the hard coded constant. + assertThat(FlagsFactory.getFlags().getAdServicesSystemServiceEnabled()) + .isEqualTo(ADSERVICES_SYSTEM_SERVICE_ENABLED); + + // Now overriding with the value from PH. + final boolean phOverridingValue = true; + + DeviceConfig.setProperty( + DeviceConfig.NAMESPACE_ADSERVICES, + KEY_ADSERVICES_SYSTEM_SERVICE_ENABLED, + Boolean.toString(phOverridingValue), + /* makeDefault */ false); + + Flags phFlags = FlagsFactory.getFlags(); + assertThat(phFlags.getAdServicesSystemServiceEnabled()).isEqualTo(phOverridingValue); + } +} -- cgit v1.2.3