Customize Safety Center

Enable or disable Safety Center

To enable or disable Safety Center, use the overlayable config_enableSafetyCenter boolean field in the frameworks/base/core/res/res/values/config.xml file.

On most devices, Safety Center is supported by default, for example, on phones and tablets. On some form factors, Safety Center is disabled by default, for example, on Auto, TV, and Wear.

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- ... -->
   <!-- Determines whether SafetyCenter feature is enabled. -->
    <bool name="config_enableSafetyCenter">true</bool>
    <!-- ... -->
</resources>

To support Safety Center, set config_enableSafetyCenter to true. If you don't want to support Safety Center, set this value to false to disable it.

When Safety Center is disabled, any attempt to redirect to the Security & Privacy page opens the Settings app instead. Any attempt to interact with the APIs is silently ignored or returns a default value. The associated Quick Settings tile and Settings entry are also exposed or hidden depending on whether Safety Center is enabled.

DeviceConfig flag

In addition to enabling Safety Center using the config_enableSafetyCenter configuration, a DeviceConfig flag (safety_center_is_enabled) is used to remotely enable or disable Safety Center.

In Android 14 and above, no further action is necessary as this flag is true by default.

In Android 13, Safety Center is disabled by default server-side and enabled by allowlist using this flag. Submit your device fingerprints and contact your TAM to be added to the allowlist. Note that mainline version M-2022-11 or higher is required to be added to the allowlist. For local development and testing, the flag can be enabled or disabled locally (until a reboot) with an adb command. For example, to enable the flag:

adb root
adb shell device_config set_sync_disabled_for_tests until_reboot
adb shell device_config put privacy safety_center_is_enabled true

And to confirm whether Safety Center is enabled:

adb root
adb shell cmd safety_center enabled

The output will return whether Safety Center is correctly enabled on the device.

Update the configuration file

Use the safety_center_config.xml configuration file to modify the contents of the Safety Center screen. You can overlay this file assuming you've met the Customization Requirements.

Overlay the configuration file

To overlay the safety_center_config.xml file, see Change the value of an app's resources at runtime for information about modifying runtime resource overlays (RROs).

In Android 14, make sure to overlay the res/raw-v34/safety_center_config.xml file and not the res/raw/safety_center_config.xml as the former takes precedence (this also applies to other files that are scoped for v34 for e.g. res/values-v34/strings.xml). The overlay package must have a min SDK lower than 34, otherwise the v34 qualifier may be stripped during optimization. Also make sure to use a static overlay, as this value is loaded around boot time.

For Android Open Source Project (AOSP) devices, target the package com.android.safetycenter.resources. There's no overlay configuration to target. All resources are overlayable with no restriction on the content.

For GMS devices that are configured to receive Mainline updates, target the package com.google.android.safetycenter.resources. Target the configuration SafetyCenterConfig. This configuration requires that the overlay package is in either the product, system, or vendor partition. GMS OEMs should copy the Google provided safety_center_config.xml file and limit modifications to those allowed by the GTS tests. The overlay definition should be close to this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.overlay.package"
    android:versionCode="1"
    android:versionName="1.0">
    <application android:hasCode="false" />
    <overlay
      android:targetPackage="com.google.android.safetycenter.resources"
      android:targetName="SafetyCenterConfig"
      android:isStatic="true"
      android:priority="0"/>
</manifest>

For GMS devices that aren't configured to receive Mainline updates, target the package com.android.safetycenter.resources. There's no overlay configuration to target. The overlay package must use the package name com.google.android.safetycenter.resources.

GMS OEMs should copy the Google provided safety_center_config.xml file and limit modifications to those allowed by the GTS tests. GMS OEMs must also define the strings used in the XML configuration.

File structure

At a high level, the safety_center_config.xml file is a list of safety sources. These safety sources are organized in groups to manage the signals on the Safety Center screen, for example, App Security or Screen Lock. The order of this list defines the display order:

<safety-center-config> <!-- Wrapper for the Safety Center configuration -->
    <safety-sources-config>< !-- Wrapper for the safety sources groups -->
        <safety-sources-group> <!-- Contains information about a safety sources group -->
            <dynamic-safety-source /> <!-- Contains information about a safety source -->
            <!-- More safety sources in the group -->
        </safety-sources-group> <!-- More safety sources groups -->
    </safety-sources-config>
</safety-center-config>

Google configuration file

The AOSP configuration file is located in packages/modules/Permission/SafetyCenter/Resources/res/raw/safety_center_config.xml.

In Android 13, the Google configuration file is:

