Create MoreSecurtiyPrivacyFragment

Created a new MoreSecurityPrivacyFragment, a new
more_security_privacy_settings xml.
This more_security_privacy_settings xml is a created by merging
privacy_advanced_settings.xml and security_advanced_settings.xml and the
MoreSecurityPrivacyFragment is created by merging
PrivacyDashboardFragment and SecurityAdvancedSettings fragments.

Test: adb shell am start -a com.android.settings.security.MORE_SECURITY_PRIVACY_SETTINGS
Bug: b/261557620
Change-Id: I8729f4eaf25a31f91354383e7b6cb5e0fc7df976
This commit is contained in:
Prabal Singh
2022-12-06 14:28:10 +00:00
parent 43eb9f8fc9
commit 52ba133285
15 changed files with 889 additions and 121 deletions

View File

@@ -1875,6 +1875,20 @@
android:value="@string/menu_key_security"/> android:value="@string/menu_key_security"/>
</activity> </activity>
<activity
android:name="Settings$MoreSecurityPrivacySettingsActivity"
android:label="@string/more_security_privacy_settings"
android:exported="true">
<intent-filter android:priority="1">
<action android:name="com.android.settings.MORE_SECURITY_PRIVACY_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.safetycenter.MoreSecurityPrivacyFragment" />
<meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
android:value="@string/menu_key_safety_center"/>
</activity>
<activity android:name="MonitoringCertInfoActivity" <activity android:name="MonitoringCertInfoActivity"
android:label="" android:label=""
android:theme="@style/Transparent" android:theme="@style/Transparent"

View File

@@ -1010,6 +1010,15 @@
<!-- Title for the section that has additional privacy settings. [CHAR LIMIT=60] --> <!-- Title for the section that has additional privacy settings. [CHAR LIMIT=60] -->
<string name="privacy_advanced_settings">More privacy settings</string> <string name="privacy_advanced_settings">More privacy settings</string>
<!-- Title for the subpage in the "Security & privacy". This page consists of the more security and privacy settings. Can be navigated by Settings -> Security & privacy -> More Settings [CHAR LIMIT=NONE] -->
<string name="more_security_privacy_settings">More settings</string>
<!-- Title for the section that has security entries in the More Settings page. [CHAR LIMIT=60] -->
<string name="security_header">Security</string>
<!-- Title for the section that has privacy entries in the More Settings page. [CHAR LIMIT=60] -->
<string name="privacy_header">Privacy</string>
<!-- Title for the section that has work profile entries in the More Settings page. [CHAR LIMIT=60] -->
<string name="work_profile_category_header">Work profile</string>
<!-- Text shown when "Add fingerprint" button is disabled --> <!-- Text shown when "Add fingerprint" button is disabled -->
<string name="fingerprint_add_max">You can add up to <xliff:g id="count" example="5">%d</xliff:g> fingerprints</string> <string name="fingerprint_add_max">You can add up to <xliff:g id="count" example="5">%d</xliff:g> fingerprints</string>
<!-- Text shown when users has enrolled a maximum number of fingerprints [CHAR LIMIT=NONE] --> <!-- Text shown when users has enrolled a maximum number of fingerprints [CHAR LIMIT=NONE] -->

View File

