Add a flag to control whether service error is returned to callers.
Bug: 324478256
Test: TH
Change-Id: I06e8712d45ca93408a456fe50890300744a1c7d1
diff --git a/src/com/android/ondevicepersonalization/services/Flags.java b/src/com/android/ondevicepersonalization/services/Flags.java
index cd83fbc..8e3a263 100644
--- a/src/com/android/ondevicepersonalization/services/Flags.java
+++ b/src/com/android/ondevicepersonalization/services/Flags.java
@@ -96,6 +96,11 @@
*/
int DEFAULT_BACKGROUND_JOB_SAMPLING_LOGGING_RATE = 5;
+ /**
+ * Default value for isolated service debugging flag.
+ */
+ boolean DEFAULT_ISOLATED_SERVICE_DEBUGGING_ENABLED = false;
+
String DEFAULT_CALLER_APP_ALLOW_LIST =
"android.ondevicepersonalization,"
+ "android.ondevicepersonalization.test.scenario,"
@@ -228,6 +233,10 @@
return DEFAULT_OUTPUT_DATA_ALLOW_LIST;
}
+ default boolean isIsolatedServiceDebuggingEnabled() {
+ return DEFAULT_ISOLATED_SERVICE_DEBUGGING_ENABLED;
+ }
+
/** Set all stable flags. */
default void setStableFlags() {}
diff --git a/src/com/android/ondevicepersonalization/services/PhFlags.java b/src/com/android/ondevicepersonalization/services/PhFlags.java
index 8d07e1e..b8f3e4a 100644
--- a/src/com/android/ondevicepersonalization/services/PhFlags.java
+++ b/src/com/android/ondevicepersonalization/services/PhFlags.java
@@ -79,6 +79,9 @@
public static final String KEY_IS_ART_IMAGE_LOADING_OPTIMIZATION_ENABLED =
"is_art_image_loading_optimization_enabled";
+ public static final String KEY_ISOLATED_SERVICE_DEBUGGING_ENABLED =
+ "isolated_service_debugging_enabled";
+
// OnDevicePersonalization Namespace String from DeviceConfig class
public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
@@ -243,6 +246,14 @@
}
@Override
+ public boolean isIsolatedServiceDebuggingEnabled() {
+ return DeviceConfig.getBoolean(
+ /* namespace= */ NAMESPACE_ON_DEVICE_PERSONALIZATION,
+ /* name= */ KEY_ISOLATED_SERVICE_DEBUGGING_ENABLED,
+ /* defaultValue= */ DEFAULT_ISOLATED_SERVICE_DEBUGGING_ENABLED);
+ }
+
+ @Override
public String getCallerAppAllowList() {
return DeviceConfig.getString(
/* namespace= */ NAMESPACE_ON_DEVICE_PERSONALIZATION,
diff --git a/src/com/android/ondevicepersonalization/services/util/DebugUtils.java b/src/com/android/ondevicepersonalization/services/util/DebugUtils.java
index 8b35120..331e0b4 100644
--- a/src/com/android/ondevicepersonalization/services/util/DebugUtils.java
+++ b/src/com/android/ondevicepersonalization/services/util/DebugUtils.java
@@ -25,6 +25,7 @@
import android.provider.Settings;
import com.android.ondevicepersonalization.internal.util.LoggerFactory;
+import com.android.ondevicepersonalization.services.FlagsFactory;
import com.android.ondevicepersonalization.services.OdpServiceException;
import java.util.Objects;
@@ -48,6 +49,9 @@
@NonNull ComponentName service,
@NonNull OdpServiceException e) {
try {
+ if (!FlagsFactory.getFlags().isIsolatedServiceDebuggingEnabled()) {
+ return 0;
+ }
if (isDeveloperModeEnabled(context)
&& PackageUtils.isPackageDebuggable(context, service.getPackageName())) {
if (e.getCause() != null && e.getCause() instanceof IsolatedServiceException) {
diff --git a/tests/servicetests/src/com/android/ondevicepersonalization/services/PhFlagsTest.java b/tests/servicetests/src/com/android/ondevicepersonalization/services/PhFlagsTest.java
index 57a7e8a..a2ba05e 100644
--- a/tests/servicetests/src/com/android/ondevicepersonalization/services/PhFlagsTest.java
+++ b/tests/servicetests/src/com/android/ondevicepersonalization/services/PhFlagsTest.java
@@ -39,6 +39,7 @@
import static com.android.ondevicepersonalization.services.PhFlags.KEY_EXAMPLE_STORE_FLOW_DEADLINE_SECONDS;
import static com.android.ondevicepersonalization.services.PhFlags.KEY_GLOBAL_KILL_SWITCH;
import static com.android.ondevicepersonalization.services.PhFlags.KEY_ISOLATED_SERVICE_ALLOW_LIST;
+import static com.android.ondevicepersonalization.services.PhFlags.KEY_ISOLATED_SERVICE_DEBUGGING_ENABLED;
import static com.android.ondevicepersonalization.services.PhFlags.KEY_IS_ART_IMAGE_LOADING_OPTIMIZATION_ENABLED;
import static com.android.ondevicepersonalization.services.PhFlags.KEY_ODP_BACKGROUND_JOBS_LOGGING_ENABLED;
import static com.android.ondevicepersonalization.services.PhFlags.KEY_ODP_BACKGROUND_JOB_SAMPLING_LOGGING_RATE;
@@ -390,6 +391,27 @@
}
@Test
+ public void testIsolatedServiceDebuggingEnabled() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_ON_DEVICE_PERSONALIZATION,
+ KEY_ISOLATED_SERVICE_DEBUGGING_ENABLED,
+ Boolean.toString(false),
+ /* makeDefault */ false);
+
+ assertThat(FlagsFactory.getFlags().isIsolatedServiceDebuggingEnabled())
+ .isEqualTo(false);
+
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_ON_DEVICE_PERSONALIZATION,
+ KEY_ISOLATED_SERVICE_DEBUGGING_ENABLED,
+ Boolean.toString(true),
+ /* makeDefault */ false);
+
+ assertThat(FlagsFactory.getFlags().isIsolatedServiceDebuggingEnabled())
+ .isEqualTo(true);
+ }
+
+ @Test
public void testIsArtImageLoadingOptimizationEnabled() {
assertThat(FlagsFactory.getFlags().isArtImageLoadingOptimizationEnabled())
.isEqualTo(IS_ART_IMAGE_LOADING_OPTIMIZATION_ENABLED);
diff --git a/tests/servicetests/src/com/android/ondevicepersonalization/services/util/DebugUtilsTest.java b/tests/servicetests/src/com/android/ondevicepersonalization/services/util/DebugUtilsTest.java
index 61a9272..d793fe2 100644
--- a/tests/servicetests/src/com/android/ondevicepersonalization/services/util/DebugUtilsTest.java
+++ b/tests/servicetests/src/com/android/ondevicepersonalization/services/util/DebugUtilsTest.java
@@ -19,10 +19,15 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.quality.Strictness.LENIENT;
+import android.adservices.ondevicepersonalization.Constants;
+import android.adservices.ondevicepersonalization.IsolatedServiceException;
+import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
@@ -30,6 +35,9 @@
import androidx.test.core.app.ApplicationProvider;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.ondevicepersonalization.services.Flags;
+import com.android.ondevicepersonalization.services.FlagsFactory;
+import com.android.ondevicepersonalization.services.OdpServiceException;
import org.junit.After;
import org.junit.Before;
@@ -45,6 +53,8 @@
mSession = ExtendedMockito.mockitoSession()
.mockStatic(Build.class)
.mockStatic(Settings.Global.class)
+ .mockStatic(FlagsFactory.class)
+ .mockStatic(PackageUtils.class)
.strictness(LENIENT)
.startMocking();
}
@@ -82,6 +92,63 @@
assertTrue(DebugUtils.isDeveloperModeEnabled(mContext));
}
+ @Test
+ public void testReturnsExceptionCodeIfDebuggableAndFlagEnabled() {
+ doReturn(new TestFlags(true)).when(FlagsFactory::getFlags);
+ doReturn(true).when(() -> PackageUtils.isPackageDebuggable(any(), any()));
+ enableDeveloperOptions();
+ assertEquals(42,
+ DebugUtils.getIsolatedServiceExceptionCode(
+ mContext,
+ new ComponentName("a", "b"),
+ new OdpServiceException(
+ Constants.STATUS_SERVICE_FAILED,
+ new IsolatedServiceException(42))));
+ }
+
+ @Test
+ public void testDoesNotReturnExceptionCodeIfFlagDisabled() {
+ doReturn(new TestFlags(false)).when(FlagsFactory::getFlags);
+ doReturn(true).when(() -> PackageUtils.isPackageDebuggable(any(), any()));
+ enableDeveloperOptions();
+ assertEquals(0,
+ DebugUtils.getIsolatedServiceExceptionCode(
+ mContext,
+ new ComponentName("a", "b"),
+ new OdpServiceException(
+ Constants.STATUS_SERVICE_FAILED,
+ new IsolatedServiceException(42))));
+ }
+
+ @Test
+ public void testDoesNotReturnExceptionCodeIfPackageNotDebuggable() {
+ doReturn(new TestFlags(true)).when(FlagsFactory::getFlags);
+ doReturn(false).when(() -> PackageUtils.isPackageDebuggable(any(), any()));
+ enableDeveloperOptions();
+ assertEquals(0,
+ DebugUtils.getIsolatedServiceExceptionCode(
+ mContext,
+ new ComponentName("a", "b"),
+ new OdpServiceException(
+ Constants.STATUS_SERVICE_FAILED,
+ new IsolatedServiceException(42))));
+ }
+
+ @Test
+ public void testDoesNotReturnExceptionCodeIfDeviceNotDebuggable() {
+ doReturn(new TestFlags(true)).when(FlagsFactory::getFlags);
+ doReturn(true).when(() -> PackageUtils.isPackageDebuggable(any(), any()));
+ doReturn(false).when(Build::isDebuggable);
+ disableDeveloperOptions();
+ assertEquals(0,
+ DebugUtils.getIsolatedServiceExceptionCode(
+ mContext,
+ new ComponentName("a", "b"),
+ new OdpServiceException(
+ Constants.STATUS_SERVICE_FAILED,
+ new IsolatedServiceException(42))));
+ }
+
private void enableDeveloperOptions() {
when(Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0))
@@ -93,4 +160,14 @@
mContext.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0))
.thenReturn(0);
}
+
+ class TestFlags implements Flags {
+ public boolean mIsolatedServiceDebuggingEnabled;
+ TestFlags(boolean value) {
+ mIsolatedServiceDebuggingEnabled = value;
+ }
+ @Override public boolean isIsolatedServiceDebuggingEnabled() {
+ return mIsolatedServiceDebuggingEnabled;
+ }
+ }
}