<safety-center-config>
    <safety-sources-config>
        <safety-sources-group
            id="GoogleAppSecuritySources"
            title="@com.google.android.safetycenter.resources:string/google_app_security_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_app_security_sources_summary">
            <dynamic-safety-source
                id="GooglePlayProtect"
                packageName="com.android.vending"
                profile="all_profiles"
                intentAction="com.google.android.finsky.PLAY_PROTECT"
                title="@com.google.android.safetycenter.resources:string/google_play_protect_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_play_protect_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_play_protect_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_play_protect_search_terms"
                refreshOnPageOpenAllowed="true"/>
            <dynamic-safety-source
                id="GoogleAppProtectionService"
                packageName="com.google.android.odad"
                profile="primary_profile_only"
                initialDisplayState="hidden"
                loggingAllowed="false"/>
        </safety-sources-group>
        <safety-sources-group
            id="AndroidLockScreenSources"
            title="@com.google.android.safetycenter.resources:string/google_lock_screen_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_lock_screen_sources_summary">
            <dynamic-safety-source
                id="AndroidLockScreen"
                packageName="com.android.settings"
                profile="primary_profile_only"
                title="@com.google.android.safetycenter.resources:string/google_lock_screen_title"
                summary="@com.google.android.safetycenter.resources:string/google_lock_screen_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_lock_screen_search_terms"
                initialDisplayState="disabled"
                maxSeverityLevel="300"
                refreshOnPageOpenAllowed="true"/>
            <dynamic-safety-source
                id="AndroidBiometrics"
                packageName="com.android.settings"
                profile="primary_profile_only"
                title="@com.google.android.safetycenter.resources:string/google_biometrics_title"
                summary="@com.google.android.safetycenter.resources:string/google_biometrics_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_biometrics_search_terms"
                initialDisplayState="@com.google.android.safetycenter.resources:string/google_biometrics_initial_display_state"
                maxSeverityLevel="0"
                refreshOnPageOpenAllowed="true"/>
        </safety-sources-group>
        <safety-sources-group
            id="GoogleAccountsSources"
            title="@com.google.android.safetycenter.resources:string/google_accounts_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_accounts_sources_summary">
            <dynamic-safety-source
                id="GoogleSecurityCheckup"
                packageName="com.google.android.gms"
                profile="all_profiles"
                intentAction="com.google.android.gms.accountsettings.action.SAFETY_CENTER_SECURITY_CHECKUP"
                title="@com.google.android.safetycenter.resources:string/google_security_checkup_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_security_checkup_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_security_checkup_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_security_checkup_search_terms"
                refreshOnPageOpenAllowed="true"/>
        </safety-sources-group>
        <safety-sources-group
            id="GoogleDeviceFinderSources"
            title="@com.google.android.safetycenter.resources:string/google_device_finder_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_device_finder_sources_summary">
            <dynamic-safety-source
                id="GoogleFindMyDevice"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                intentAction="com.google.android.gms.settings.FIND_MY_DEVICE_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_find_my_device_title"
                summary="@com.google.android.safetycenter.resources:string/google_find_my_device_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_find_my_device_search_terms"
                refreshOnPageOpenAllowed="true"/>
            <dynamic-safety-source
                id="GoogleRogueTag"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                initialDisplayState="hidden"
                refreshOnPageOpenAllowed="true"/>
        </safety-sources-group>
        <safety-sources-group
            id="GoogleUpdateSources"
            title="@com.google.android.safetycenter.resources:string/google_updates_title"
            summary="@com.google.android.safetycenter.resources:string/google_updates_summary">
            <dynamic-safety-source
                id="GoogleSecurityUpdates"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                intentAction="@com.google.android.safetycenter.resources:string/google_security_updates_intent"
                title="@com.google.android.safetycenter.resources:string/google_security_updates_title"
                summary="@com.google.android.safetycenter.resources:string/google_security_updates_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_security_updates_search_terms"
                refreshOnPageOpenAllowed="true"/>
            <dynamic-safety-source
                id="GooglePlaySystemUpdate"
                packageName="com.android.vending"
                profile="primary_profile_only"
                intentAction="android.settings.MODULE_UPDATE_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_play_system_update_title"
                summary="@com.google.android.safetycenter.resources:string/google_play_system_update_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_play_system_update_search_terms"
                refreshOnPageOpenAllowed="true"/>
        </safety-sources-group>
        <safety-sources-group
            id="AndroidPrivacySources"
            title="@com.google.android.safetycenter.resources:string/google_privacy_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_privacy_sources_summary"
            statelessIconType="privacy">
            <static-safety-source
                id="AndroidPermissionUsage"
                profile="primary_profile_only"
                intentAction="android.intent.action.REVIEW_PERMISSION_USAGE"
                title="@com.google.android.safetycenter.resources:string/google_permission_usage_title"
                summary="@com.google.android.safetycenter.resources:string/google_permission_usage_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_permission_usage_search_terms"/>
            <static-safety-source
                id="AndroidPermissionManager"
                profile="primary_profile_only"
                intentAction="android.intent.action.MANAGE_PERMISSIONS"
                title="@com.google.android.safetycenter.resources:string/google_permission_manager_title"
                summary="@com.google.android.safetycenter.resources:string/google_permission_manager_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_permission_manager_search_terms"/>
            <static-safety-source
                id="AndroidPrivacyControls"
                profile="primary_profile_only"
                intentAction="android.settings.PRIVACY_CONTROLS"
                title="@com.google.android.safetycenter.resources:string/google_privacy_controls_title"
                summary="@com.google.android.safetycenter.resources:string/google_privacy_controls_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_privacy_controls_search_terms"/>
            <issue-only-safety-source
                id="AndroidAccessibility"
                packageName="com.google.android.permissioncontroller"
                profile="all_profiles"
                refreshOnPageOpenAllowed="true"/>
            <issue-only-safety-source
                id="AndroidNotificationListener"
                packageName="com.google.android.permissioncontroller"
                profile="primary_profile_only"
                refreshOnPageOpenAllowed="true"/>
            <issue-only-safety-source
                id="AndroidBackgroundLocation"
                packageName="com.google.android.permissioncontroller"
                profile="all_profiles"
                refreshOnPageOpenAllowed="true"/>
            <issue-only-safety-source
                id="AndroidPermissionAutoRevoke"
                packageName="com.google.android.permissioncontroller"
                profile="all_profiles"
                refreshOnPageOpenAllowed="true"/>
        </safety-sources-group>
        <safety-sources-group
            id="AndroidAdvancedSources"
            title="@com.google.android.safetycenter.resources:string/google_advanced_title">
            <dynamic-safety-source
                id="AndroidWorkPolicyInfo"
                packageName="com.google.android.permissioncontroller"
                profile="primary_profile_only"
                initialDisplayState="hidden"
                refreshOnPageOpenAllowed="true"/>
            <static-safety-source
                id="AndroidAdvancedSecurity"
                profile="primary_profile_only"
                intentAction="com.android.settings.security.SECURITY_ADVANCED_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_advanced_security_title"
                summary="@com.google.android.safetycenter.resources:string/google_advanced_security_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_advanced_security_search_terms"/>
            <static-safety-source
                id="AndroidAdvancedPrivacy"
                profile="primary_profile_only"
                intentAction="android.settings.PRIVACY_ADVANCED_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_advanced_privacy_title"
                summary="@com.google.android.safetycenter.resources:string/google_advanced_privacy_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_advanced_privacy_search_terms"/>
        </safety-sources-group>
    </safety-sources-config>