@@ -0,0 +1,227 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="more_security_privacy_settings"
android:title="@string/more_security_privacy_settings">
<!-- work profile security section. See also: security_advanced_settings.xml and
privacy_advanced_settings.xml. That page also has some duplicate entries -->
<PreferenceCategory
android:order="10"
android:key="work_profile_category"
android:title="@string/work_profile_category_header">
<!-- security_settings_unification -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="unification"
android:title="@string/lock_settings_profile_unification_title"
android:summary="@string/lock_settings_profile_unification_summary"
settings:keywords="@string/keywords_unification" />
<com.android.settingslib.RestrictedPreference
android:key="unlock_set_or_change_profile"
android:title="@string/unlock_set_unlock_launch_picker_title_profile"
android:summary="@string/unlock_set_unlock_mode_pattern"
settings:keywords="@string/keywords_lockscreen" />
<SwitchPreference
android:key="visiblepattern_profile"
android:title="@string/lockpattern_settings_enable_visible_pattern_title_profile" />
<com.android.settingslib.RestrictedPreference
android:key="fingerprint_settings_profile"
android:title="@string/security_settings_work_fingerprint_preference_title"
android:summary="@string/summary_placeholder" />
<com.android.settingslib.RestrictedPreference
android:key="face_settings_profile"
android:title="@string/security_settings_face_preference_title"
android:summary="@string/summary_placeholder" />
<com.android.settingslib.RestrictedPreference
android:key="biometric_settings_profile"
android:title="@string/security_settings_biometric_preference_title"
android:summary="@string/summary_placeholder" />
</PreferenceCategory>
<PreferenceCategory
android:key="privacy_work_profile_notifications_category"
android:title="@string/profile_section_header_for_advanced_privacy"
android:layout="@layout/preference_category_no_label"
android:order="20">
<com.android.settings.RestrictedListPreference
android:key="privacy_lock_screen_work_profile_notifications"
android:title="@string/locked_work_profile_notification_title"
android:summary="@string/summary_placeholder"
android:order="21"
settings:searchable="false"/>
</PreferenceCategory>
<!-- Connected work and personal apps -->
<Preference
android:key="interact_across_profiles_privacy"
android:title="@string/interact_across_profiles_title"
android:order="25"
android:fragment="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesSettings"
settings:searchable="false"
settings:controller="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesController" />
<!-- Main security section - for trust agents added in code. -->
<PreferenceCategory
android:order="30"
android:key="security_category"
android:title="@string/security_header" />
<PreferenceCategory
android:order="40"
android:key="security_settings_device_admin_category"
android:layout="@layout/preference_category_no_label">
<Preference
android:key="manage_device_admin"
android:title="@string/manage_device_admin"
android:summary="@string/summary_placeholder"
android:fragment=
"com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings"
settings:controller=
"com.android.settings.enterprise.ManageDeviceAdminPreferenceController" />
<Preference
android:key="enterprise_privacy"
android:title="@string/enterprise_privacy_settings"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"
settings:controller="com.android.settings.enterprise.EnterprisePrivacyPreferenceController"/>
<Preference
android:key="financed_privacy"
android:title="@string/financed_privacy_settings"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"
settings:controller="com.android.settings.enterprise.FinancedPrivacyPreferenceController"/>
</PreferenceCategory>
<Preference
android:order="50"
android:key="sim_lock_settings"
android:title="@string/sim_lock_settings_category"
settings:isPreferenceVisible="@bool/config_show_sim_info"
settings:controller="com.android.settings.security.SimLockPreferenceController">
<intent
android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.Settings$IccLockSettingsActivity" />
</Preference>
<Preference
android:order="60"
android:key="encryption_and_credential"
android:title="@string/encryption_and_credential_settings_title"
android:summary="@string/encryption_and_credential_settings_summary"
android:fragment="com.android.settings.security.EncryptionAndCredential"
settings:controller="com.android.settings.security.EncryptionStatusPreferenceController" />
<Preference
android:order="70"
android:key="manage_trust_agents"
android:title="@string/manage_trust_agents"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.security.trustagent.TrustAgentSettings"
settings:controller="com.android.settings.security.trustagent.ManageTrustAgentsPreferenceController" />
<Preference
android:order="80"
android:key="screen_pinning_settings"
android:title="@string/screen_pinning_title"
android:summary="@string/summary_placeholder"
android:fragment="com.android.settings.security.ScreenPinningSettings"
settings:keywords="@string/keywords_app_pinning"
settings:controller="com.android.settings.security.ScreenPinningPreferenceController" />
<SwitchPreference
android:order="90"
android:key="confirm_sim_deletion"
android:title="@string/confirm_sim_deletion_title"
android:summary="@string/confirm_sim_deletion_description"
settings:isPreferenceVisible="@bool/config_show_sim_info"
settings:controller="com.android.settings.security.ConfirmSimDeletionPreferenceController" />
<Preference
android:order="100"
android:id="@+id/memtag_page"
android:key="memtag_page"
android:title="@string/memtag_title"
android:fragment="com.android.settings.security.MemtagPage"
settings:controller="com.android.settings.security.MemtagPagePreferenceController" />
<!-- Privacy section -->
<PreferenceCategory
android:order="200"
android:key="privacy_category"
android:title="@string/privacy_header">
<!-- Accessibility usage -->
<Preference
android:key="privacy_accessibility_usage"
android:title="@string/accessibility_usage_title"
settings:controller="com.android.settings.privacy.AccessibilityUsagePreferenceController">
<intent android:action="android.intent.action.REVIEW_ACCESSIBILITY_SERVICES"/>
</Preference>
<!-- On lock screen notifications -->
<com.android.settings.RestrictedListPreference
android:key="privacy_lock_screen_notifications"
android:title="@string/lock_screen_notifs_title"
android:summary="@string/summary_placeholder"
settings:searchable="false"/>
<!-- Show media on lock screen -->
<SwitchPreference
android:key="privacy_media_controls_lockscreen"
android:title="@string/media_controls_lockscreen_title"
android:summary="@string/media_controls_lockscreen_description"
settings:controller=
"com.android.settings.sound.MediaControlsLockScreenPreferenceController" />
<!-- Content Capture -->
<!-- NOTE: content capture has a different preference, depending whether or not the
ContentCaptureService implementations defines a custom settings activitiy on its manifest.
Hence, we show both here, but the controller itself will decide if it's available or not.
-->
<SwitchPreference
android:key="content_capture"
android:title="@string/content_capture"
android:summary="@string/content_capture_summary"
settings:controller="com.android.settings.privacy.EnableContentCapturePreferenceController"/>
<com.android.settingslib.PrimarySwitchPreference
android:key="content_capture_custom_settings"
android:title="@string/content_capture"
android:summary="@string/content_capture_summary"
settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -110,7 +110,7 @@
<!-- work profile security section --> <!-- work profile security section -->
<PreferenceCategory <PreferenceCategory
android:order="110" android:order="110"
android:key="security_category_profile" android:key="work_profile_category"
android:title="@string/lock_settings_profile_title"> android:title="@string/lock_settings_profile_title">
<!-- security_settings_unification --> <!-- security_settings_unification -->

View File

