summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Giulio Fiscella <fiscella@google.com> 2022-11-21 14:56:38 +0000
committer Giulio Fiscella <fiscella@google.com> 2022-11-23 00:10:11 +0000
commit7a11a7b0cc53f930963df001d73103bde18b7ba4 (patch)
tree187d9143be8eaab5ece40df09d068563caa50797
parente0771d4a9d4d7035570473aedf986dbd81ba8da2 (diff)
Make the entry group type explicit
Bug: 254631418 Test: atest --no-bazel-mode CtsSafetyCenterTestCases Change-Id: I3980e80dcb5adb5ee945d67a05025a929d546d5a
-rw-r--r--SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java35
-rw-r--r--SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt68
-rw-r--r--SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt88
-rw-r--r--SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_collapsible_with_only_issue_only.xml13
-rw-r--r--SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_dynamic.xml15
-rw-r--r--SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_static.xml14
-rw-r--r--SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_rigid_with_only_issue_only.xml13
-rw-r--r--SafetyCenter/Config/tests/res/raw-v34/config_valid.xml63
-rw-r--r--framework-s/api/system-current.txt1
-rw-r--r--framework-s/java/android/safetycenter/config/SafetySource.java35
-rw-r--r--framework-s/java/android/safetycenter/config/SafetySourcesGroup.java119
-rw-r--r--framework-s/java/android/safetycenter/config/safety_center_config-v34.xsd17
-rw-r--r--tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt6
-rw-r--r--tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetyCenterConfigTest.kt26
-rw-r--r--tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourcesGroupTest.kt407
-rw-r--r--tests/cts/safetycenter/src/android/safetycenter/cts/testing/SafetyCenterCtsConfigs.kt17
16 files changed, 775 insertions, 162 deletions
diff --git a/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java b/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java
index adb7260ba..504fcfc3c 100644
--- a/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java
+++ b/SafetyCenter/Config/java/com/android/safetycenter/config/SafetyCenterConfigParser.java
@@ -60,6 +60,7 @@ public final class SafetyCenterConfigParser {
private static final String ATTR_SAFETY_SOURCES_GROUP_TITLE = "title";
private static final String ATTR_SAFETY_SOURCES_GROUP_SUMMARY = "summary";
private static final String ATTR_SAFETY_SOURCES_GROUP_STATELESS_ICON_TYPE = "statelessIconType";
+ private static final String ATTR_SAFETY_SOURCES_GROUP_TYPE = "type";
private static final String ATTR_SAFETY_SOURCE_ID = "id";
private static final String ATTR_SAFETY_SOURCE_PACKAGE_NAME = "packageName";
private static final String ATTR_SAFETY_SOURCE_TITLE = "title";
@@ -77,6 +78,9 @@ public final class SafetyCenterConfigParser {
private static final String ATTR_SAFETY_SOURCE_DEDUPLICATION_GROUP = "deduplicationGroup";
private static final String ENUM_STATELESS_ICON_TYPE_NONE = "none";
private static final String ENUM_STATELESS_ICON_TYPE_PRIVACY = "privacy";
+ private static final String ENUM_GROUP_TYPE_COLLAPSIBLE = "collapsible";
+ private static final String ENUM_GROUP_TYPE_HIDDEN = "hidden";
+ private static final String ENUM_GROUP_TYPE_RIGID = "rigid";
private static final String ENUM_PROFILE_PRIMARY = "primary_profile_only";
private static final String ENUM_PROFILE_ALL = "all_profiles";
private static final String ENUM_INITIAL_DISPLAY_STATE_ENABLED = "enabled";
@@ -187,6 +191,18 @@ public final class SafetyCenterConfigParser {
parser.getAttributeName(i),
resources));
break;
+ case ATTR_SAFETY_SOURCES_GROUP_TYPE:
+ if (SdkLevel.isAtLeastU()) {
+ builder.setType(
+ parseGroupType(
+ parser.getAttributeValue(i),
+ name,
+ parser.getAttributeName(i),
+ resources));
+ } else {
+ throw attributeUnexpected(name, parser.getAttributeName(i));
+ }
+ break;
default:
throw attributeUnexpected(name, parser.getAttributeName(i));
}
@@ -529,6 +545,25 @@ public final class SafetyCenterConfigParser {
}
}
+ private static int parseGroupType(
+ @NonNull String valueString,
+ @NonNull String parent,
+ @NonNull String name,
+ @NonNull Resources resources)
+ throws ParseException {
+ String valueToParse = getValueToParse(valueString, parent, name, resources);
+ switch (valueToParse) {
+ case ENUM_GROUP_TYPE_COLLAPSIBLE:
+ return SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE;
+ case ENUM_GROUP_TYPE_RIGID:
+ return SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID;
+ case ENUM_GROUP_TYPE_HIDDEN:
+ return SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN;
+ default:
+ throw attributeInvalid(valueToParse, parent, name);
+ }
+ }
+
private static int parseProfile(
@NonNull String valueString,
@NonNull String parent,
diff --git a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt
index 107d6e35a..3d4ce37d9 100644
--- a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt
+++ b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigInvalidTest.kt
@@ -17,8 +17,6 @@
package com.android.safetycenter.config
import android.content.Context
-import android.os.Build
-import androidx.annotation.RequiresApi
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import com.android.modules.utils.build.SdkLevel
import com.android.safetycenter.config.tests.R
@@ -36,7 +34,8 @@ class ParserConfigInvalidTest {
private val testName: String,
val configResourceId: Int,
val errorMessage: String,
- val causeErrorMessage: String?
+ val causeErrorMessage: String?,
+ val includeCondition: Boolean = true
) {
override fun toString() = testName
}
@@ -62,28 +61,6 @@ class ParserConfigInvalidTest {
@JvmStatic
@Parameterized.Parameters(name = "{0}")
fun parameters() =
- if (SdkLevel.isAtLeastU()) {
- parametersUpsideDownCake()
- } else {
- parametersTiramisu()
- }
-
- @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
- fun parametersUpsideDownCake(): Array<Params> =
- parametersTiramisu() +
- arrayOf(
- Params(
- "ConfigStaticSafetySourceWithNotifications",
- R.raw.config_static_safety_source_with_notifications,
- "Element static-safety-source invalid",
- "Prohibited attribute notificationsAllowed present"),
- Params(
- "ConfigStaticSafetySourceWithDeduplicationGroups",
- R.raw.config_static_safety_source_with_deduplication_groups,
- "Element static-safety-source invalid",
- "Prohibited attribute deduplicationGroup present"))
-
- fun parametersTiramisu(): Array<Params> =
arrayOf(
Params(
"ConfigDynamicSafetySourceAllDisabledNoWork",
@@ -252,6 +229,13 @@ class ParserConfigInvalidTest {
"Element safety-sources-config missing",
null),
Params(
+ "ConfigSafetySourcesGroupCollapsibleWithOnlyIssueOnly",
+ R.raw.config_safety_sources_group_collapsible_with_only_issue_only,
+ "Element safety-sources-group invalid",
+ "Safety sources groups containing only sources of type issue-only must be of " +
+ "type hidden",
+ SdkLevel.isAtLeastU()),
+ Params(
"ConfigSafetySourcesGroupDuplicateId",
R.raw.config_safety_sources_group_duplicate_id,
"Element safety-sources-config invalid",
@@ -262,6 +246,20 @@ class ParserConfigInvalidTest {
"Element safety-sources-group invalid",
"Safety sources group empty"),
Params(
+ "ConfigSafetySourcesGroupHiddenWithOnlyDynamic",
+ R.raw.config_safety_sources_group_hidden_with_only_dynamic,
+ "Element safety-sources-group invalid",
+ "Safety sources groups of type hidden can only contain sources of type " +
+ "issue-only",
+ SdkLevel.isAtLeastU()),
+ Params(
+ "ConfigSafetySourcesGroupHiddenWithOnlyStatic",
+ R.raw.config_safety_sources_group_hidden_with_only_static,
+ "Element safety-sources-group invalid",
+ "Safety sources groups of type hidden can only contain sources of type " +
+ "issue-only",
+ SdkLevel.isAtLeastU()),
+ Params(
"ConfigSafetySourcesGroupInvalidIcon",
R.raw.config_safety_sources_group_invalid_icon,
"Attribute value \"invalid\" in safety-sources-group.statelessIconType invalid",
@@ -277,6 +275,13 @@ class ParserConfigInvalidTest {
"Element safety-sources-group invalid",
"Required attribute title missing"),
Params(
+ "ConfigSafetySourcesGroupRigidWithOnlyIssueOnly",
+ R.raw.config_safety_sources_group_rigid_with_only_issue_only,
+ "Element safety-sources-group invalid",
+ "Safety sources groups containing only sources of type issue-only must be of " +
+ "type hidden",
+ SdkLevel.isAtLeastU()),
+ Params(
"ConfigStaticSafetySourceDuplicateKey",
R.raw.config_static_safety_source_duplicate_key,
"Element safety-sources-config invalid",
@@ -307,6 +312,12 @@ class ParserConfigInvalidTest {
"Element static-safety-source invalid",
"Required attribute title missing"),
Params(
+ "ConfigStaticSafetySourceWithDeduplicationGroups",
+ R.raw.config_static_safety_source_with_deduplication_groups,
+ "Element static-safety-source invalid",
+ "Prohibited attribute deduplicationGroup present",
+ SdkLevel.isAtLeastU()),
+ Params(
"ConfigStaticSafetySourceWithDisplay",
R.raw.config_static_safety_source_with_display,
"Element static-safety-source invalid",
@@ -317,6 +328,12 @@ class ParserConfigInvalidTest {
"Element static-safety-source invalid",
"Prohibited attribute loggingAllowed present"),
Params(
+ "ConfigStaticSafetySourceWithNotifications",
+ R.raw.config_static_safety_source_with_notifications,
+ "Element static-safety-source invalid",
+ "Prohibited attribute notificationsAllowed present",
+ SdkLevel.isAtLeastU()),
+ Params(
"ConfigStaticSafetySourceWithPackage",
R.raw.config_static_safety_source_with_package,
"Element static-safety-source invalid",
@@ -372,5 +389,6 @@ class ParserConfigInvalidTest {
"Resource name \"@com.android.safetycenter.config.tests:string/missing\" in " +
"safety-sources-group.title missing or invalid",
null))
+ .filter { it.includeCondition }
}
}
diff --git a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt
index 34d91e6bf..bd5137cf4 100644
--- a/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt
+++ b/SafetyCenter/Config/tests/java/com/android/safetycenter/config/ParserConfigValidTest.kt
@@ -200,6 +200,94 @@ class ParserConfigValidTest {
.setProfile(SafetySource.PROFILE_PRIMARY)
.build())
.build())
+ .apply {
+ if (SdkLevel.isAtLeastU()) {
+ addSafetySourcesGroup(
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ .setId("collapsible_barebone")
+ .setTitleResId(R.string.reference)
+ .addSafetySource(
+ SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_STATIC)
+ .setId("collapsible_barebone_source")
+ .setTitleResId(R.string.reference)
+ .setIntentAction("intent")
+ .setProfile(SafetySource.PROFILE_PRIMARY)
+ .build())
+ .build())
+ addSafetySourcesGroup(
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ .setId("collapsible_all_optional")
+ .setTitleResId(R.string.reference)
+ .setSummaryResId(R.string.reference)
+ .setStatelessIconType(
+ SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(
+ SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_STATIC)
+ .setId("collapsible_all_optional_source")
+ .setTitleResId(R.string.reference)
+ .setIntentAction("intent")
+ .setProfile(SafetySource.PROFILE_PRIMARY)
+ .build())
+ .build())
+ addSafetySourcesGroup(
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ .setId("rigid_barebone")
+ .setTitleResId(R.string.reference)
+ .addSafetySource(
+ SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_STATIC)
+ .setId("rigid_barebone_source")
+ .setTitleResId(R.string.reference)
+ .setIntentAction("intent")
+ .setProfile(SafetySource.PROFILE_PRIMARY)
+ .build())
+ .build())
+ addSafetySourcesGroup(
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ .setId("rigid_all_optional")
+ .setTitleResId(R.string.reference)
+ .setSummaryResId(R.string.reference)
+ .setStatelessIconType(
+ SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(
+ SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_STATIC)
+ .setId("rigid_all_optional_source")
+ .setTitleResId(R.string.reference)
+ .setIntentAction("intent")
+ .setProfile(SafetySource.PROFILE_PRIMARY)
+ .build())
+ .build())
+ addSafetySourcesGroup(
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ .setId("hidden_barebone")
+ .addSafetySource(
+ SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_ISSUE_ONLY)
+ .setId("hidden_barebone_source")
+ .setPackageName("package")
+ .setProfile(SafetySource.PROFILE_PRIMARY)
+ .build())
+ .build())
+ addSafetySourcesGroup(
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ .setId("hidden_all_optional")
+ .setTitleResId(R.string.reference)
+ .setSummaryResId(R.string.reference)
+ .setStatelessIconType(
+ SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(
+ SafetySource.Builder(SafetySource.SAFETY_SOURCE_TYPE_ISSUE_ONLY)
+ .setId("hidden_all_optional_source")
+ .setPackageName("package")
+ .setProfile(SafetySource.PROFILE_PRIMARY)
+ .build())
+ .build())
+ }
+ }
.build()
assertThat(actual).isEqualTo(expected)
}
diff --git a/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_collapsible_with_only_issue_only.xml b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_collapsible_with_only_issue_only.xml
new file mode 100644
index 000000000..effe379f4
--- /dev/null
+++ b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_collapsible_with_only_issue_only.xml
@@ -0,0 +1,13 @@
+<safety-center-config>
+ <safety-sources-config>
+ <safety-sources-group
+ type="collapsible"
+ id="id"
+ title="@com.android.safetycenter.config.tests:string/reference">
+ <issue-only-safety-source
+ id="id"
+ packageName="package"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ </safety-sources-config>
+</safety-center-config>
diff --git a/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_dynamic.xml b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_dynamic.xml
new file mode 100644
index 000000000..4be2c75ff
--- /dev/null
+++ b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_dynamic.xml
@@ -0,0 +1,15 @@
+<safety-center-config>
+ <safety-sources-config>
+ <safety-sources-group
+ type="hidden"
+ id="id">
+ <dynamic-safety-source
+ id="id"
+ packageName="package"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ summary="@com.android.safetycenter.config.tests:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ </safety-sources-config>
+</safety-center-config>
diff --git a/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_static.xml b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_static.xml
new file mode 100644
index 000000000..65f9f0ac9
--- /dev/null
+++ b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_hidden_with_only_static.xml
@@ -0,0 +1,14 @@
+<safety-center-config>
+ <safety-sources-config>
+ <safety-sources-group
+ type="hidden"
+ id="id">
+ <static-safety-source
+ id="id"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ summary="@com.android.safetycenter.config.tests:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ </safety-sources-config>
+</safety-center-config>
diff --git a/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_rigid_with_only_issue_only.xml b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_rigid_with_only_issue_only.xml
new file mode 100644
index 000000000..1d95a55ec
--- /dev/null
+++ b/SafetyCenter/Config/tests/res/raw-v34/config_safety_sources_group_rigid_with_only_issue_only.xml
@@ -0,0 +1,13 @@
+<safety-center-config>
+ <safety-sources-config>
+ <safety-sources-group
+ type="rigid"
+ id="id"
+ title="@com.android.safetycenter.config.tests:string/reference">
+ <issue-only-safety-source
+ id="id"
+ packageName="package"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ </safety-sources-config>
+</safety-center-config>
diff --git a/SafetyCenter/Config/tests/res/raw-v34/config_valid.xml b/SafetyCenter/Config/tests/res/raw-v34/config_valid.xml
index eec65ec7e..5b88dd5e3 100644
--- a/SafetyCenter/Config/tests/res/raw-v34/config_valid.xml
+++ b/SafetyCenter/Config/tests/res/raw-v34/config_valid.xml
@@ -118,5 +118,68 @@
intentAction="intent"
profile="primary_profile_only"/>
</safety-sources-group>
+ <safety-sources-group
+ type="collapsible"
+ id="collapsible_barebone"
+ title="@com.android.safetycenter.config.tests:string/reference">
+ <static-safety-source
+ id="collapsible_barebone_source"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ <safety-sources-group
+ type="collapsible"
+ id="collapsible_all_optional"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ summary="@com.android.safetycenter.config.tests:string/reference"
+ statelessIconType="privacy">
+ <static-safety-source
+ id="collapsible_all_optional_source"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ <safety-sources-group
+ type="rigid"
+ id="rigid_barebone"
+ title="@com.android.safetycenter.config.tests:string/reference">
+ <static-safety-source
+ id="rigid_barebone_source"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ <safety-sources-group
+ type="rigid"
+ id="rigid_all_optional"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ summary="@com.android.safetycenter.config.tests:string/reference"
+ statelessIconType="privacy">
+ <static-safety-source
+ id="rigid_all_optional_source"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ intentAction="intent"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ <safety-sources-group
+ type="hidden"
+ id="hidden_barebone">
+ <issue-only-safety-source
+ id="hidden_barebone_source"
+ packageName="package"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
+ <safety-sources-group
+ type="hidden"
+ id="hidden_all_optional"
+ title="@com.android.safetycenter.config.tests:string/reference"
+ summary="@com.android.safetycenter.config.tests:string/reference"
+ statelessIconType="privacy">
+ <issue-only-safety-source
+ id="hidden_all_optional_source"
+ packageName="package"
+ profile="primary_profile_only"/>
+ </safety-sources-group>
</safety-sources-config>
</safety-center-config>
diff --git a/framework-s/api/system-current.txt b/framework-s/api/system-current.txt
index 006374367..9fda15d51 100644
--- a/framework-s/api/system-current.txt
+++ b/framework-s/api/system-current.txt
@@ -552,6 +552,7 @@ package android.safetycenter.config {
method @NonNull public android.safetycenter.config.SafetySourcesGroup.Builder setStatelessIconType(int);
method @NonNull public android.safetycenter.config.SafetySourcesGroup.Builder setSummaryResId(@StringRes int);
method @NonNull public android.safetycenter.config.SafetySourcesGroup.Builder setTitleResId(@StringRes int);
+ method @NonNull public android.safetycenter.config.SafetySourcesGroup.Builder setType(int);
}
}
diff --git a/framework-s/java/android/safetycenter/config/SafetySource.java b/framework-s/java/android/safetycenter/config/SafetySource.java
index d3d9cb9f7..0066b62f8 100644
--- a/framework-s/java/android/safetycenter/config/SafetySource.java
+++ b/framework-s/java/android/safetycenter/config/SafetySource.java
@@ -817,19 +817,22 @@ public final class SafetySource implements Parcelable {
*/
@NonNull
public SafetySource build() {
- if (mType != SAFETY_SOURCE_TYPE_STATIC
- && mType != SAFETY_SOURCE_TYPE_DYNAMIC
- && mType != SAFETY_SOURCE_TYPE_ISSUE_ONLY) {
+ int type = mType;
+ if (type != SAFETY_SOURCE_TYPE_STATIC
+ && type != SAFETY_SOURCE_TYPE_DYNAMIC
+ && type != SAFETY_SOURCE_TYPE_ISSUE_ONLY) {
throw new IllegalStateException("Unexpected type");
}
- boolean isStatic = mType == SAFETY_SOURCE_TYPE_STATIC;
- boolean isDynamic = mType == SAFETY_SOURCE_TYPE_DYNAMIC;
- boolean isIssueOnly = mType == SAFETY_SOURCE_TYPE_ISSUE_ONLY;
+ boolean isStatic = type == SAFETY_SOURCE_TYPE_STATIC;
+ boolean isDynamic = type == SAFETY_SOURCE_TYPE_DYNAMIC;
+ boolean isIssueOnly = type == SAFETY_SOURCE_TYPE_ISSUE_ONLY;
- BuilderUtils.validateAttribute(mId, "id", true, false);
+ String id = mId;
+ BuilderUtils.validateAttribute(id, "id", true, false);
+ String packageName = mPackageName;
BuilderUtils.validateAttribute(
- mPackageName, "packageName", isDynamic || isIssueOnly, isStatic);
+ packageName, "packageName", isDynamic || isIssueOnly, isStatic);
int initialDisplayState =
BuilderUtils.validateIntDef(
@@ -877,8 +880,9 @@ public final class SafetySource implements Parcelable {
BuilderUtils.validateResId(
mSummaryResId, "summary", isDynamicNotHidden, isIssueOnly);
+ String intentAction = mIntentAction;
BuilderUtils.validateAttribute(
- mIntentAction,
+ intentAction,
"intentAction",
(isDynamic && isEnabled) || isStatic,
isIssueOnly);
@@ -903,6 +907,7 @@ public final class SafetySource implements Parcelable {
isStatic,
false);
+ String deduplicationGroup = mDeduplicationGroup;
boolean notificationsAllowed = false;
if (SdkLevel.isAtLeastU()) {
notificationsAllowed =
@@ -914,17 +919,17 @@ public final class SafetySource implements Parcelable {
false);
BuilderUtils.validateAttribute(
- mDeduplicationGroup, "deduplicationGroup", false, isStatic);
+ deduplicationGroup, "deduplicationGroup", false, isStatic);
}
return new SafetySource(
- mType,
- mId,
- mPackageName,
+ type,
+ id,
+ packageName,
titleResId,
titleForWorkResId,
summaryResId,
- mIntentAction,
+ intentAction,
profile,
initialDisplayState,
maxSeverityLevel,
@@ -932,7 +937,7 @@ public final class SafetySource implements Parcelable {
loggingAllowed,
refreshOnPageOpenAllowed,
notificationsAllowed,
- mDeduplicationGroup);
+ deduplicationGroup);
}
}
}
diff --git a/framework-s/java/android/safetycenter/config/SafetySourcesGroup.java b/framework-s/java/android/safetycenter/config/SafetySourcesGroup.java
index 2868ee7ec..9e53feac2 100644
--- a/framework-s/java/android/safetycenter/config/SafetySourcesGroup.java
+++ b/framework-s/java/android/safetycenter/config/SafetySourcesGroup.java
@@ -17,6 +17,7 @@
package android.safetycenter.config;
import static android.os.Build.VERSION_CODES.TIRAMISU;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
import static java.util.Collections.unmodifiableList;
import static java.util.Objects.requireNonNull;
@@ -32,6 +33,8 @@ import android.os.Parcelable;
import androidx.annotation.RequiresApi;
+import com.android.modules.utils.build.SdkLevel;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -116,6 +119,9 @@ public final class SafetySourcesGroup implements Parcelable {
for (int i = 0; i < safetySources.size(); i++) {
builder.addSafetySource(safetySources.get(i));
}
+ if (SdkLevel.isAtLeastU()) {
+ builder.setType(in.readInt());
+ }
return builder.build();
}
@@ -125,6 +131,7 @@ public final class SafetySourcesGroup implements Parcelable {
}
};
+ @SafetySourceGroupType private final int mType;
@NonNull private final String mId;
@StringRes private final int mTitleResId;
@StringRes private final int mSummaryResId;
@@ -132,11 +139,13 @@ public final class SafetySourcesGroup implements Parcelable {
@NonNull private final List<SafetySource> mSafetySources;
private SafetySourcesGroup(
+ @SafetySourceGroupType int type,
@NonNull String id,
@StringRes int titleResId,
@StringRes int summaryResId,
@StatelessIconType int statelessIconType,
@NonNull List<SafetySource> safetySources) {
+ mType = type;
mId = id;
mTitleResId = titleResId;
mSummaryResId = summaryResId;
@@ -144,23 +153,10 @@ public final class SafetySourcesGroup implements Parcelable {
mSafetySources = safetySources;
}
- /**
- * Returns the type of this safety sources group.
- *
- * <p>The type is inferred according to the state of certain fields. If no title is provided
- * when building the group, the group is of type hidden. If a title is provided but no summary
- * or stateless icon are provided when building the group, the group is of type rigid.
- * Otherwise, the group is of type collapsible.
- */
+ /** Returns the type of this safety sources group. */
@SafetySourceGroupType
public int getType() {
- if (mTitleResId == Resources.ID_NULL) {
- return SAFETY_SOURCES_GROUP_TYPE_HIDDEN;
- }
- if (mSummaryResId != Resources.ID_NULL || mStatelessIconType != STATELESS_ICON_TYPE_NONE) {
- return SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE;
- }
- return SAFETY_SOURCES_GROUP_TYPE_RIGID;
+ return mType;
}
/**
@@ -224,7 +220,8 @@ public final class SafetySourcesGroup implements Parcelable {
if (this == o) return true;
if (!(o instanceof SafetySourcesGroup)) return false;
SafetySourcesGroup that = (SafetySourcesGroup) o;
- return Objects.equals(mId, that.mId)
+ return mType == that.mType
+ && Objects.equals(mId, that.mId)
&& mTitleResId == that.mTitleResId
&& mSummaryResId == that.mSummaryResId
&& mStatelessIconType == that.mStatelessIconType
@@ -233,13 +230,16 @@ public final class SafetySourcesGroup implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mId, mTitleResId, mSummaryResId, mStatelessIconType, mSafetySources);
+ return Objects.hash(
+ mType, mId, mTitleResId, mSummaryResId, mStatelessIconType, mSafetySources);
}
@Override
public String toString() {
return "SafetySourcesGroup{"
- + "mId="
+ + "mType="
+ + mType
+ + ", mId="
+ mId
+ ", mTitleResId="
+ mTitleResId
@@ -264,6 +264,9 @@ public final class SafetySourcesGroup implements Parcelable {
dest.writeInt(mSummaryResId);
dest.writeInt(mStatelessIconType);
dest.writeTypedList(mSafetySources);
+ if (SdkLevel.isAtLeastU()) {
+ dest.writeInt(mType);
+ }
}
/** Builder class for {@link SafetySourcesGroup}. */
@@ -271,6 +274,7 @@ public final class SafetySourcesGroup implements Parcelable {
private final List<SafetySource> mSafetySources = new ArrayList<>();
+ @Nullable @SafetySourceGroupType private Integer mType;
@Nullable private String mId;
@Nullable @StringRes private Integer mTitleResId;
@Nullable @StringRes private Integer mSummaryResId;
@@ -280,6 +284,22 @@ public final class SafetySourcesGroup implements Parcelable {
public Builder() {}
/**
+ * Sets the type of this safety sources group.
+ *
+ * <p>If the type is not explicitly set, the type is inferred according to the state of
+ * certain fields. If no title is provided when building the group, the group is of type
+ * hidden. If a title is provided but no summary or stateless icon are provided when
+ * building the group, the group is of type stateless. Otherwise, the group is of type
+ * stateful.
+ */
+ @NonNull
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ public Builder setType(@StatelessIconType int type) {
+ mType = type;
+ return this;
+ }
+
+ /**
* Sets the id of this safety sources group.
*
* <p>The id must be unique among safety sources groups in a Safety Center configuration.
@@ -351,22 +371,16 @@ public final class SafetySourcesGroup implements Parcelable {
*/
@NonNull
public SafetySourcesGroup build() {
- BuilderUtils.validateAttribute(mId, "id", true, false);
+ String id = mId;
+ BuilderUtils.validateAttribute(id, "id", true, false);
+
List<SafetySource> safetySources = unmodifiableList(new ArrayList<>(mSafetySources));
if (safetySources.isEmpty()) {
throw new IllegalStateException("Safety sources group empty");
}
- boolean titleRequired = false;
- int safetySourcesSize = safetySources.size();
- for (int i = 0; i < safetySourcesSize; i++) {
- int type = safetySources.get(i).getType();
- if (type != SafetySource.SAFETY_SOURCE_TYPE_ISSUE_ONLY) {
- titleRequired = true;
- break;
- }
- }
- int titleResId = BuilderUtils.validateResId(mTitleResId, "title", titleRequired, false);
+
int summaryResId = BuilderUtils.validateResId(mSummaryResId, "summary", false, false);
+
int statelessIconType =
BuilderUtils.validateIntDef(
mStatelessIconType,
@@ -376,8 +390,53 @@ public final class SafetySourcesGroup implements Parcelable {
STATELESS_ICON_TYPE_NONE,
STATELESS_ICON_TYPE_NONE,
STATELESS_ICON_TYPE_PRIVACY);
+
+ boolean hasOnlyIssueOnlySources = true;
+ int safetySourcesSize = safetySources.size();
+ for (int i = 0; i < safetySourcesSize; i++) {
+ int type = safetySources.get(i).getType();
+ if (type != SafetySource.SAFETY_SOURCE_TYPE_ISSUE_ONLY) {
+ hasOnlyIssueOnlySources = false;
+ break;
+ }
+ }
+
+ int inferredGroupType = SAFETY_SOURCES_GROUP_TYPE_RIGID;
+ if (hasOnlyIssueOnlySources) {
+ inferredGroupType = SAFETY_SOURCES_GROUP_TYPE_HIDDEN;
+ } else if (summaryResId != Resources.ID_NULL
+ || statelessIconType != Resources.ID_NULL) {
+ inferredGroupType = SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE;
+ }
+ int type =
+ BuilderUtils.validateIntDef(
+ mType,
+ "type",
+ false,
+ false,
+ inferredGroupType,
+ SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE,
+ SAFETY_SOURCES_GROUP_TYPE_RIGID,
+ SAFETY_SOURCES_GROUP_TYPE_HIDDEN);
+ if (type == SAFETY_SOURCES_GROUP_TYPE_HIDDEN && !hasOnlyIssueOnlySources) {
+ throw new IllegalStateException(
+ "Safety sources groups of type hidden can only contain sources of type "
+ + "issue-only");
+ }
+ if (type != SAFETY_SOURCES_GROUP_TYPE_HIDDEN && hasOnlyIssueOnlySources) {
+ throw new IllegalStateException(
+ "Safety sources groups containing only sources of type issue-only must be "
+ + "of type hidden");
+ }
+
+ boolean isCollapsible = type == SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE;
+ boolean isRigid = type == SAFETY_SOURCES_GROUP_TYPE_RIGID;
+ int titleResId =
+ BuilderUtils.validateResId(
+ mTitleResId, "title", isCollapsible || isCollapsible, false);
+
return new SafetySourcesGroup(
- mId, titleResId, summaryResId, statelessIconType, safetySources);
+ type, id, titleResId, summaryResId, statelessIconType, safetySources);
}
}
}
diff --git a/framework-s/java/android/safetycenter/config/safety_center_config-v34.xsd b/framework-s/java/android/safetycenter/config/safety_center_config-v34.xsd
index 75b31c166..492cff9ef 100644
--- a/framework-s/java/android/safetycenter/config/safety_center_config-v34.xsd
+++ b/framework-s/java/android/safetycenter/config/safety_center_config-v34.xsd
@@ -47,6 +47,8 @@
<xsd:attribute name="summary" type="runtimeStringResourceName"/>
<xsd:attribute name="statelessIconType" type="statelessIconTypeOrStringResourceName"
default="none"/>
+ <!-- type is inferred from other attributes and the group content if omitted -->
+ <xsd:attribute name="type" type="groupTypeOrStringResourceName"/>
</xsd:complexType>
<xsd:complexType name="dynamic-safety-source">
@@ -166,6 +168,21 @@
</xsd:restriction>
</xsd:simpleType>
+ <xsd:simpleType name="groupTypeOrStringResourceName">
+ <!-- String resource names will be resolved only once at parse time. -->
+ <!-- Locale changes and device config changes will be ignored. -->
+ <!-- The value of the string resource must be of type groupType. -->
+ <xsd:union memberTypes="stringResourceName groupType"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="groupType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="collapsible"/>
+ <xsd:enumeration value="rigid"/>
+ <xsd:enumeration value="hidden"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
<xsd:simpleType name="runtimeStringResourceName">
<!-- String resource names will be resolved at runtime whenever the string value is used. -->
<xsd:union memberTypes="stringResourceName"/>
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
index f833ffc98..bdbde0f9d 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
+++ b/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
@@ -546,11 +546,9 @@ class SafetyCenterManagerTest {
safetyCenterCtsData.safetyCenterStatusCritical(6),
listOf(
safetyCenterCtsData.safetyCenterIssueCritical(DYNAMIC_BAREBONE_ID),
- safetyCenterCtsData.safetyCenterIssueCritical(
- ISSUE_ONLY_BAREBONE_ID, attributionTitle = null),
+ safetyCenterCtsData.safetyCenterIssueCritical(ISSUE_ONLY_BAREBONE_ID),
safetyCenterCtsData.safetyCenterIssueRecommendation(DYNAMIC_DISABLED_ID),
- safetyCenterCtsData.safetyCenterIssueRecommendation(
- ISSUE_ONLY_ALL_OPTIONAL_ID, attributionTitle = null),
+ safetyCenterCtsData.safetyCenterIssueRecommendation(ISSUE_ONLY_ALL_OPTIONAL_ID),
safetyCenterCtsData.safetyCenterIssueInformation(DYNAMIC_IN_RIGID_ID),
safetyCenterCtsData.safetyCenterIssueInformation(ISSUE_ONLY_IN_RIGID_ID)),
listOf(
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetyCenterConfigTest.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetyCenterConfigTest.kt
index 73aee4dff..7b0a35311 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetyCenterConfigTest.kt
+++ b/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetyCenterConfigTest.kt
@@ -32,7 +32,8 @@ class SafetyCenterConfigTest {
@Test
fun getSafetySourcesGroups_returnsSafetySourcesGroups() {
assertThat(BASE.safetySourcesGroups)
- .containsExactly(SafetySourcesGroupTest.RIGID, SafetySourcesGroupTest.HIDDEN)
+ .containsExactly(
+ SafetySourcesGroupTest.RIGID_INFERRED, SafetySourcesGroupTest.HIDDEN_INFERRED)
.inOrder()
}
@@ -41,7 +42,7 @@ class SafetyCenterConfigTest {
val sourcesGroups = BASE.safetySourcesGroups
assertFailsWith(UnsupportedOperationException::class) {
- sourcesGroups.add(SafetySourcesGroupTest.COLLAPSIBLE_WITH_SUMMARY)
+ sourcesGroups.add(SafetySourcesGroupTest.COLLAPSIBLE_INFERRED_WITH_SUMMARY)
}
}
@@ -49,15 +50,16 @@ class SafetyCenterConfigTest {
fun builder_addSafetySourcesGroup_doesNotMutatePreviouslyBuiltInstance() {
val safetyCenterConfigBuilder =
SafetyCenterConfig.Builder()
- .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID)
- .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID_INFERRED)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN_INFERRED)
val sourceGroups = safetyCenterConfigBuilder.build().safetySourcesGroups
safetyCenterConfigBuilder.addSafetySourcesGroup(
- SafetySourcesGroupTest.COLLAPSIBLE_WITH_SUMMARY)
+ SafetySourcesGroupTest.COLLAPSIBLE_INFERRED_WITH_SUMMARY)
assertThat(sourceGroups)
- .containsExactly(SafetySourcesGroupTest.RIGID, SafetySourcesGroupTest.HIDDEN)
+ .containsExactly(
+ SafetySourcesGroupTest.RIGID_INFERRED, SafetySourcesGroupTest.HIDDEN_INFERRED)
.inOrder()
}
@@ -77,13 +79,13 @@ class SafetyCenterConfigTest {
.addEqualityGroup(
BASE,
SafetyCenterConfig.Builder()
- .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID)
- .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID_INFERRED)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN_INFERRED)
.build())
.addEqualityGroup(
SafetyCenterConfig.Builder()
- .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN)
- .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN_INFERRED)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID_INFERRED)
.build())
.test()
}
@@ -91,8 +93,8 @@ class SafetyCenterConfigTest {
companion object {
private val BASE =
SafetyCenterConfig.Builder()
- .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID)
- .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.RIGID_INFERRED)
+ .addSafetySourcesGroup(SafetySourcesGroupTest.HIDDEN_INFERRED)
.build()
}
}
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourcesGroupTest.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourcesGroupTest.kt
index f742b5d28..d241e9f4b 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourcesGroupTest.kt
+++ b/tests/cts/safetycenter/src/android/safetycenter/cts/config/SafetySourcesGroupTest.kt
@@ -17,9 +17,13 @@
package android.safetycenter.cts.config
import android.content.res.Resources
+import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE
import android.safetycenter.config.SafetySourcesGroup
+import androidx.annotation.RequiresApi
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.truth.os.ParcelableSubject.assertThat
+import androidx.test.filters.SdkSuppress
+import com.android.modules.utils.build.SdkLevel
import com.android.permission.testing.EqualsHashCodeToStringTester
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertFailsWith
@@ -32,78 +36,156 @@ class SafetySourcesGroupTest {
@Test
fun getType_returnsType() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.type)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.type)
.isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
- assertThat(COLLAPSIBLE_WITH_ICON.type)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.type)
.isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
- assertThat(COLLAPSIBLE_WITH_BOTH.type)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.type)
.isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
- assertThat(RIGID.type).isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
- assertThat(HIDDEN.type).isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ assertThat(RIGID_INFERRED.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ assertThat(HIDDEN_INFERRED.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ assertThat(RIGID_BAREBONE.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ assertThat(RIGID_ALL_OPTIONAL.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ assertThat(HIDDEN_BAREBONE.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ assertThat(HIDDEN_ALL_OPTIONAL.type)
+ .isEqualTo(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ }
}
@Test
fun getId_returnsId() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.id).isEqualTo(COLLAPSIBLE_WITH_SUMMARY_ID)
- assertThat(COLLAPSIBLE_WITH_ICON.id).isEqualTo(COLLAPSIBLE_WITH_ICON_ID)
- assertThat(COLLAPSIBLE_WITH_BOTH.id).isEqualTo(COLLAPSIBLE_WITH_BOTH_ID)
- assertThat(RIGID.id).isEqualTo(RIGID_ID)
- assertThat(HIDDEN.id).isEqualTo(HIDDEN_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.id)
+ .isEqualTo(COLLAPSIBLE_INFERRED_WITH_SUMMARY_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.id).isEqualTo(COLLAPSIBLE_INFERRED_WITH_ICON_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.id).isEqualTo(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
+ assertThat(RIGID_INFERRED.id).isEqualTo(RIGID_INFERRED_ID)
+ assertThat(HIDDEN_INFERRED.id).isEqualTo(HIDDEN_INFERRED_ID)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.id).isEqualTo(COLLAPSIBLE_BAREBONE_ID)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.id).isEqualTo(COLLAPSIBLE_ALL_OPTIONAL_ID)
+ assertThat(RIGID_BAREBONE.id).isEqualTo(RIGID_BAREBONE_ID)
+ assertThat(RIGID_ALL_OPTIONAL.id).isEqualTo(RIGID_ALL_OPTIONAL_ID)
+ assertThat(HIDDEN_BAREBONE.id).isEqualTo(HIDDEN_BAREBONE_ID)
+ assertThat(HIDDEN_ALL_OPTIONAL.id).isEqualTo(HIDDEN_ALL_OPTIONAL_ID)
+ }
}
@Test
fun getTitleResId_returnsTitleResId() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.titleResId).isEqualTo(REFERENCE_RES_ID)
- assertThat(COLLAPSIBLE_WITH_ICON.titleResId).isEqualTo(REFERENCE_RES_ID)
- assertThat(COLLAPSIBLE_WITH_BOTH.titleResId).isEqualTo(REFERENCE_RES_ID)
- assertThat(RIGID.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(RIGID_INFERRED.titleResId).isEqualTo(REFERENCE_RES_ID)
// This is not an enforced invariant, titleResId should just be ignored for hidden groups
- assertThat(HIDDEN.titleResId).isEqualTo(Resources.ID_NULL)
+ assertThat(HIDDEN_INFERRED.titleResId).isEqualTo(Resources.ID_NULL)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(RIGID_BAREBONE.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(RIGID_ALL_OPTIONAL.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(HIDDEN_BAREBONE.titleResId).isEqualTo(Resources.ID_NULL)
+ assertThat(HIDDEN_ALL_OPTIONAL.titleResId).isEqualTo(REFERENCE_RES_ID)
+ }
}
@Test
fun getSummaryResId_returnsSummaryResId() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.summaryResId).isEqualTo(REFERENCE_RES_ID)
- assertThat(COLLAPSIBLE_WITH_ICON.summaryResId).isEqualTo(Resources.ID_NULL)
- assertThat(COLLAPSIBLE_WITH_BOTH.summaryResId).isEqualTo(REFERENCE_RES_ID)
- assertThat(RIGID.summaryResId).isEqualTo(Resources.ID_NULL)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.summaryResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.summaryResId).isEqualTo(Resources.ID_NULL)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.summaryResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(RIGID_INFERRED.summaryResId).isEqualTo(Resources.ID_NULL)
// This is not an enforced invariant, summaryResId should just be ignored for hidden groups
- assertThat(HIDDEN.summaryResId).isEqualTo(Resources.ID_NULL)
+ assertThat(HIDDEN_INFERRED.summaryResId).isEqualTo(Resources.ID_NULL)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(RIGID_BAREBONE.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(RIGID_ALL_OPTIONAL.titleResId).isEqualTo(REFERENCE_RES_ID)
+ assertThat(HIDDEN_BAREBONE.titleResId).isEqualTo(Resources.ID_NULL)
+ assertThat(HIDDEN_ALL_OPTIONAL.titleResId).isEqualTo(REFERENCE_RES_ID)
+ }
}
@Test
fun getStatelessIconType_returnsStatelessIconType() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.statelessIconType)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.statelessIconType)
.isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
- assertThat(COLLAPSIBLE_WITH_ICON.statelessIconType)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.statelessIconType)
.isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
- assertThat(COLLAPSIBLE_WITH_BOTH.statelessIconType)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.statelessIconType)
.isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
- assertThat(RIGID.statelessIconType).isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
+ assertThat(RIGID_INFERRED.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
// This is not an enforced invariant
// statelessIconType should just be ignored for hidden groups
- assertThat(HIDDEN.statelessIconType).isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
+ assertThat(HIDDEN_INFERRED.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ assertThat(RIGID_BAREBONE.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
+ assertThat(RIGID_ALL_OPTIONAL.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ assertThat(HIDDEN_BAREBONE.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
+ assertThat(HIDDEN_ALL_OPTIONAL.statelessIconType)
+ .isEqualTo(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ }
}
@Test
fun getSafetySources_returnsSafetySources() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.safetySources)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.safetySources)
.containsExactly(SafetySourceTest.DYNAMIC_BAREBONE)
- assertThat(COLLAPSIBLE_WITH_ICON.safetySources)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.safetySources)
.containsExactly(SafetySourceTest.STATIC_BAREBONE)
- assertThat(COLLAPSIBLE_WITH_BOTH.safetySources)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.safetySources)
.containsExactly(
SafetySourceTest.DYNAMIC_BAREBONE,
SafetySourceTest.STATIC_BAREBONE,
SafetySourceTest.ISSUE_ONLY_BAREBONE)
.inOrder()
- assertThat(RIGID.safetySources).containsExactly(SafetySourceTest.STATIC_BAREBONE)
- assertThat(HIDDEN.safetySources).containsExactly(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ assertThat(RIGID_INFERRED.safetySources).containsExactly(SafetySourceTest.STATIC_BAREBONE)
+ assertThat(HIDDEN_INFERRED.safetySources)
+ .containsExactly(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.safetySources)
+ .containsExactly(SafetySourceTest.DYNAMIC_BAREBONE)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.safetySources)
+ .containsExactly(
+ SafetySourceTest.DYNAMIC_BAREBONE,
+ SafetySourceTest.STATIC_BAREBONE,
+ SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ assertThat(RIGID_BAREBONE.safetySources)
+ .containsExactly(SafetySourceTest.STATIC_BAREBONE)
+ assertThat(RIGID_ALL_OPTIONAL.safetySources)
+ .containsExactly(
+ SafetySourceTest.DYNAMIC_BAREBONE,
+ SafetySourceTest.STATIC_BAREBONE,
+ SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ assertThat(HIDDEN_BAREBONE.safetySources)
+ .containsExactly(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ assertThat(HIDDEN_ALL_OPTIONAL.safetySources)
+ .containsExactly(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ }
}
@Test
fun getSafetySources_mutationsAreNotAllowed() {
- val sources = COLLAPSIBLE_WITH_SUMMARY.safetySources
+ val sources = COLLAPSIBLE_INFERRED_WITH_SUMMARY.safetySources
assertFailsWith(UnsupportedOperationException::class) {
sources.add(SafetySourceTest.DYNAMIC_BAREBONE)
@@ -114,7 +196,7 @@ class SafetySourcesGroupTest {
fun builder_addSafetySource_doesNotMutatePreviouslyBuiltInstance() {
val safetySourcesGroupBuilder =
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_SUMMARY_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_SUMMARY_ID)
.setTitleResId(REFERENCE_RES_ID)
.setSummaryResId(REFERENCE_RES_ID)
.addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
@@ -126,41 +208,134 @@ class SafetySourcesGroupTest {
}
@Test
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ fun build_hiddenGroupWithDynamicSource_throwsIllegalStateException() {
+ val builder =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ .setId(HIDDEN_BAREBONE_ID)
+ .addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
+
+ val exception = assertFailsWith(IllegalStateException::class) { builder.build() }
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(
+ "Safety sources groups of type hidden can only contain sources of type issue-only")
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ fun build_hiddenGroupWithStaticSource_throwsIllegalStateException() {
+ val builder =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ .setId(HIDDEN_BAREBONE_ID)
+ .addSafetySource(SafetySourceTest.STATIC_BAREBONE)
+
+ val exception = assertFailsWith(IllegalStateException::class) { builder.build() }
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(
+ "Safety sources groups of type hidden can only contain sources of type issue-only")
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ fun build_collapsibleGroupWithIssueOnlySource_throwsIllegalStateException() {
+ val builder =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ .setId(COLLAPSIBLE_BAREBONE_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+
+ val exception = assertFailsWith(IllegalStateException::class) { builder.build() }
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(
+ "Safety sources groups containing only sources of type issue-only must be of " +
+ "type hidden")
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ fun build_rigidGroupWithIssueOnlySource_throwsIllegalStateException() {
+ val builder =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ .setId(RIGID_BAREBONE_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+
+ val exception = assertFailsWith(IllegalStateException::class) { builder.build() }
+ assertThat(exception)
+ .hasMessageThat()
+ .isEqualTo(
+ "Safety sources groups containing only sources of type issue-only must be of " +
+ "type hidden")
+ }
+
+ @Test
fun describeContents_returns0() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY.describeContents()).isEqualTo(0)
- assertThat(COLLAPSIBLE_WITH_ICON.describeContents()).isEqualTo(0)
- assertThat(COLLAPSIBLE_WITH_BOTH.describeContents()).isEqualTo(0)
- assertThat(RIGID.describeContents()).isEqualTo(0)
- assertThat(HIDDEN.describeContents()).isEqualTo(0)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY.describeContents()).isEqualTo(0)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON.describeContents()).isEqualTo(0)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH.describeContents()).isEqualTo(0)
+ assertThat(RIGID_INFERRED.describeContents()).isEqualTo(0)
+ assertThat(HIDDEN_INFERRED.describeContents()).isEqualTo(0)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE.describeContents()).isEqualTo(0)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL.describeContents()).isEqualTo(0)
+ assertThat(RIGID_BAREBONE.describeContents()).isEqualTo(0)
+ assertThat(RIGID_ALL_OPTIONAL.describeContents()).isEqualTo(0)
+ assertThat(HIDDEN_BAREBONE.describeContents()).isEqualTo(0)
+ assertThat(HIDDEN_ALL_OPTIONAL.describeContents()).isEqualTo(0)
+ }
}
@Test
fun parcelRoundTrip_recreatesEqual() {
- assertThat(COLLAPSIBLE_WITH_SUMMARY).recreatesEqual(SafetySourcesGroup.CREATOR)
- assertThat(COLLAPSIBLE_WITH_ICON).recreatesEqual(SafetySourcesGroup.CREATOR)
- assertThat(COLLAPSIBLE_WITH_BOTH).recreatesEqual(SafetySourcesGroup.CREATOR)
- assertThat(RIGID).recreatesEqual(SafetySourcesGroup.CREATOR)
- assertThat(HIDDEN).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_SUMMARY).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_ICON).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(COLLAPSIBLE_INFERRED_WITH_BOTH).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(RIGID_INFERRED).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(HIDDEN_INFERRED).recreatesEqual(SafetySourcesGroup.CREATOR)
+ if (SdkLevel.isAtLeastU()) {
+ assertThat(COLLAPSIBLE_BAREBONE).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(COLLAPSIBLE_ALL_OPTIONAL).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(RIGID_BAREBONE).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(RIGID_ALL_OPTIONAL).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(HIDDEN_BAREBONE).recreatesEqual(SafetySourcesGroup.CREATOR)
+ assertThat(HIDDEN_ALL_OPTIONAL).recreatesEqual(SafetySourcesGroup.CREATOR)
+ }
}
@Test
fun equalsHashCodeToString_usingEqualsHashCodeToStringTester() {
EqualsHashCodeToStringTester()
- .addEqualityGroup(COLLAPSIBLE_WITH_SUMMARY)
- .addEqualityGroup(COLLAPSIBLE_WITH_ICON)
+ .addEqualityGroup(COLLAPSIBLE_INFERRED_WITH_SUMMARY)
+ .addEqualityGroup(COLLAPSIBLE_INFERRED_WITH_ICON)
.addEqualityGroup(
- COLLAPSIBLE_WITH_BOTH,
- SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_BOTH_ID)
- .setTitleResId(REFERENCE_RES_ID)
- .setSummaryResId(REFERENCE_RES_ID)
- .setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
- .addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
- .addSafetySource(SafetySourceTest.STATIC_BAREBONE)
- .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
- .build())
- .addEqualityGroup(RIGID)
- .addEqualityGroup(HIDDEN)
+ *mutableListOf(
+ COLLAPSIBLE_INFERRED_WITH_BOTH,
+ SafetySourcesGroup.Builder()
+ .setId(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .setSummaryResId(REFERENCE_RES_ID)
+ .setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
+ .addSafetySource(SafetySourceTest.STATIC_BAREBONE)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ .build())
+ .apply { if (SdkLevel.isAtLeastU()) add(COLLAPSIBLE_ALL_OPTIONAL) }
+ .toTypedArray())
+ .addEqualityGroup(
+ *mutableListOf(RIGID_INFERRED)
+ .apply { if (SdkLevel.isAtLeastU()) add(RIGID_BAREBONE) }
+ .toTypedArray())
+ .addEqualityGroup(
+ *mutableListOf(HIDDEN_INFERRED)
+ .apply { if (SdkLevel.isAtLeastU()) add(HIDDEN_BAREBONE) }
+ .toTypedArray())
.addEqualityGroup(
SafetySourcesGroup.Builder()
.setId("other")
@@ -171,7 +346,7 @@ class SafetySourcesGroupTest {
.build())
.addEqualityGroup(
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_BOTH_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
.setTitleResId(-1)
.setSummaryResId(REFERENCE_RES_ID)
.setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
@@ -179,7 +354,7 @@ class SafetySourcesGroupTest {
.build())
.addEqualityGroup(
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_BOTH_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
.setTitleResId(REFERENCE_RES_ID)
.setSummaryResId(-1)
.setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
@@ -187,7 +362,7 @@ class SafetySourcesGroupTest {
.build())
.addEqualityGroup(
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_BOTH_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
.setTitleResId(REFERENCE_RES_ID)
.setSummaryResId(REFERENCE_RES_ID)
.setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_NONE)
@@ -195,44 +370,57 @@ class SafetySourcesGroupTest {
.build())
.addEqualityGroup(
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_BOTH_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
.setTitleResId(REFERENCE_RES_ID)
.setSummaryResId(REFERENCE_RES_ID)
.setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
.addSafetySource(SafetySourceTest.STATIC_BAREBONE)
.build())
+ .apply {
+ if (SdkLevel.isAtLeastU()) {
+ addEqualityGroup(COLLAPSIBLE_BAREBONE)
+ addEqualityGroup(RIGID_ALL_OPTIONAL)
+ addEqualityGroup(HIDDEN_ALL_OPTIONAL)
+ }
+ }
.test()
}
companion object {
private const val REFERENCE_RES_ID = 9999
- private const val COLLAPSIBLE_WITH_SUMMARY_ID = "collapsible_with_summary"
- private const val COLLAPSIBLE_WITH_ICON_ID = "collapsible_with_icon"
- private const val COLLAPSIBLE_WITH_BOTH_ID = "collapsible_with_both"
- private const val RIGID_ID = "rigid"
- private const val HIDDEN_ID = "hidden"
+ private const val COLLAPSIBLE_BAREBONE_ID = "collapsible_barebone"
+ private const val COLLAPSIBLE_ALL_OPTIONAL_ID = "collapsible_all_optional"
+ private const val RIGID_BAREBONE_ID = "rigid_barebone"
+ private const val RIGID_ALL_OPTIONAL_ID = "rigid_all_optional"
+ private const val HIDDEN_BAREBONE_ID = "hidden_barebone"
+ private const val HIDDEN_ALL_OPTIONAL_ID = "hidden_all_optional"
+ private const val COLLAPSIBLE_INFERRED_WITH_SUMMARY_ID = "collapsible_inferred_with_summary"
+ private const val COLLAPSIBLE_INFERRED_WITH_ICON_ID = "collapsible_inferred_with_icon"
+ private const val COLLAPSIBLE_INFERRED_WITH_BOTH_ID = COLLAPSIBLE_ALL_OPTIONAL_ID
+ private const val RIGID_INFERRED_ID = RIGID_BAREBONE_ID
+ private const val HIDDEN_INFERRED_ID = HIDDEN_BAREBONE_ID
// TODO(b/230078826): Consider extracting shared constants to a separate file.
- internal val COLLAPSIBLE_WITH_SUMMARY =
+ internal val COLLAPSIBLE_INFERRED_WITH_SUMMARY =
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_SUMMARY_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_SUMMARY_ID)
.setTitleResId(REFERENCE_RES_ID)
.setSummaryResId(REFERENCE_RES_ID)
.addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
.build()
- private val COLLAPSIBLE_WITH_ICON =
+ private val COLLAPSIBLE_INFERRED_WITH_ICON =
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_ICON_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_ICON_ID)
.setTitleResId(REFERENCE_RES_ID)
.setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
.addSafetySource(SafetySourceTest.STATIC_BAREBONE)
.build()
- private val COLLAPSIBLE_WITH_BOTH =
+ private val COLLAPSIBLE_INFERRED_WITH_BOTH =
SafetySourcesGroup.Builder()
- .setId(COLLAPSIBLE_WITH_BOTH_ID)
+ .setId(COLLAPSIBLE_INFERRED_WITH_BOTH_ID)
.setTitleResId(REFERENCE_RES_ID)
.setSummaryResId(REFERENCE_RES_ID)
.setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
@@ -241,17 +429,86 @@ class SafetySourcesGroupTest {
.addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
.build()
- internal val RIGID =
+ private val COLLAPSIBLE_BAREBONE: SafetySourcesGroup
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ get() =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ .setId(COLLAPSIBLE_BAREBONE_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
+ .build()
+
+ private val COLLAPSIBLE_ALL_OPTIONAL: SafetySourcesGroup
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ get() =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_COLLAPSIBLE)
+ .setId(COLLAPSIBLE_ALL_OPTIONAL_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .setSummaryResId(REFERENCE_RES_ID)
+ .setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
+ .addSafetySource(SafetySourceTest.STATIC_BAREBONE)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ .build()
+
+ internal val RIGID_INFERRED =
SafetySourcesGroup.Builder()
- .setId(RIGID_ID)
+ .setId(RIGID_INFERRED_ID)
.setTitleResId(REFERENCE_RES_ID)
.addSafetySource(SafetySourceTest.STATIC_BAREBONE)
.build()
- internal val HIDDEN =
+ private val RIGID_BAREBONE: SafetySourcesGroup
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ get() =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ .setId(RIGID_BAREBONE_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .addSafetySource(SafetySourceTest.STATIC_BAREBONE)
+ .build()
+
+ private val RIGID_ALL_OPTIONAL: SafetySourcesGroup
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ get() =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ .setId(RIGID_ALL_OPTIONAL_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .setSummaryResId(REFERENCE_RES_ID)
+ .setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(SafetySourceTest.DYNAMIC_BAREBONE)
+ .addSafetySource(SafetySourceTest.STATIC_BAREBONE)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ .build()
+
+ internal val HIDDEN_INFERRED =
SafetySourcesGroup.Builder()
- .setId(HIDDEN_ID)
+ .setId(HIDDEN_INFERRED_ID)
.addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
.build()
+
+ private val HIDDEN_BAREBONE: SafetySourcesGroup
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ get() =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ .setId(HIDDEN_BAREBONE_ID)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ .build()
+
+ private val HIDDEN_ALL_OPTIONAL: SafetySourcesGroup
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ get() =
+ SafetySourcesGroup.Builder()
+ .setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ .setId(HIDDEN_ALL_OPTIONAL_ID)
+ .setTitleResId(REFERENCE_RES_ID)
+ .setSummaryResId(REFERENCE_RES_ID)
+ .setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ .addSafetySource(SafetySourceTest.ISSUE_ONLY_BAREBONE)
+ .build()
}
}
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/testing/SafetyCenterCtsConfigs.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/testing/SafetyCenterCtsConfigs.kt
index fce6cdad7..56a095ba8 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/testing/SafetyCenterCtsConfigs.kt
+++ b/tests/cts/safetycenter/src/android/safetycenter/cts/testing/SafetyCenterCtsConfigs.kt
@@ -553,7 +553,14 @@ object SafetyCenterCtsConfigs {
.build())
.addSafetySourcesGroup(
safetySourcesGroupBuilder(STATIC_GROUP_ID)
- .setSummaryResId(Resources.ID_NULL)
+ .apply {
+ if (SdkLevel.isAtLeastU()) {
+ setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_RIGID)
+ setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ } else {
+ setSummaryResId(Resources.ID_NULL)
+ }
+ }
.addSafetySource(
staticSafetySourceBuilder(STATIC_BAREBONE_ID)
.setSummaryResId(Resources.ID_NULL)
@@ -566,6 +573,14 @@ object SafetyCenterCtsConfigs {
.addSafetySourcesGroup(
SafetySourcesGroup.Builder()
.setId(ISSUE_ONLY_GROUP_ID)
+ .apply {
+ if (SdkLevel.isAtLeastU()) {
+ setType(SafetySourcesGroup.SAFETY_SOURCES_GROUP_TYPE_HIDDEN)
+ setTitleResId(android.R.string.ok)
+ setSummaryResId(android.R.string.ok)
+ setStatelessIconType(SafetySourcesGroup.STATELESS_ICON_TYPE_PRIVACY)
+ }
+ }
.addSafetySource(
issueOnlySafetySourceBuilder(ISSUE_ONLY_BAREBONE_ID)
.setRefreshOnPageOpenAllowed(false)