</safety-center-config>

In Android 14, the Google configuration file is:

<safety-center-config>
    <safety-sources-config>
        <safety-sources-group
            id="GoogleAppSecuritySources"
            title="@com.google.android.safetycenter.resources:string/google_app_security_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_app_security_sources_summary">
            <dynamic-safety-source
                id="GooglePlayProtect"
                packageName="com.android.vending"
                profile="all_profiles"
                intentAction="com.google.android.finsky.PLAY_PROTECT"
                title="@com.google.android.safetycenter.resources:string/google_play_protect_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_play_protect_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_play_protect_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_play_protect_search_terms"
                notificationsAllowed="true"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                deduplicationGroup="AppSecurity"/>
            <issue-only-safety-source
                id="GoogleAppProtectionService"
                packageName="com.google.android.odad"
                profile="primary_profile_only"
                loggingAllowed="false"
                deduplicationGroup="AppSecurity"/>
        </safety-sources-group>
        <safety-sources-group
            id="AndroidLockScreenSources"
            title="@com.google.android.safetycenter.resources:string/google_lock_screen_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_lock_screen_sources_summary">
            <dynamic-safety-source
                id="AndroidLockScreen"
                packageName="com.android.settings"
                profile="primary_profile_only"
                title="@com.google.android.safetycenter.resources:string/google_lock_screen_title"
                summary="@com.google.android.safetycenter.resources:string/google_lock_screen_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_lock_screen_search_terms"
                initialDisplayState="disabled"
                notificationsAllowed="true"
                maxSeverityLevel="300"/>
            <dynamic-safety-source
                id="AndroidBiometrics"
                packageName="com.android.settings"
                profile="all_profiles"
                title="@com.google.android.safetycenter.resources:string/google_biometrics_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_biometrics_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_biometrics_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_biometrics_search_terms"
                initialDisplayState="@com.google.android.safetycenter.resources:string/google_biometrics_initial_display_state"
                maxSeverityLevel="0"/>
        </safety-sources-group>
        <safety-sources-group
            id="GoogleAccountsSources"
            title="@com.google.android.safetycenter.resources:string/google_accounts_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_accounts_sources_summary">
            <dynamic-safety-source
                id="GoogleSecurityCheckup"
                packageName="com.google.android.gms"
                profile="all_profiles"
                intentAction="com.google.android.gms.accountsettings.action.SAFETY_CENTER_SECURITY_CHECKUP"
                title="@com.google.android.safetycenter.resources:string/google_security_checkup_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_security_checkup_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_security_checkup_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_security_checkup_search_terms"
                deduplicationGroup="AccountRequired"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                refreshOnPageOpenAllowed="true"/>
            <dynamic-safety-source
                id="GooglePasswordCheckup"
                packageName="com.google.android.gms"
                profile="all_profiles"
                title="@com.google.android.safetycenter.resources:string/google_password_checkup_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_password_checkup_title_for_work"
                searchTerms="@com.google.android.safetycenter.resources:string/google_password_checkup_search_terms"
                initialDisplayState="hidden"
                notificationsAllowed="true"
                deduplicationGroup="AccountRequired"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                refreshOnPageOpenAllowed="false"/>
        </safety-sources-group>
        <safety-sources-group
            id="GoogleDeviceFinderSources"
            title="@com.google.android.safetycenter.resources:string/google_device_finder_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_device_finder_sources_summary">
            <dynamic-safety-source
                id="GoogleFindMyDevice"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                intentAction="com.google.android.gms.settings.FIND_MY_DEVICE_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_find_my_device_title"
                summary="@com.google.android.safetycenter.resources:string/google_find_my_device_summary"
                notificationsAllowed="true"
                deduplicationGroup="AccountRequired"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                searchTerms="@com.google.android.safetycenter.resources:string/google_find_my_device_search_terms"/>
            <dynamic-safety-source
                id="GoogleRogueTag"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                initialDisplayState="hidden"/>
        </safety-sources-group>
        <safety-sources-group
            id="GoogleUpdateSources"
            title="@com.google.android.safetycenter.resources:string/google_updates_title"
            summary="@com.google.android.safetycenter.resources:string/google_updates_summary">
            <dynamic-safety-source
                id="GoogleSecurityUpdates"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                intentAction="@com.google.android.safetycenter.resources:string/google_security_updates_intent"
                title="@com.google.android.safetycenter.resources:string/google_security_updates_title"
                summary="@com.google.android.safetycenter.resources:string/google_security_updates_summary"
                notificationsAllowed="true"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                searchTerms="@com.google.android.safetycenter.resources:string/google_security_updates_search_terms"/>
            <dynamic-safety-source
                id="GooglePlaySystemUpdate"
                packageName="com.android.vending"
                profile="primary_profile_only"
                intentAction="android.settings.MODULE_UPDATE_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_play_system_update_title"
                summary="@com.google.android.safetycenter.resources:string/google_play_system_update_summary"
                notificationsAllowed="true"
                deduplicationGroup="AccountRequired"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                searchTerms="@com.google.android.safetycenter.resources:string/google_play_system_update_search_terms"/>
            <dynamic-safety-source
                id="GoogleBackupAndRestore"
                packageName="com.google.android.gms"
                profile="primary_profile_only"
                initialDisplayState="hidden"
                title="@com.google.android.safetycenter.resources:string/google_backup_title"
                packageCertificateHashes="1975b2f17177bc89a5dff31f9e64a6cae281a53dc1d1d59b1d147fe1c82afa00,f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83,d22cc500299fb22873a01a010de1c82fbe4d061119b94814dd301dab50cb7678,7ce83c1b71f3d572fed04c8d40c5cb10ff75e6d87d9df6fbd53f0468c2905053"
                searchTerms="@com.google.android.safetycenter.resources:string/google_backup_search_terms"/>
        </safety-sources-group>
        <safety-sources-group
            id="AndroidPrivacySources"
            title="@com.google.android.safetycenter.resources:string/google_privacy_sources_title"
            summary="@com.google.android.safetycenter.resources:string/google_privacy_sources_summary"
            statelessIconType="privacy">
            <static-safety-source
                id="AndroidPermissionManager"
                profile="primary_profile_only"
                intentAction="android.intent.action.MANAGE_PERMISSIONS"
                title="@com.google.android.safetycenter.resources:string/google_permission_manager_title"
                summary="@com.google.android.safetycenter.resources:string/google_permission_manager_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_permission_manager_search_terms"/>
            <static-safety-source
                id="AndroidPermissionUsage"
                profile="primary_profile_only"
                intentAction="android.intent.action.REVIEW_PERMISSION_USAGE"
                title="@com.google.android.safetycenter.resources:string/google_permission_usage_title"
                summary="@com.google.android.safetycenter.resources:string/google_permission_usage_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_permission_usage_search_terms"/>
            <static-safety-source
                id="GoogleAdsIdentity"
                profile="all_profiles"
                packageName="com.google.android.gms"
                intentAction="com.google.android.gms.adsidentity.ACTION_ADS_IDENTITY_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_ads_identity_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_ads_identity_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_ads_identity_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_ads_identity_search_terms"/>
            <dynamic-safety-source
                id="AndroidHealthConnect"
                profile="primary_profile_only"
                packageName="com.google.android.healthconnect.controller"
                initialDisplayState="hidden"
                refreshOnPageOpenAllowed="false"
                title="@com.google.android.safetycenter.resources:string/google_health_connect_title"
                searchTerms="@com.google.android.safetycenter.resources:string/google_health_connect_search_terms"/>
            <dynamic-safety-source
                id="AndroidPrivacyAppDataSharingUpdates"
                packageName="com.google.android.permissioncontroller"
                profile="primary_profile_only"
                initialDisplayState="hidden"
                refreshOnPageOpenAllowed="true"
                title="@com.google.android.safetycenter.resources:string/google_app_data_sharing_updates_title"
                searchTerms="@com.google.android.safetycenter.resources:string/google_app_data_sharing_updates_search_terms"/>
            <static-safety-source
                id="AndroidPrivacyControls"
                profile="primary_profile_only"
                intentAction="android.settings.PRIVACY_CONTROLS"
                title="@com.google.android.safetycenter.resources:string/google_privacy_controls_title"
                summary="@com.google.android.safetycenter.resources:string/google_privacy_controls_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_privacy_controls_search_terms"/>
            <static-safety-source
                id="GoogleActivityControls"
                profile="all_profiles"
                packageName="com.google.android.gms"
                intentAction="com.google.android.gms.accountsettings.action.ACTIVITY_CONTROLS"
                title="@com.google.android.safetycenter.resources:string/google_activity_controls_title"
                titleForWork="@com.google.android.safetycenter.resources:string/google_activity_controls_title_for_work"
                summary="@com.google.android.safetycenter.resources:string/google_activity_controls_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_activity_controls_search_terms"/>
            <issue-only-safety-source
                id="AndroidAccessibility"
                packageName="com.google.android.permissioncontroller"
                profile="all_profiles"
                notificationsAllowed="true"
                refreshOnPageOpenAllowed="true"/>
            <issue-only-safety-source
                id="AndroidNotificationListener"
                packageName="com.google.android.permissioncontroller"
                profile="primary_profile_only"
                notificationsAllowed="true"
                refreshOnPageOpenAllowed="true"/>
            <issue-only-safety-source
                id="AndroidBackgroundLocation"
                packageName="com.google.android.permissioncontroller"
                profile="all_profiles"
                notificationsAllowed="true"
                refreshOnPageOpenAllowed="true"/>
            <issue-only-safety-source
                id="AndroidPermissionAutoRevoke"
                packageName="com.google.android.permissioncontroller"
                profile="all_profiles"
                notificationsAllowed="true"
                refreshOnPageOpenAllowed="true"/>
        </safety-sources-group>
        <safety-sources-group
            id="AndroidAdvancedSources"
            title="@com.google.android.safetycenter.resources:string/google_advanced_title">
            <dynamic-safety-source
                id="AndroidWorkPolicyInfo"
                packageName="com.google.android.permissioncontroller"
                profile="primary_profile_only"
                title="@com.google.android.safetycenter.resources:string/google_work_policy_title"
                initialDisplayState="hidden"
                refreshOnPageOpenAllowed="true"/>
            <static-safety-source
                id="AndroidMoreSettings"
                profile="primary_profile_only"
                intentAction="com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS"
                title="@com.google.android.safetycenter.resources:string/google_more_settings_title"
                summary="@com.google.android.safetycenter.resources:string/google_more_settings_summary"
                searchTerms="@com.google.android.safetycenter.resources:string/google_more_settings_search_terms"/>
        </safety-sources-group>
    </safety-sources-config>