@@ -209,6 +209,8 @@ public class Settings extends SettingsActivity {
} }
/** Activity for the Advanced security settings. */ /** Activity for the Advanced security settings. */
public static class SecurityAdvancedSettings extends SettingsActivity { /* empty */ } public static class SecurityAdvancedSettings extends SettingsActivity { /* empty */ }
/** Activity for the More settings page. */
public static class MoreSecurityPrivacySettingsActivity extends SettingsActivity { /* empty */ }
public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class UsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class AppUsageAccessSettingsActivity extends SettingsActivity { /* empty */ } public static class AppUsageAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocationSettingsActivity extends SettingsActivity { /* empty */ } public static class LocationSettingsActivity extends SettingsActivity { /* empty */ }

View File

@@ -165,6 +165,7 @@ import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.privacy.PrivacyControlsFragment; import com.android.settings.privacy.PrivacyControlsFragment;
import com.android.settings.privacy.PrivacyDashboardFragment; import com.android.settings.privacy.PrivacyDashboardFragment;
import com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment; import com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment;
import com.android.settings.safetycenter.MoreSecurityPrivacyFragment;
import com.android.settings.security.LockscreenDashboardFragment; import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.MemtagPage; import com.android.settings.security.MemtagPage;
import com.android.settings.security.SecurityAdvancedSettings; import com.android.settings.security.SecurityAdvancedSettings;
@@ -240,6 +241,7 @@ public class SettingsGateway {
LocationServices.class.getName(), LocationServices.class.getName(),
SecuritySettings.class.getName(), SecuritySettings.class.getName(),
SecurityAdvancedSettings.class.getName(), SecurityAdvancedSettings.class.getName(),
MoreSecurityPrivacyFragment.class.getName(),
UsageAccessDetails.class.getName(), UsageAccessDetails.class.getName(),
PrivacySettings.class.getName(), PrivacySettings.class.getName(),
DeviceAdminSettings.class.getName(), DeviceAdminSettings.class.getName(),

View File

@@ -16,12 +16,6 @@
package com.android.settings.privacy; package com.android.settings.privacy;
import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_WORK_AND_PERSONAL_APPS_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCKED_NOTIFICATION_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PRIVACY_POLICY_INFO;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
@@ -32,23 +26,20 @@ import android.provider.SearchIndexableResource;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.safetycenter.SafetyCenterManagerWrapper; import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
import com.android.settings.safetycenter.SafetyCenterUtils;
import com.android.settings.safetycenter.SafetyCenterUtils.EnterpriseOverrideString;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@SearchIndexable @SearchIndexable
public class PrivacyDashboardFragment extends DashboardFragment { public class PrivacyDashboardFragment extends DashboardFragment {
private static final String TAG = "PrivacyDashboardFrag"; private static final String TAG = "PrivacyDashboardFrag";
private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "privacy_lock_screen_notifications";
private static final String KEY_WORK_PROFILE_CATEGORY =
"privacy_work_profile_notifications_category";
private static final String KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS = private static final String KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS =
"privacy_lock_screen_work_profile_notifications"; "privacy_lock_screen_work_profile_notifications";
@@ -65,18 +56,13 @@ public class PrivacyDashboardFragment extends DashboardFragment {
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
replaceEnterpriseStringTitle("privacy_lock_screen_work_profile_notifications", List<EnterpriseOverrideString> privacyOverrideStrings =
WORK_PROFILE_LOCKED_NOTIFICATION_TITLE, SafetyCenterUtils.getEnterpriseOverrideStringForPrivacyEntries();
R.string.locked_work_profile_notification_title); for (int i = 0; i < privacyOverrideStrings.size(); i++) {
replaceEnterpriseStringTitle("interact_across_profiles_privacy", EnterpriseOverrideString overrideString = privacyOverrideStrings.get(i);
CONNECTED_WORK_AND_PERSONAL_APPS_TITLE, R.string.interact_across_profiles_title); replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
replaceEnterpriseStringTitle("privacy_work_profile_notifications_category", overrideString.getOverrideKey(), overrideString.getResource());
WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER, R.string.profile_section_header); }
replaceEnterpriseStringTitle("work_policy_info",
WORK_PROFILE_PRIVACY_POLICY_INFO, R.string.work_policy_privacy_settings);
replaceEnterpriseStringSummary("work_policy_info",
WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY,
R.string.work_policy_privacy_settings_summary);
} }
@Override @Override
@@ -104,26 +90,21 @@ public class PrivacyDashboardFragment extends DashboardFragment {
private static List<AbstractPreferenceController> buildPreferenceControllers( private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context, Lifecycle lifecycle) { Context context, Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>(); return SafetyCenterUtils.getControllersForAdvancedPrivacy(context, lifecycle);
final LockScreenNotificationPreferenceController notificationController =
new LockScreenNotificationPreferenceController(context,
KEY_LOCK_SCREEN_NOTIFICATIONS,
KEY_WORK_PROFILE_CATEGORY,
KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS);
if (lifecycle != null) {
lifecycle.addObserver(notificationController);
}
controllers.add(notificationController);
return controllers;
} }
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() { new BaseSearchIndexProvider() {
/**
* If SafetyCenter is enabled, all of these entries will be in the More Settings
* page, and we don't want to index these entries.
*/
@Override @Override
public List<SearchIndexableResource> getXmlResourcesToIndex( public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) { Context context, boolean enabled) {
if (SafetyCenterManagerWrapper.get().isEnabled(context)) {
return null;
}
final SearchIndexableResource sir = new SearchIndexableResource(context); final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = getPreferenceScreenResId(context); sir.xmlResId = getPreferenceScreenResId(context);
return Arrays.asList(sir); return Arrays.asList(sir);

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.safetycenter;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.safetycenter.SafetyCenterUtils.EnterpriseOverrideString;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.security.LockUnificationPreferenceController;
import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
/**
* An overflow menu for {@code SecuritySettings} containing advanced security and privacy settings.
*
* <p>This also includes all work-profile related settings.
*/
@SearchIndexable
public class MoreSecurityPrivacyFragment extends DashboardFragment {
private static final String TAG = "MoreSecurityPrivacyFragment";
private static final String KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS =
"privacy_lock_screen_work_profile_notifications";
@Override
public int getMetricsCategory() {
return SettingsEnums.MORE_SECURITY_PRIVACY_SETTINGS;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.more_security_privacy_settings;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
List<EnterpriseOverrideString> privacyOverrideStrings =
SafetyCenterUtils.getEnterpriseOverrideStringForPrivacyEntries();
for (int i = 0; i < privacyOverrideStrings.size(); i++) {
EnterpriseOverrideString overrideString = privacyOverrideStrings.get(i);
replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
overrideString.getOverrideKey(), overrideString.getResource());
}
List<EnterpriseOverrideString> securityOverrideStrings =
SafetyCenterUtils.getEnterpriseOverrideStringForSecurityEntries();
for (int i = 0; i < securityOverrideStrings.size(); i++) {
EnterpriseOverrideString overrideString = securityOverrideStrings.get(i);
replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
overrideString.getOverrideKey(), overrideString.getResource());
}
}
/**
* see confirmPatternThenDisableAndClear
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (use(TrustAgentListPreferenceController.class)
.handleActivityResult(requestCode, resultCode)) {
return;
}
if (use(LockUnificationPreferenceController.class)
.handleActivityResult(requestCode, resultCode, data)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getSettingsLifecycle(), this /* host*/);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context, Lifecycle lifecycle, DashboardFragment host) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.addAll(SafetyCenterUtils.getControllersForAdvancedPrivacy(context, lifecycle));
controllers.addAll(
SafetyCenterUtils.getControllersForAdvancedSecurity(context, lifecycle, host));
return controllers;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.more_security_privacy_settings) {
/**
* If SafetyCenter is disabled, all of these entries will be in the More Security
* Settings and the Privacy page, and we don't want to index these entries.
*/
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
if (!SafetyCenterManagerWrapper.get().isEnabled(context)) {
return null;
}
return super.getXmlResourcesToIndex(context, enabled);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null, null);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
final int profileUserId =
Utils.getManagedProfileId(
UserManager.get(context), UserHandle.myUserId());
// If work profile is supported, we should keep the search result.
if (profileUserId != UserHandle.USER_NULL) {
return keys;
}
// Otherwise, we should hide the search result.
keys.add(KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS);
return keys;
}
};
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.safetycenter;
import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_WORK_AND_PERSONAL_APPS_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_FOR_WORK;
import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_DEVICE_INFO;
import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGE_DEVICE_ADMIN_APPS;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCKED_NOTIFICATION_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PRIVACY_POLICY_INFO;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SECURITY_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFY_LOCKS_SUMMARY;
import android.annotation.StringRes;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.biometrics.combination.CombinedBiometricProfileStatusPreferenceController;
import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController;
import com.android.settings.biometrics.fingerprint.FingerprintProfileStatusPreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.privacy.PrivacyDashboardFragment;
import com.android.settings.security.ChangeProfileScreenLockPreferenceController;
import com.android.settings.security.LockUnificationPreferenceController;
import com.android.settings.security.VisiblePatternProfilePreferenceController;
import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
/**
* A class with helper method used in logic involving safety center.
*/
public final class SafetyCenterUtils {
/**
* Returns preference controllers related to advanced security entries.
* This is used in {@link MoreSecurityPrivacyFragment} and
* {@link com.android.settings.security.SecurityAdvancedSettings}.
*/
public static List<AbstractPreferenceController> getControllersForAdvancedSecurity(
Context context,
com.android.settingslib.core.lifecycle.Lifecycle lifecycle, DashboardFragment host) {
final String WORK_PROFILE_SECURITY_CATEGORY = "work_profile_category";
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new TrustAgentListPreferenceController(context, host, lifecycle));
final List<AbstractPreferenceController> profileSecurityControllers = new ArrayList<>();
profileSecurityControllers.add(new ChangeProfileScreenLockPreferenceController(
context, host));
profileSecurityControllers.add(new LockUnificationPreferenceController(context, host));
profileSecurityControllers.add(new VisiblePatternProfilePreferenceController(
context, lifecycle));
profileSecurityControllers.add(new FaceProfileStatusPreferenceController(
context, lifecycle));
profileSecurityControllers.add(new FingerprintProfileStatusPreferenceController(
context, lifecycle));
profileSecurityControllers
.add(new CombinedBiometricProfileStatusPreferenceController(context, lifecycle));
controllers.add(new PreferenceCategoryController(context, WORK_PROFILE_SECURITY_CATEGORY)
.setChildren(profileSecurityControllers));
controllers.addAll(profileSecurityControllers);
return controllers;
}
/**
* Returns preference controllers for advanced privacy entries.
* This is used in {@link MoreSecurityPrivacyFragment} and {@link PrivacyDashboardFragment}.
*/
public static List<AbstractPreferenceController> getControllersForAdvancedPrivacy(
Context context, com.android.settingslib.core.lifecycle.Lifecycle lifecycle) {
final String KEY_LOCK_SCREEN_NOTIFICATIONS = "privacy_lock_screen_notifications";
final String KEY_WORK_PROFILE_CATEGORY =
"privacy_work_profile_notifications_category";
final String KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS =
"privacy_lock_screen_work_profile_notifications";
final List<AbstractPreferenceController> controllers = new ArrayList<>();
final LockScreenNotificationPreferenceController notificationController =
new LockScreenNotificationPreferenceController(context,
KEY_LOCK_SCREEN_NOTIFICATIONS,
KEY_WORK_PROFILE_CATEGORY,
KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS);
if (lifecycle != null) {
lifecycle.addObserver(notificationController);
}
controllers.add(notificationController);
return controllers;
}
/**
* A class that stores the resource that will be overridden using preferenceKey and overrideKey.
*/
public static final class EnterpriseOverrideString {
private final String mPreferenceKey;
private final String mOverrideKey;
@StringRes private final int mResource;
public EnterpriseOverrideString(
String preferenceKey,
String overrideKey,
@StringRes int resource) {
this.mPreferenceKey = preferenceKey;
this.mOverrideKey = overrideKey;
this.mResource = resource;
}
@StringRes
public int getResource() {
return mResource;
}
public String getPreferenceKey() {
return mPreferenceKey;
}
public String getOverrideKey() {
return mOverrideKey;
}
}
/**
* Returns a list of @{EnterpriseOverrideString} for the privacy entries.
*/
public static List<EnterpriseOverrideString> getEnterpriseOverrideStringForPrivacyEntries() {
List<EnterpriseOverrideString> enterpriseOverrideStrings = new ArrayList<>();
enterpriseOverrideStrings.add(
new EnterpriseOverrideString("privacy_lock_screen_work_profile_notifications",
WORK_PROFILE_LOCKED_NOTIFICATION_TITLE,
R.string.locked_work_profile_notification_title));
enterpriseOverrideStrings.add(
new EnterpriseOverrideString("interact_across_profiles_privacy",
CONNECTED_WORK_AND_PERSONAL_APPS_TITLE,
R.string.interact_across_profiles_title));
enterpriseOverrideStrings.add(
new EnterpriseOverrideString("privacy_work_profile_notifications_category",
WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER,
R.string.profile_section_header));
enterpriseOverrideStrings.add(new EnterpriseOverrideString("work_policy_info",
WORK_PROFILE_PRIVACY_POLICY_INFO, R.string.work_policy_privacy_settings));
enterpriseOverrideStrings.add(new EnterpriseOverrideString("work_policy_info",
WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY,
R.string.work_policy_privacy_settings_summary));
return enterpriseOverrideStrings;
}
/**
* Returns a list of @{EnterpriseOverrideString} for the security entries.
*/
public static List<EnterpriseOverrideString> getEnterpriseOverrideStringForSecurityEntries() {
List<EnterpriseOverrideString> enterpriseOverrideStrings = new ArrayList<>();
enterpriseOverrideStrings.add(new EnterpriseOverrideString("unlock_set_or_change_profile",
WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE,
R.string.unlock_set_unlock_launch_picker_title_profile));
enterpriseOverrideStrings.add(new EnterpriseOverrideString("unification",
WORK_PROFILE_UNIFY_LOCKS_SUMMARY,
R.string.lock_settings_profile_unification_summary));
enterpriseOverrideStrings.add(new EnterpriseOverrideString("fingerprint_settings_profile",
FINGERPRINT_FOR_WORK,
R.string.security_settings_work_fingerprint_preference_title));
enterpriseOverrideStrings.add(new EnterpriseOverrideString("manage_device_admin",
MANAGE_DEVICE_ADMIN_APPS, R.string.manage_device_admin));
enterpriseOverrideStrings.add(new EnterpriseOverrideString("security_category_profile",
WORK_PROFILE_SECURITY_TITLE, R.string.lock_settings_profile_title));
enterpriseOverrideStrings.add(
new EnterpriseOverrideString("enterprise_privacy", MANAGED_DEVICE_INFO,
R.string.enterprise_privacy_settings));
return enterpriseOverrideStrings;
}
private SafetyCenterUtils() {}
}

