diff options
author | 2024-02-08 12:55:40 +0000 | |
---|---|---|
committer | 2024-02-08 12:55:40 +0000 | |
commit | fcba235c4c03c0bf0b58e8b1661be45eec7d57ca (patch) | |
tree | f0a2d001ad75140572f9a5d7bf43e0547f362cb6 /framework-s/java | |
parent | a78527583c737cd4c04535533a9dae6df9f6951b (diff) | |
parent | 1103d313bf297370cd948cf4a78d4a3f748ba87e (diff) |
Merge changes from topics "ps_safety_center", "sc_biometrics", "sc_private_profile_api" into main
* changes:
Add the titleForPrivateProfile API
Generalise the code for various profile types - 6
Generalise the code for various profile types - 5
Generalise the code for various profile types - 4
Don't add primary profile in default group summary
Generalise the code for various profile types - 3
Generalise the code for various profile types - 2
Generalise the code for various profile types - 1
Diffstat (limited to 'framework-s/java')
-rw-r--r-- | framework-s/java/android/safetycenter/config/SafetySource.java | 100 | ||||
-rw-r--r-- | framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd | 223 |
2 files changed, 316 insertions, 7 deletions
diff --git a/framework-s/java/android/safetycenter/config/SafetySource.java b/framework-s/java/android/safetycenter/config/SafetySource.java index 8aa897850..5502ca950 100644 --- a/framework-s/java/android/safetycenter/config/SafetySource.java +++ b/framework-s/java/android/safetycenter/config/SafetySource.java @@ -18,9 +18,11 @@ package android.safetycenter.config; import static android.os.Build.VERSION_CODES.TIRAMISU; import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; +import static android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM; import static java.util.Objects.requireNonNull; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -34,6 +36,7 @@ import android.util.ArraySet; import androidx.annotation.RequiresApi; import com.android.modules.utils.build.SdkLevel; +import com.android.permission.flags.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -182,6 +185,9 @@ public final class SafetySource implements Parcelable { builder.addPackageCertificateHash(certs.get(i)); } } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + builder.setTitleForPrivateProfileResId(in.readInt()); + } return builder.build(); } @@ -207,6 +213,7 @@ public final class SafetySource implements Parcelable { private final boolean mNotificationsAllowed; @Nullable final String mDeduplicationGroup; @NonNull private final Set<String> mPackageCertificateHashes; + @StringRes private final int mTitleForPrivateProfileResId; private SafetySource( @SafetySourceType int type, @@ -224,7 +231,8 @@ public final class SafetySource implements Parcelable { boolean refreshOnPageOpenAllowed, boolean notificationsAllowed, @Nullable String deduplicationGroup, - @NonNull Set<String> packageCertificateHashes) { + @NonNull Set<String> packageCertificateHashes, + @StringRes int titleForPrivateProfileResId) { mType = type; mId = id; mPackageName = packageName; @@ -241,6 +249,7 @@ public final class SafetySource implements Parcelable { mNotificationsAllowed = notificationsAllowed; mDeduplicationGroup = deduplicationGroup; mPackageCertificateHashes = Set.copyOf(packageCertificateHashes); + mTitleForPrivateProfileResId = titleForPrivateProfileResId; } /** Returns the type of this safety source. */ @@ -347,6 +356,37 @@ public final class SafetySource implements Parcelable { } /** + * Returns the resource id of the title for private profile of this safety source. + * + * <p>The id refers to a string resource that is either accessible from any resource context or + * that is accessible from the same resource context that was used to load the Safety Center + * configuration. The id is {@link Resources#ID_NULL} when a title for private profile is not + * provided. + * + * @throws UnsupportedOperationException if the source is of type {@link + * SafetySource#SAFETY_SOURCE_TYPE_ISSUE_ONLY} or if the profile property of the source is + * set to {@link SafetySource#PROFILE_PRIMARY} + */ + @FlaggedApi(Flags.FLAG_PRIVATE_PROFILE_TITLE_API) + @RequiresApi(VANILLA_ICE_CREAM) + @StringRes + public int getTitleForPrivateProfileResId() { + if (!SdkLevel.isAtLeastV()) { + throw new UnsupportedOperationException( + "getTitleForPrivateProfileResId unsupported for SDKs lower than V"); + } + if (mType == SAFETY_SOURCE_TYPE_ISSUE_ONLY) { + throw new UnsupportedOperationException( + "getTitleForPrivateProfileResId unsupported for issue-only safety source"); + } + if (mProfile == PROFILE_PRIMARY) { + throw new UnsupportedOperationException( + "getTitleForPrivateProfileResId unsupported for primary profile safety source"); + } + return mTitleForPrivateProfileResId; + } + + /** * Returns the resource id of the summary of this safety source. * * <p>The id refers to a string resource that is either accessible from any resource context or @@ -554,7 +594,8 @@ public final class SafetySource implements Parcelable { && mRefreshOnPageOpenAllowed == that.mRefreshOnPageOpenAllowed && mNotificationsAllowed == that.mNotificationsAllowed && Objects.equals(mDeduplicationGroup, that.mDeduplicationGroup) - && Objects.equals(mPackageCertificateHashes, that.mPackageCertificateHashes); + && Objects.equals(mPackageCertificateHashes, that.mPackageCertificateHashes) + && mTitleForPrivateProfileResId == that.mTitleForPrivateProfileResId; } @Override @@ -575,7 +616,8 @@ public final class SafetySource implements Parcelable { mRefreshOnPageOpenAllowed, mNotificationsAllowed, mDeduplicationGroup, - mPackageCertificateHashes); + mPackageCertificateHashes, + mTitleForPrivateProfileResId); } @Override @@ -613,6 +655,8 @@ public final class SafetySource implements Parcelable { + mDeduplicationGroup + ", mPackageCertificateHashes=" + mPackageCertificateHashes + + ", mTitleForPrivateProfileResId=" + + mTitleForPrivateProfileResId + '}'; } @@ -641,6 +685,9 @@ public final class SafetySource implements Parcelable { dest.writeString(mDeduplicationGroup); dest.writeStringList(List.copyOf(mPackageCertificateHashes)); } + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + dest.writeInt(mTitleForPrivateProfileResId); + } } /** Builder class for {@link SafetySource}. */ @@ -662,6 +709,7 @@ public final class SafetySource implements Parcelable { @Nullable private Boolean mNotificationsAllowed; @Nullable private String mDeduplicationGroup; @NonNull private final ArraySet<String> mPackageCertificateHashes = new ArraySet<>(); + @Nullable @StringRes private Integer mTitleForPrivateProfileResId; /** Creates a {@link Builder} for a {@link SafetySource}. */ public Builder(@SafetySourceType int type) { @@ -692,6 +740,7 @@ public final class SafetySource implements Parcelable { mNotificationsAllowed = safetySource.mNotificationsAllowed; mDeduplicationGroup = safetySource.mDeduplicationGroup; mPackageCertificateHashes.addAll(safetySource.mPackageCertificateHashes); + mTitleForPrivateProfileResId = safetySource.mTitleForPrivateProfileResId; } /** @@ -759,6 +808,32 @@ public final class SafetySource implements Parcelable { } /** + * Sets the resource id of the title for work of this safety source. + * + * <p>The id must refer to a string resource that is either accessible from any resource + * context or that is accessible from the same resource context that was used to load the + * Safety Center configuration. The id defaults to {@link Resources#ID_NULL} when a title + * for work is not provided. + * + * <p>The title for work is required if the profile property of the source is set to {@link + * SafetySource#PROFILE_ALL} and either the source is of type static or the source is a + * source of type dynamic that is not hidden and that does not provide search terms. The + * title for work is prohibited for sources of type issue-only and if the profile property + * of the source is not set to {@link SafetySource#PROFILE_ALL}. + */ + @FlaggedApi(Flags.FLAG_PRIVATE_PROFILE_TITLE_API) + @RequiresApi(VANILLA_ICE_CREAM) + @NonNull + public Builder setTitleForPrivateProfileResId(@StringRes int titleForPrivateProfileResId) { + if (!SdkLevel.isAtLeastV()) { + throw new UnsupportedOperationException( + "setTitleForPrivateProfileResId unsupported for SDKs lower than V"); + } + mTitleForPrivateProfileResId = titleForPrivateProfileResId; + return this; + } + + /** * Sets the resource id of the summary of this safety source. * * <p>The id must refer to a string resource that is either accessible from any resource @@ -984,7 +1059,7 @@ public final class SafetySource implements Parcelable { PROFILE_NONE, PROFILE_PRIMARY, PROFILE_ALL); - boolean hasWork = profile == PROFILE_ALL; + boolean hasAllProfiles = profile == PROFILE_ALL; int searchTermsResId = BuilderUtils.validateResId( @@ -1000,8 +1075,8 @@ public final class SafetySource implements Parcelable { BuilderUtils.validateResId( mTitleForWorkResId, "titleForWork", - hasWork && titleRequired, - !hasWork || isIssueOnly); + hasAllProfiles && titleRequired, + !hasAllProfiles || isIssueOnly); int summaryResId = BuilderUtils.validateResId( @@ -1052,6 +1127,16 @@ public final class SafetySource implements Parcelable { packageCertificateHashes, "packageCertificateHashes", false, isStatic); } + int titleForPrivateProfileResId = Resources.ID_NULL; + if (SdkLevel.isAtLeastV() && Flags.privateProfileTitleApi()) { + titleForPrivateProfileResId = + BuilderUtils.validateResId( + mTitleForPrivateProfileResId, + "titleForPrivateProfile", + hasAllProfiles && titleRequired, + !hasAllProfiles || isIssueOnly); + } + return new SafetySource( type, id, @@ -1068,7 +1153,8 @@ public final class SafetySource implements Parcelable { refreshOnPageOpenAllowed, notificationsAllowed, deduplicationGroup, - packageCertificateHashes); + packageCertificateHashes, + titleForPrivateProfileResId); } } } diff --git a/framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd b/framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd new file mode 100644 index 000000000..20b1e7655 --- /dev/null +++ b/framework-s/java/android/safetycenter/config/safety_center_config-v35.xsd @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright (C) 2021 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. + --> +<!-- This file contains comments that define constraints that cannot be covered by the XSD language --> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" + version="1.0"> + + <xsd:element name="safety-center-config" type="safety-center-config"/> + + <xsd:complexType name="safety-center-config"> + <xsd:sequence> + <xsd:element name="safety-sources-config" type="safety-sources-config"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="safety-sources-config"> + <xsd:sequence> + <xsd:element + name="safety-sources-group" type="safety-sources-group" + minOccurs="1" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="safety-sources-group"> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> + <xsd:element name="dynamic-safety-source" type="dynamic-safety-source"/> + <xsd:element name="static-safety-source" type="static-safety-source"/> + <xsd:element name="issue-only-safety-source" type="issue-only-safety-source"/> + </xsd:choice> + <!-- id must be unique among safety sources groups --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <!-- title is required unless the group contains issue only and/or internal sources --> + <xsd:attribute name="title" type="runtimeStringResourceName"/> + <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"> + <!-- id must be unique among safety sources --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <xsd:attribute name="packageName" type="stringOrStringResourceName" use="required"/> + <!-- optional comma-separated set of certificate hashes, if provided will be used for validation. --> + <xsd:attribute name="packageCertificateHashes" type="stringOrStringResourceName"/> + <!-- title is required if initialDisplayState is not set to hidden or if searchTerms are provided --> + <xsd:attribute name="title" type="runtimeStringResourceName"/> + <!-- titleForWork is required if profile is set to all_profiles, and initialDisplayState is not set to hidden or if searchTerms are provided --> + <!-- titleForWork is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForWork" type="runtimeStringResourceName"/> + <!-- titleForPrivateProfile is required if profile is set to all_profiles, and initialDisplayState is not set to hidden or if searchTerms are provided --> + <!-- titleForPrivateProfile is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForPrivateProfile" type="runtimeStringResourceName"/> + <!-- summary is required if initialDisplayState is not set to hidden --> + <xsd:attribute name="summary" type="runtimeStringResourceName"/> + <!-- intentAction is required if initialDisplayState is set to enabled --> + <xsd:attribute name="intentAction" type="stringOrStringResourceName"/> + <xsd:attribute name="profile" type="profile" use="required"/> + <xsd:attribute name="initialDisplayState" type="initialDisplayStateOrStringResourceName" + default="enabled"/> + <xsd:attribute name="maxSeverityLevel" type="intOrStringResourceName" default="2147483647"/> + <xsd:attribute name="searchTerms" type="runtimeStringResourceName"/> + <xsd:attribute name="loggingAllowed" type="booleanOrStringResourceName" default="true"/> + <xsd:attribute name="refreshOnPageOpenAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="notificationsAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="deduplicationGroup" type="stringOrStringResourceName"/> + </xsd:complexType> + + <xsd:complexType name="issue-only-safety-source"> + <!-- id must be unique among safety sources --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <xsd:attribute name="packageName" type="stringOrStringResourceName" use="required"/> + <!-- optional comma-separated set of certificate hashes, if provided will be used for validation. --> + <xsd:attribute name="packageCertificateHashes" type="stringOrStringResourceName"/> + <xsd:attribute name="profile" type="profileOrStringResourceName" use="required"/> + <xsd:attribute name="maxSeverityLevel" type="intOrStringResourceName" default="2147483647"/> + <xsd:attribute name="loggingAllowed" type="booleanOrStringResourceName" default="true"/> + <xsd:attribute name="refreshOnPageOpenAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="notificationsAllowed" type="booleanOrStringResourceName" + default="false"/> + <xsd:attribute name="deduplicationGroup" type="stringOrStringResourceName"/> + </xsd:complexType> + + <xsd:complexType name="static-safety-source"> + <!-- id must be unique among safety sources --> + <xsd:attribute name="id" type="idOrStringResourceName" use="required"/> + <xsd:attribute name="packageName" type="stringOrStringResourceName"/> + <xsd:attribute name="title" type="runtimeStringResourceName" use="required"/> + <!-- titleForWork is required if profile is set to all_profiles --> + <!-- titleForWork is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForWork" type="runtimeStringResourceName"/> + <!-- titleForPrivateProfile is required if profile is set to all_profiles --> + <!-- titleForPrivateProfile is prohibited if profile is set to primary_profile_only --> + <xsd:attribute name="titleForPrivateProfile" type="runtimeStringResourceName"/> + <xsd:attribute name="summary" type="runtimeStringResourceName"/> + <xsd:attribute name="intentAction" type="stringOrStringResourceName" use="required"/> + <xsd:attribute name="profile" type="profileOrStringResourceName" use="required"/> + <xsd:attribute name="searchTerms" type="runtimeStringResourceName"/> + </xsd:complexType> + + <xsd:simpleType name="intOrStringResourceName"> + <!-- 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 xsd:int. --> + <xsd:union memberTypes="stringResourceName xsd:int"/> + </xsd:simpleType> + + <xsd:simpleType name="booleanOrStringResourceName"> + <!-- 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 xsd:boolean. --> + <xsd:union memberTypes="stringResourceName xsd:boolean"/> + </xsd:simpleType> + + <xsd:simpleType name="stringOrStringResourceName"> + <!-- 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 xsd:string. --> + <xsd:union memberTypes="stringResourceName xsd:string"/> + </xsd:simpleType> + + <xsd:simpleType name="idOrStringResourceName"> + <!-- 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 xsd:string. --> + <xsd:union memberTypes="stringResourceName id"/> + </xsd:simpleType> + + <xsd:simpleType name="id"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="[0-9a-zA-Z_-]+"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="statelessIconTypeOrStringResourceName"> + <!-- 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 statelessIconType. --> + <xsd:union memberTypes="stringResourceName statelessIconType"/> + </xsd:simpleType> + + <xsd:simpleType name="statelessIconType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="none"/> + <xsd:enumeration value="privacy"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="profileOrStringResourceName"> + <!-- 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 profile. --> + <xsd:union memberTypes="stringResourceName profile"/> + </xsd:simpleType> + + <xsd:simpleType name="profile"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="primary_profile_only"/> + <xsd:enumeration value="all_profiles"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="initialDisplayStateOrStringResourceName"> + <!-- 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 initialDisplayState. --> + <xsd:union memberTypes="stringResourceName initialDisplayState"/> + </xsd:simpleType> + + <xsd:simpleType name="initialDisplayState"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="enabled"/> + <xsd:enumeration value="disabled"/> + <xsd:enumeration value="hidden"/> + </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="stateless"/> + <xsd:enumeration value="stateful"/> + <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"/> + </xsd:simpleType> + + <!-- String resource names will be ignored for any attribute not directly or indirectly marked as stringResourceName. --> + <!-- A stringResourceName is a fully qualified resource name of the form "@package:string/entry". Package is required. --> + <xsd:simpleType name="stringResourceName"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value="@([a-z]+\.)*[a-z]+:string/.+"/> + </xsd:restriction> + </xsd:simpleType> + +</xsd:schema> |