</safety-center-config>

Customize Safety Center sources

Safety Center source types

Sources can be dynamic, issue-only, or static, based on the type of data they provide to the Safety Center.

Dynamic sources

Mark the safety source as dynamic-safety-source if it can provide dynamic data to the Safety Center both for its entry and potential warning cards:

<dynamic-safety-source
    id="AndroidLockScreen"
    packageName="com.android.settings"
    profile="primary_profile_only"
    title="@com.google.android.safetycenter.resources:string/google_lock_screen_title"
    summary="@com.google.android.safetycenter.resources:string/google_lock_screen_summary"
    searchTerms="@com.google.android.safetycenter.resources:string/google_lock_screen_search_terms"
    initialDisplayState="disabled"
    maxSeverityLevel="300"
    refreshOnPageOpenAllowed="true"/>

Issue-only sources

Mark the source as issue-only-safety-source if there's' no associated settings entry but warnings are still provided. You can provide only warnings; providing a settings entry results in an error:

<issue-only-safety-source
    id="AndroidAccessibility"
    packageName="com.google.android.permissioncontroller"
    profile="all_profiles"
    refreshOnPageOpenAllowed="true"/>

Static sources

Mark the source as static-safety-source if it's a redirection entry with no dynamic data:

<static-safety-source
    id="AndroidAdvancedSecurity"
    profile="primary_profile_only"
    intentAction="com.google.android.settings.security.SECURITY_ADVANCED_SETTINGS"
    title="@com.google.android.safetycenter.resources:string/google_advanced_security_title"
    summary="@com.google.android.safetycenter.resources:string/google_advanced_security_summary"
    searchTerms="@com.google.android.safetycenter.resources:string/google_advanced_security_search_terms"/>