View File

@@ -16,34 +16,25 @@
package com.android.settings.security; package com.android.settings.security;
import static android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_FOR_WORK;
import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_DEVICE_INFO;
import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGE_DEVICE_ADMIN_APPS;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SECURITY_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFY_LOCKS_SUMMARY;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.provider.SearchIndexableResource;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.biometrics.combination.CombinedBiometricProfileStatusPreferenceController;
import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController;
import com.android.settings.biometrics.fingerprint.FingerprintProfileStatusPreferenceController;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.safetycenter.SafetyCenterManagerWrapper; import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
import com.android.settings.safetycenter.SafetyCenterUtils;
import com.android.settings.safetycenter.SafetyCenterUtils.EnterpriseOverrideString;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.security.trustagent.TrustAgentListPreferenceController; import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -55,7 +46,6 @@ import java.util.List;
public class SecurityAdvancedSettings extends DashboardFragment { public class SecurityAdvancedSettings extends DashboardFragment {
private static final String TAG = "SecurityAdvancedSettings"; private static final String TAG = "SecurityAdvancedSettings";
private static final String WORK_PROFILE_SECURITY_CATEGORY = "security_category_profile";
/** Used in case of old Security settings when SafetyCenter is disabled */ /** Used in case of old Security settings when SafetyCenter is disabled */
private static final String CATEGORY_SECURITY_LEGACY_ADVANCED_SETTINGS = private static final String CATEGORY_SECURITY_LEGACY_ADVANCED_SETTINGS =
@@ -64,22 +54,13 @@ public class SecurityAdvancedSettings extends DashboardFragment {
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
replaceEnterpriseStringTitle("unlock_set_or_change_profile", List<EnterpriseOverrideString> securityOverrideStrings =
WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE, SafetyCenterUtils.getEnterpriseOverrideStringForSecurityEntries();
R.string.unlock_set_unlock_launch_picker_title_profile); for (int i = 0; i < securityOverrideStrings.size(); i++) {
replaceEnterpriseStringSummary("unification", EnterpriseOverrideString overrideString = securityOverrideStrings.get(i);
WORK_PROFILE_UNIFY_LOCKS_SUMMARY, replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
R.string.lock_settings_profile_unification_summary); overrideString.getOverrideKey(), overrideString.getResource());
replaceEnterpriseStringTitle("fingerprint_settings_profile", }
FINGERPRINT_FOR_WORK,
R.string.security_settings_work_fingerprint_preference_title);
replaceEnterpriseStringTitle("manage_device_admin",
MANAGE_DEVICE_ADMIN_APPS, R.string.manage_device_admin);
replaceEnterpriseStringTitle("security_category_profile",
WORK_PROFILE_SECURITY_TITLE, R.string.lock_settings_profile_title);
replaceEnterpriseStringTitle("enterprise_privacy", MANAGED_DEVICE_INFO,
R.string.enterprise_privacy_settings);
} }
@Override @Override
@@ -140,26 +121,7 @@ public class SecurityAdvancedSettings extends DashboardFragment {
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context, private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle, DashboardFragment host) { Lifecycle lifecycle, DashboardFragment host) {
final List<AbstractPreferenceController> controllers = new ArrayList<>(); return SafetyCenterUtils.getControllersForAdvancedSecurity(context, lifecycle, host);
controllers.add(new TrustAgentListPreferenceController(context, host, lifecycle));
final List<AbstractPreferenceController> profileSecurityControllers = new ArrayList<>();
profileSecurityControllers.add(new ChangeProfileScreenLockPreferenceController(
context, host));
profileSecurityControllers.add(new LockUnificationPreferenceController(context, host));
profileSecurityControllers.add(new VisiblePatternProfilePreferenceController(
context, lifecycle));
profileSecurityControllers.add(new FaceProfileStatusPreferenceController(
context, lifecycle));
profileSecurityControllers.add(new FingerprintProfileStatusPreferenceController(
context, lifecycle));
profileSecurityControllers
.add(new CombinedBiometricProfileStatusPreferenceController(context, lifecycle));
controllers.add(new PreferenceCategoryController(context, WORK_PROFILE_SECURITY_CATEGORY)
.setChildren(profileSecurityControllers));
controllers.addAll(profileSecurityControllers);
return controllers;
} }
/** /**
@@ -167,6 +129,18 @@ public class SecurityAdvancedSettings extends DashboardFragment {
*/ */
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.security_advanced_settings) { new BaseSearchIndexProvider(R.xml.security_advanced_settings) {
/**
* If SafetyCenter is enabled, all of these entries will be in the More Settings
* page, and we don't want to index these entries.
*/
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
if (SafetyCenterManagerWrapper.get().isEnabled(context)) {
return null;
}
return super.getXmlResourcesToIndex(context, enabled);
}
@Override @Override
public List<AbstractPreferenceController> createPreferenceControllers(Context public List<AbstractPreferenceController> createPreferenceControllers(Context

View File

@@ -15,6 +15,21 @@
*/ */
package com.android.settings; package com.android.settings;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_INCLUDE_PREF_SCREEN;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY;
import android.annotation.XmlRes;
import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import com.android.settings.core.PreferenceXmlParserUtils;
import com.android.settings.search.BaseSearchIndexProvider;
import java.util.ArrayList;
import java.util.List;
/** /**
* Convenience methods and constants for testing. * Convenience methods and constants for testing.
*/ */
@@ -22,4 +37,30 @@ public class TestUtils {
public static final long KILOBYTE = 1024L; // TODO: Change to 1000 in O Robolectric. public static final long KILOBYTE = 1024L; // TODO: Change to 1000 in O Robolectric.
public static final long MEGABYTE = KILOBYTE * KILOBYTE; public static final long MEGABYTE = KILOBYTE * KILOBYTE;
public static final long GIGABYTE = KILOBYTE * MEGABYTE; public static final long GIGABYTE = KILOBYTE * MEGABYTE;
public static List<String> getAllXmlKeys(
Context context, BaseSearchIndexProvider indexProvider)
throws Exception {
final List<SearchIndexableResource> resources = indexProvider.getXmlResourcesToIndex(
context, true /* not used*/);
if (resources == null || resources.isEmpty()) {
return new ArrayList<>();
}
final List<String> keys = new ArrayList<>();
for (SearchIndexableResource res : resources) {
keys.addAll(getKeysFromXml(res.xmlResId, context));
}
return keys;
}
private static List<String> getKeysFromXml(@XmlRes int xmlResId, Context context)
throws Exception {
final List<String> keys = new ArrayList<>();
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(context, xmlResId,
FLAG_NEED_KEY | FLAG_INCLUDE_PREF_SCREEN);
for (Bundle bundle : metadata) {
keys.add(bundle.getString(METADATA_KEY));
}
return keys;
}
} }

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.privacy;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.TestUtils;
import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
import com.android.settings.search.BaseSearchIndexProvider;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
public class PrivacyDashboardFragmentTest {
private Context mContext;
private PrivacyDashboardFragment mPrivacyDashboardFragment;
@Mock
private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
@Before
@UiThreadTest
public void setUp() {
MockitoAnnotations.initMocks(this);
MockitoAnnotations.initMocks(this);
if (Looper.myLooper() == null) {
Looper.prepare();
}
mContext = ApplicationProvider.getApplicationContext();
SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
mPrivacyDashboardFragment = spy(new PrivacyDashboardFragment());
when(mPrivacyDashboardFragment.getContext()).thenReturn(mContext);
}
@Test
public void whenSafetyCenterIsEnabled_pageIndexExcluded() throws Exception {
when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(true);
BaseSearchIndexProvider indexProvider = PrivacyDashboardFragment.SEARCH_INDEX_DATA_PROVIDER;
List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
allXmlKeys.removeAll(nonIndexableKeys);
assertThat(allXmlKeys).isEmpty();
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.safetycenter;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.TestUtils;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class MoreSecurityPrivacyFragmentSettingsTest {
private static final String SCREEN_XML_RESOURCE_NAME = "more_security_privacy_settings";
private MoreSecurityPrivacyFragment mMoreSecurityPrivacyFragment;
private Context mContext;
@Mock
private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
@Before
@UiThreadTest
public void setUp() {
MockitoAnnotations.initMocks(this);
MockitoAnnotations.initMocks(this);
if (Looper.myLooper() == null) {
Looper.prepare();
}
mContext = ApplicationProvider.getApplicationContext();
SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
mMoreSecurityPrivacyFragment = spy(new MoreSecurityPrivacyFragment());
when(mMoreSecurityPrivacyFragment.getContext()).thenReturn(mContext);
}
@Test
public void getPreferenceXml_returnsMoreSecurityPrivacy() {
assertThat(mMoreSecurityPrivacyFragment.getPreferenceScreenResId())
.isEqualTo(getXmlResId(SCREEN_XML_RESOURCE_NAME));
}
@Test
public void whenSafetyCenterIsEnabled_pageIndexIncluded() throws Exception {
when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(true);
BaseSearchIndexProvider indexProvider =
MoreSecurityPrivacyFragment.SEARCH_INDEX_DATA_PROVIDER;
List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
allXmlKeys.removeAll(nonIndexableKeys);
assertThat(allXmlKeys).isNotEmpty();
}
@Test
public void whenSafetyCenterIsDisabled_pageIndexExcluded() throws Exception {
when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(false);
BaseSearchIndexProvider indexProvider =
MoreSecurityPrivacyFragment.SEARCH_INDEX_DATA_PROVIDER;
List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
allXmlKeys.removeAll(nonIndexableKeys);
assertThat(allXmlKeys).isEmpty();
}
private int getXmlResId(String resName) {
return ResourcesUtils.getResourcesId(mContext, "xml", resName);
}
}

View File

@@ -16,6 +16,7 @@
package com.android.settings.security; package com.android.settings.security;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -29,7 +30,9 @@ import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.TestUtils;
import com.android.settings.safetycenter.SafetyCenterManagerWrapper; import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.ResourcesUtils; import com.android.settings.testutils.ResourcesUtils;
import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.CategoryKey;
@@ -40,6 +43,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.List;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class SecurityAdvancedSettingsTest { public class SecurityAdvancedSettingsTest {
private static final String SCREEN_XML_RESOURCE_NAME = "security_advanced_settings"; private static final String SCREEN_XML_RESOURCE_NAME = "security_advanced_settings";
@@ -100,6 +105,18 @@ public class SecurityAdvancedSettingsTest {
.isEqualTo(LEGACY_CATEGORY_KEY); .isEqualTo(LEGACY_CATEGORY_KEY);
} }
@Test
public void whenSafetyCenterIsEnabled_pageIndexExcluded() throws Exception {
when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(false);
BaseSearchIndexProvider indexProvider = SecurityAdvancedSettings.SEARCH_INDEX_DATA_PROVIDER;
List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
allXmlKeys.removeAll(nonIndexableKeys);
assertThat(allXmlKeys).isEmpty();
}
private int getXmlResId(String resName) { private int getXmlResId(String resName) {
return ResourcesUtils.getResourcesId(mContext, "xml", resName); return ResourcesUtils.getResourcesId(mContext, "xml", resName);
} }

View File

@@ -21,24 +21,18 @@ import static android.content.Context.FINGERPRINT_SERVICE;
import static android.content.pm.PackageManager.FEATURE_FACE; import static android.content.pm.PackageManager.FEATURE_FACE;
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_INCLUDE_PREF_SCREEN;
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.annotation.XmlRes;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.hardware.face.FaceManager; import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.Looper; import android.os.Looper;
import android.provider.SearchIndexableResource;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -48,10 +42,11 @@ import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.TestUtils;
import com.android.settings.biometrics.combination.CombinedBiometricStatusPreferenceController; import com.android.settings.biometrics.combination.CombinedBiometricStatusPreferenceController;
import com.android.settings.biometrics.face.FaceStatusPreferenceController; import com.android.settings.biometrics.face.FaceStatusPreferenceController;
import com.android.settings.biometrics.fingerprint.FingerprintStatusPreferenceController; import com.android.settings.biometrics.fingerprint.FingerprintStatusPreferenceController;
import com.android.settings.core.PreferenceXmlParserUtils; import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.security.trustagent.TrustAgentManager; import com.android.settings.security.trustagent.TrustAgentManager;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
@@ -64,7 +59,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@@ -85,6 +79,8 @@ public class SecuritySettingsTest {
private FingerprintManager mFingerprintManager; private FingerprintManager mFingerprintManager;
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@Mock
private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
private PreferenceScreen mScreen; private PreferenceScreen mScreen;
@@ -96,6 +92,7 @@ public class SecuritySettingsTest {
} }
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
mContext = spy(ApplicationProvider.getApplicationContext()); mContext = spy(ApplicationProvider.getApplicationContext());
when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.hasSystemFeature(FEATURE_FACE)).thenReturn(true); when(mPackageManager.hasSystemFeature(FEATURE_FACE)).thenReturn(true);
@@ -132,12 +129,14 @@ public class SecuritySettingsTest {
} }
@Test @Test
public void noAlternativeFragmentAvailable_pageIndexIncluded() throws Exception { public void noAlternativeFragmentAvailableAndSafetyCenterIsDisabled_pageIndexIncluded()
throws Exception {
when(mSecuritySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment()).thenReturn( when(mSecuritySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment()).thenReturn(
false); false);
when(mSafetyCenterManagerWrapper.isEnabled(any())).thenReturn(false);
BaseSearchIndexProvider indexProvider = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER; BaseSearchIndexProvider indexProvider = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER;
List<String> allXmlKeys = getAllXmlKeys(indexProvider); List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext); List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
allXmlKeys.removeAll(nonIndexableKeys); allXmlKeys.removeAll(nonIndexableKeys);
@@ -150,7 +149,7 @@ public class SecuritySettingsTest {
true); true);
BaseSearchIndexProvider indexProvider = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER; BaseSearchIndexProvider indexProvider = SecuritySettings.SEARCH_INDEX_DATA_PROVIDER;
List<String> allXmlKeys = getAllXmlKeys(indexProvider); List<String> allXmlKeys = TestUtils.getAllXmlKeys(mContext, indexProvider);
List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext); List<String> nonIndexableKeys = indexProvider.getNonIndexableKeys(mContext);
allXmlKeys.removeAll(nonIndexableKeys); allXmlKeys.removeAll(nonIndexableKeys);
@@ -340,29 +339,6 @@ public class SecuritySettingsTest {
assertThat(mPreferenceCombined.isVisible()).isFalse(); assertThat(mPreferenceCombined.isVisible()).isFalse();
} }
private List<String> getAllXmlKeys(BaseSearchIndexProvider indexProvider) throws Exception {
final List<SearchIndexableResource> resources = indexProvider.getXmlResourcesToIndex(
mContext, true /* not used*/);
if (resources == null || resources.isEmpty()) {
return new ArrayList<>();
}
final List<String> keys = new ArrayList<>();
for (SearchIndexableResource res : resources) {
keys.addAll(getKeysFromXml(res.xmlResId));
}
return keys;
}
private List<String> getKeysFromXml(@XmlRes int xmlResId) throws Exception {
final List<String> keys = new ArrayList<>();
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext, xmlResId,
FLAG_NEED_KEY | FLAG_INCLUDE_PREF_SCREEN);
for (Bundle bundle : metadata) {
keys.add(bundle.getString(METADATA_KEY));
}
return keys;
}
boolean isFacePrefAvailable(List<AbstractPreferenceController> controllers) { boolean isFacePrefAvailable(List<AbstractPreferenceController> controllers) {
return controllers.stream().filter( return controllers.stream().filter(
controller -> controller instanceof FaceStatusPreferenceController controller -> controller instanceof FaceStatusPreferenceController