Safety Center source configuration

Depending on the Safety Center source type and other invariants, configuration file fields are optional, required, or prohibited and can be customized:

  • id
    • Unique identifier for the safety source, must be unique in the entire file and must be composed of alphabetical characters only (a-z, A-Z) and is case sensitive
    • String type
    • Required for all safety source types
  • packageName
    • Name of the package that owns this safety source, for example, com.google.android.permissioncontroller
    • String type
    • Required for dynamic and issue-only safety sources
    • Prohibited for static safety sources in Android 13; in Android 14 this can optionally be set to target the intentAction of the source explicitly rather than implicitly (see the intent resolution documentation for more details)
  • initialDisplayState
    • How the UI entry is displayed when no data is provided by the safety source
    • Enum type represented as a string, must be one of the following:
      • enabled (default, displays normally)
      • disabled (displays grayed out, can't be clicked)
      • hidden (doesn't display)
    • Optional for dynamic safety sources (default is enabled)
    • Prohibited for issue-only and static safety sources
  • profile
    • Whether this safety source interacts with the user's managed profile
    • Enum type represented as a string, must be one of the following:
      • primary_profile_only (interacts only with the profile parent only)
      • all_profiles (can also interact with the managed profile(s))
    • On all_profiles, several UI entries are generated (one for the profile parent, and one for each managed profile); the safety source can provide different data for each profile
    • Required for all safety sources
  • searchTerms
    • List of search terms that map to the Safety Center entry when using search in the Settings app
    • Resource ID represented as a fully qualified resource name, for example, @package:string/my_search_terms
    • Optional for dynamic and static safety sources (default is no search terms)
    • Prohibited for issue-only safety sources
  • title
    • Default title of the UI entry, used when no data is provided dynamically by the source
    • Resource ID represented as a fully qualified resource name, for example, @package:string/my_title
    • Required for dynamic and static safety sources (unless initialDisplayState="hidden" with no searchTerms)
    • Prohibited for issue-only safety sources
  • titleForWork
    • Default title of the UI entry for the managed profile that's used when data isn't provided dynamically by the source
    • Resource ID represented as a fully qualified resource name, for example, @package:string/my_title_for_work
    • Required for dynamic and static safety sources that have specified profile="all_profiles" (unless initialDisplayState="hidden" with no searchTerms)
    • Prohibited for issue-only safety sources or sources with profile="primary_profile_only"
  • summary
    • Default summary of the UI entry (this is a longer text description displayed below the title), used when data isn't provided dynamically by the source
    • Resource ID represented as a fully qualified resource name, for example, @package:string/my_summary
    • Optional for static safety sources (default is no summary)
    • Required for dynamic safety sources (unless initialDisplayState is hidden)
    • Prohibited for issue-only safety sources
  • intentAction
    • Action to trigger when the UI entry is clicked
    • String type, for example, com.google.android.settings.security.SECURITY_ADVANCED_SETTINGS, or resource ID represented as a fully qualified resource name, for example, @package:string/my_intent_action
    • If this intent action doesn't resolve for the given packageName (if any), the UI entry behaves in the same way as having initialDisplayState="disabled"
    • Required for static safety sources and dynamic safety sources that have initialDisplayState="enabled"
    • Prohibited for issue-only safety sources
  • maxSeverityLevel
    • Maximum severity level that this Safety Center source can provide
    • Integer represented as a string, for example, 300
    • Optional for dynamic and issue-only safety sources (default is no maximum)
    • Prohibited for static safety sources
  • loggingAllowed
    • Whether Safety Center can log interactions or data related to this source
    • Boolean represented as a string, for example false
    • Optional for dynamic and issue-only safety sources (default is true)
    • Prohibited for static safety sources
  • refreshOnPageOpenAllowed
    • Whether a signal should be sent to the safety source to refresh its data when the Safety Center screen is opened
    • Boolean represented as a string, for example, true
    • Optional for dynamic and issue-only safety sources (default is false)
    • Prohibited for static safety sources
  • notificationsAllowed (Starting Android 14)
    • Whether the safety source can optionally provide a notification when reporting an issue
    • Boolean represented as a string, for example, true
    • Optional for dynamic and issue-only safety sources (default is false)
    • Prohibited for static safety sources
  • deduplicationGroup (Starting Android 14)
    • A potential unique identifier that can be used to deduplicate issues coming from different sources. Sources within the same deduplication group can send issues with an optional deduplication id. Issues with the same deduplication id will only be shown once in the UI, even if multiple sources are sending them.
    • String type
    • Optional for dynamic and issue-only safety sources (default is no deduplication)
    • Prohibited for static safety sources
  • packageCertificateHashes (Starting Android 14)
    • A comma separated list of certificate hashes for the given packageName. If this is set, a certificate check will be performed against the given packageCertificateHashes for the given packageName when interacting with the safety source, for security purposes.
    • String type
    • Optional for dynamic and issue-only safety sources (default is no certificate checks)
    • Prohibited for static safety sources

Customize Safety Center sources groups

Safety Center sources must be contained within a Safety Center sources group. Each source group is displayed in the UI in the order that Source groups are listed in the file. Each source is displayed within the group in the order Sources are listed in the file. If the group contains a single safety source, it's displayed as a single entry rather than a group.

Safety Center sources group configuration

Use the following variables to customize Safety Center source groups:

  • id
    • Unique identifier for the safety sources group; must be unique in the entire file
    • String type
    • Required
  • title
    • Title of the group in the UI
    • Resource ID represented as a fully qualified resource name, for example, @package:string/my_title
    • Required if there's at least one dynamic or static safety source within the group (i.e. the group isn’t of type="hidden")
  • summary
    • Brief description of the group in the UI, displayed below the title. Displayed under specific conditions, typically when data isn't provided; otherwise, the summary is computed based on the data provided by the sources within the group.
    • Resource ID represented as a fully qualified resource name, for example, @package:string/my_summary
    • Optional (default is no summary)
  • statelessIconType
    • Icon type displayed for the group when no state is provided by the safety sources, for example, static entries
    • Enum type represented as a string that must be either none or privacy (the privacy icon type)
    • Optional (default is none)
  • type (Starting Android 14)
    • An explicit type to qualify how this group interacts with Safety Center
    • Enum type represented as a string, must be one of the following:
      • stateful (displays and contributes to overall Safety Center status)
      • stateless (displays and doesn’t contribute to overall Safety Center status)
      • hidden (doesn't display, all sources must be issue-only)
    • Optional, inferred by default by using the safety sources contained in the group as well as the summary and statelessIconType. If the type is specified some additional invariants are enforced to make sure that it matches the sources encountered in the group (for example, the group cannot be hidden if it contains user-visible entries)

Safety Center sources group types

Safety Center source groups are classified as stateful, stateless, or hidden, based on the state of certain fields.

Stateful group

A group that has both a title and a summary, or stateLessIconType="privacy" is considered stateful contributes to the overall Safety Center status:

<safety-sources-group
    id="GoogleAppSecuritySources"
    title="@com.google.android.safetycenter.resources:string/google_app_security_sources_title"
    summary="@com.google.android.safetycenter.resources:string/google_app_security_sources_summary">
    <dynamic-safety-source
        id="GooglePlayProtect"
        packageName="com.android.vending"
        profile="all_profiles"
        intentAction="com.google.android.finsky.PLAY_PROTECT"
        title="@com.google.android.safetycenter.resources:string/google_play_protect_title"
        titleForWork="@com.google.android.safetycenter.resources:string/google_play_protect_title_for_work"
        summary="@com.google.android.safetycenter.resources:string/google_play_protect_summary"
        searchTerms="@com.google.android.safetycenter.resources:string/google_play_protect_search_terms"
        refreshOnPageOpenAllowed="true"/>
    <dynamic-safety-source
        id="GoogleAppProtectionService"
        packageName="com.google.android.odad"
        profile="primary_profile_only"
        initialDisplayState="hidden"
        loggingAllowed="false"/>
</safety-sources-group>

In Android 13, such a group will show as collapsible entry in the UI. In Android 14, it will show as an entry with its own status that redirects to subpage.

Stateless group

A group that has a title but no summary, and stateLessIconType="none" is considered stateless and doesn’t contribute to the overall Safety Center status:

<safety-sources-group
    id="AndroidPrivacySources"
    title="@com.google.android.safetycenter.resources:string/google_privacy_sources_title"
    summary="@com.google.android.safetycenter.resources:string/google_privacy_sources_summary"
    statelessIconType="privacy">
    <static-safety-source
        id="AndroidPermissionUsage"
        profile="primary_profile_only"
        intentAction="android.intent.action.REVIEW_PERMISSION_USAGE"
        title="@com.google.android.safetycenter.resources:string/google_permission_usage_title"
        summary="@com.google.android.safetycenter.resources:string/google_permission_usage_summary"
        searchTerms="@com.google.android.safetycenter.resources:string/google_permission_usage_search_terms"/>
    <static-safety-source
        id="AndroidPermissionManager"
        profile="primary_profile_only"
        intentAction="android.intent.action.MANAGE_PERMISSIONS"
        title="@com.google.android.safetycenter.resources:string/google_permission_manager_title"
        summary="@com.google.android.safetycenter.resources:string/google_permission_manager_summary"
        searchTerms="@com.google.android.safetycenter.resources:string/google_permission_manager_search_terms"/>
    <static-safety-source
        id="AndroidPrivacyControls"
        profile="primary_profile_only"
        intentAction="android.settings.PRIVACY_CONTROLS"
        title="@com.google.android.safetycenter.resources:string/google_privacy_controls_title"
        summary="@com.google.android.safetycenter.resources:string/google_privacy_controls_summary"
        searchTerms="@com.google.android.safetycenter.resources:string/google_privacy_controls_search_terms"/>
    <issue-only-safety-source
        id="AndroidAccessibility"
        packageName="com.google.android.permissioncontroller"
        profile="all_profiles"
        refreshOnPageOpenAllowed="true"/>
    <issue-only-safety-source
        id="AndroidNotificationListener"
        packageName="com.google.android.permissioncontroller"
        profile="primary_profile_only"
        refreshOnPageOpenAllowed="true"/>
    <issue-only-safety-source
        id="AndroidBackgroundLocation"
        packageName="com.google.android.permissioncontroller"
        profile="all_profiles"
        refreshOnPageOpenAllowed="true"/>
    <issue-only-safety-source
        id="AndroidPermissionAutoRevoke"
        packageName="com.google.android.permissioncontroller"
        profile="all_profiles"
        refreshOnPageOpenAllowed="true"/>
</safety-sources-group>

Such a group will show as rigid list of entries in the UI.

Hidden group

A hidden group contains only issue-only safety sources and doesn't have a title. Hidden groups aren't surfaced in the UI:

<safety-sources-group
    id="HiddenGroup">
    <issue-only-safety-source
        id="AndroidAccessibility"
        packageName="com.google.android.permissioncontroller"
        profile="all_profiles"
        refreshOnPageOpenAllowed="true"/>
</safety-sources-group>

Dynamic data for a static entry

You can display the dynamic Safety Center source as a static entry, which allows pushing redirection entries depending on some conditions, and allows customizing its content at runtime. Define the dynamic source within a stateless group, for example, depending on your work policy info entry.

This example shows a dynamic safety source that doesn't provide a safety signal, because it's in a stateless group:

<safety-sources-group
    id="AndroidAdvancedSources"
    title="@com.google.android.safetycenter.resources:string/google_advanced_title">
    <dynamic-safety-source
        id="AndroidWorkPolicyInfo"
        packageName="com.google.android.permissioncontroller"
        profile="primary_profile_only"
        initialDisplayState="hidden"
        refreshOnPageOpenAllowed="true"/>
            <!-- … -->
</safety-sources-group>

In this example, the source can push only green warning cards and provide an unspecified status. To be able to provide other data, the source must be within a stateful group.

Customize strings and overlay fields

For GMS devices that aren't configured to receive Mainline updates, instead of overlaying the whole configuration file, you can overlay six string resources to meet all customization needs. The string resources that are overlay are listed in the table.

String resource Description
google_lock_screen_sources_summary Overlay this value to define a static summary that's displayed for the AndroidLockScreenSources group when all sources in the group are in a good state (information or unspecified severity level). By default, Safety Center displays the title of all sources in the group concatenated as the summary for the group.
google_biometrics_title Overlay this value to define a static title for the biometric source owned by the com.android.settings package used when no dynamic data is provided by the source. Overlay this when also overlaying the title dynamically provided by the source in the com.android.settings package. This is ignored by default because the initial display state for the source is hidden.
google_biometrics_summary Overlay this value to define a static summary for the biometric source owned by the com.android.settings package used when no dynamic data is provided by the source. This is ignored by default because the initial display state for the source is hidden.
google_biometrics_search_terms Overlay this value to define a list of search terms for the biometric source owned by the com.android.settings package.
google_biometrics_initial_display_state Overlay this value to show a UI entry for the biometric source owned by the com.android.settings package when no dynamic data is provided by the source. The default value is hidden.
google_security_updates_intent Overlay this value to change the intent needed to open the activity that allows the user to check and install security updates. This intent action must be associated with an exported activity. The default value is android.settings.SYSTEM_UPDATE_SETTINGS.

No other strings in the com.google.android.safetycenter.resources package are overlayable.

For AOSP devices, all resources in the com.android.safetycenter.resources package are overlayable with no restriction on the content.

For GMS devices that aren't configured to receive Mainline updates, create a com.google.android.safetycenter.resources package replacing or overlaying com.android.safetycenter.resources defining all the strings expected by the GTS tests.

These strings are:

  • google_app_security_sources_title
  • google_app_security_sources_summary
  • google_play_protect_title
  • google_play_protect_title_for_work
  • google_play_protect_summary
  • google_play_protect_search_terms
  • google_lock_screen_sources_title
  • google_lock_screen_sources_summary
  • google_lock_screen_title
  • google_lock_screen_summary
  • google_lock_screen_search_terms
  • google_biometrics_title
  • google_biometrics_summary
  • google_biometrics_search_terms
  • google_biometrics_initial_display_state
  • google_accounts_sources_title
  • google_accounts_sources_summary
  • google_security_checkup_title
  • google_security_checkup_title_for_work
  • google_security_checkup_summary
  • google_security_checkup_search_terms
  • google_device_finder_sources_title
  • google_device_finder_sources_summary
  • google_find_my_device_title
  • google_find_my_device_summary
  • google_find_my_device_search_terms
  • google_updates_title
  • google_updates_summary
  • google_security_updates_title
  • google_security_updates_summary
  • google_security_updates_search_terms
  • google_security_updates_intent
  • google_play_system_update_title
  • google_play_system_update_summary
  • google_play_system_update_search_terms
  • google_privacy_sources_title
  • google_privacy_sources_summary
  • google_permission_usage_title
  • google_permission_usage_summary
  • google_permission_usage_search_terms
  • google_permission_manager_title
  • google_permission_manager_summary
  • google_permission_manager_search_terms
  • google_privacy_controls_title
  • google_privacy_controls_summary
  • google_privacy_controls_search_terms
  • google_advanced_title
  • google_advanced_security_title
  • google_advanced_security_summary
  • google_advanced_security_search_terms
  • google_advanced_privacy_title
  • google_advanced_privacy_summary
  • google_advanced_privacy_search_terms

Customization Requirements

File format requirements

The configuration file must be an XML file and follow the format described in Update the configuration file. The file must be in the raw folder. It must meet the invariants described in Customize Safety Center sources and Customize Safety Center sources groups. If the configuration file isn't well formed in line with the above requirements, the feature is disabled completely. Parsing this file is also backed by CTS and GTS tests that can provide additional context in case the file isn't well formed (on top of the logcat device logs).

Google services devices

On GMS devices, some constraints are imposed on this file. This is supported by GTS tests.

AOSP devices

On AOSP devices, the configuration file must be well formed and pass the CTS tests for Safety Center. The tests verify that the file is well formed. GMS devices must also pass these tests.