Implement "More privacy settings"
Safety Center is enabled, the existing "Privacy" screen will be
different in a few ways:
1. Its title will become "More privacy settings"
2. A few preferences will be hidden
3. A few preferences will be reworded
4. The ordering of a few preferences will change
5. The PRIVACY_SETTINGS intent will now point to Safety Center;
PRIVACY_ADVANCED_SETTINGS will point to "More privacy settings".
Test: manual
Bug: 222127397
Change-Id: I74faf770babb34f775b2ef572248e550ea683ab3
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9ab0cc2..d684567 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1297,7 +1297,10 @@
<string name="security_advanced_settings_no_work_profile_settings_summary">Encryption, credentials, and more</string>
<!-- Search keywords for the "More security settings" section in security settings. [CHAR_LIMIT=NONE] -->
<string name="security_advanced_settings_keywords">security, more security settings, more settings, advanced security settings</string>
-
+ <!-- Title for the section that has additional privacy settings. [CHAR LIMIT=60] -->
+ <string name="privacy_advanced_settings">More privacy settings</string>
+ <!-- Title for the section that has additional privacy settings. [CHAR LIMIT=60] -->
+ <string name="privacy_advanced_settings_summary">Autofill, activity controls, and more</string>
<!-- 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>
@@ -8973,6 +8976,9 @@
<!-- Configure Notifications: Work profile section header [CHAR LIMIT=30] -->
<string name="profile_section_header">Work notifications</string>
+ <!-- Configure Notifications: Work profile section header [CHAR LIMIT=30] -->
+ <string name="profile_section_header_for_advanced_privacy">Work profile</string>
+
<!-- Configure Notifications: section header for prioritizer settings [CHAR LIMIT=80] -->
<string name="smart_notifications_title">Adaptive notifications</string>
diff --git a/res/xml/privacy_advanced_settings.xml b/res/xml/privacy_advanced_settings.xml
new file mode 100644
index 0000000..9f465d4
--- /dev/null
+++ b/res/xml/privacy_advanced_settings.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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="privacy_dashboard_page"
+ android:title="@string/privacy_advanced_settings">
+
+ <!-- Work Policy info -->
+ <Preference
+ android:key="work_policy_info"
+ android:title="@string/work_policy_privacy_settings"
+ android:summary="@string/work_policy_privacy_settings_summary"
+ settings:controller="com.android.settings.privacy.WorkPolicyInfoPreferenceController"/>
+
+ <!-- Connected work and personal apps -->
+ <Preference
+ android:key="interact_across_profiles_privacy"
+ android:title="@string/interact_across_profiles_title"
+ android:fragment="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesSettings"
+ settings:searchable="false"
+ settings:controller="com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesController" />
+
+ <!-- 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"/>
+
+ <!-- Privacy Service -->
+ <PreferenceCategory
+ android:key="privacy_services"
+ android:layout="@layout/preference_category_no_label"/>
+
+ <PreferenceCategory
+ android:key="dashboard_tile_placeholder"/>
+
+ <!-- Work profile settings are at the bottom with high order value to avoid users thinking that
+ any of the above settings (including dynamic) are specific to the work profile. -->
+ <PreferenceCategory
+ android:key="privacy_work_profile_notifications_category"
+ android:title="@string/profile_section_header_for_advanced_privacy"
+ android:order="998">
+
+ <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="999"
+ settings:searchable="false"/>
+ </PreferenceCategory>
+
+ <!-- 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"/>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 9f191f6..ee0743a 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -16,6 +16,8 @@
package com.android.settings;
+import static android.provider.Settings.ACTION_PRIVACY_SETTINGS;
+
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -214,7 +216,8 @@
/** Redirects to SafetyCenter if enabled. */
@VisibleForTesting
public void handleSafetyCenterRedirection() {
- if (SafetyCenterManagerWrapper.get().isEnabled(this)) {
+ if (ACTION_PRIVACY_SETTINGS.equals(getIntent().getAction())
+ && SafetyCenterManagerWrapper.get().isEnabled(this)) {
try {
startActivity(new Intent(Intent.ACTION_SAFETY_CENTER));
finish();
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index df59bd5..75ed225 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -25,6 +25,7 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
+import android.provider.SearchIndexableResource;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -36,6 +37,7 @@
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@SearchIndexable
@@ -72,12 +74,6 @@
replaceEnterpriseStringSummary("work_policy_info",
WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY,
R.string.work_policy_privacy_settings_summary);
-
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.privacy_dashboard_settings;
}
@Override
@@ -90,6 +86,19 @@
return buildPreferenceControllers(context, getSettingsLifecycle());
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return getPreferenceScreenResId(getContext());
+ }
+
+ private static int getPreferenceScreenResId(Context context) {
+ if (SafetyCenterManagerWrapper.get().isEnabled(context)) {
+ return R.xml.privacy_advanced_settings;
+ } else {
+ return R.xml.privacy_dashboard_settings;
+ }
+ }
+
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context, Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
@@ -108,17 +117,19 @@
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.privacy_dashboard_settings) {
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = getPreferenceScreenResId(context);
+ return Arrays.asList(sir);
+ }
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
-
- @Override
- protected boolean isPageSearchEnabled(Context context) {
- return !SafetyCenterManagerWrapper.get().isEnabled(context);
- }
};
}
diff --git a/tests/unit/src/com/android/settings/privacy/PrivacyDashboardActivityTest.java b/tests/unit/src/com/android/settings/privacy/PrivacyDashboardActivityTest.java
index 1cfee0f..ae42c84 100644
--- a/tests/unit/src/com/android/settings/privacy/PrivacyDashboardActivityTest.java
+++ b/tests/unit/src/com/android/settings/privacy/PrivacyDashboardActivityTest.java
@@ -44,54 +44,79 @@
@RunWith(AndroidJUnit4.class)
public class PrivacyDashboardActivityTest {
-
private static final String DEFAULT_FRAGMENT_CLASSNAME = "DefaultFragmentClassname";
-
@Mock
private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
private Settings.PrivacyDashboardActivity mActivity;
+ private static final String ACTION_PRIVACY_ADVANCED_SETTINGS =
+ "android.settings.PRIVACY_ADVANCED_SETTINGS";
@Before
- public void setUp() throws Exception {
+ public void setUp() {
MockitoAnnotations.initMocks(this);
-
SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
- final Intent intent = new Intent();
- intent.setAction(android.provider.Settings.ACTION_PRIVACY_SETTINGS);
- intent.setClass(InstrumentationRegistry.getInstrumentation().getTargetContext(),
- Settings.PrivacyDashboardActivity.class);
- intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT_CLASSNAME);
- InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- try {
- mActivity =
- spy((Settings.PrivacyDashboardActivity) InstrumentationRegistry
- .getInstrumentation().newActivity(
- getClass().getClassLoader(),
- Settings.PrivacyDashboardActivity.class.getName(),
- intent));
- } catch (Exception e) {
- throw new RuntimeException(e); // nothing to do
- }
- });
- doNothing().when(mActivity).startActivity(any(Intent.class));
}
@Test
- public void onCreate_whenSafetyCenterEnabled_redirectsToSafetyCenter() {
+ public void onCreate_whenSafetyCenterEnabled_redirectsToSafetyCenter() throws Exception {
+ startActivityUsingIntent(android.provider.Settings.ACTION_PRIVACY_SETTINGS);
when(mSafetyCenterManagerWrapper.isEnabled(any(Context.class))).thenReturn(true);
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
-
mActivity.handleSafetyCenterRedirection();
-
verify(mActivity).startActivity(intentCaptor.capture());
assertThat(intentCaptor.getValue().getAction()).isEqualTo(Intent.ACTION_SAFETY_CENTER);
}
@Test
- public void onCreate_whenSafetyCenterDisabled_doesntRedirectToSafetyCenter() {
+ public void onCreateWithAdvancedIntent_whenSafetyCenterEnabled_doesntRedirectToSafetyCenter()
+ throws Exception {
+ startActivityUsingIntent(ACTION_PRIVACY_ADVANCED_SETTINGS);
+ when(mSafetyCenterManagerWrapper.isEnabled(any(Context.class))).thenReturn(true);
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ mActivity.handleSafetyCenterRedirection();
+ verify(mActivity, times(0)).startActivity(any());
+ }
+
+ @Test
+ public void onCreate_whenSafetyCenterDisabled_doesntRedirectToSafetyCenter() throws Exception {
+ startActivityUsingIntent(android.provider.Settings.ACTION_PRIVACY_SETTINGS);
when(mSafetyCenterManagerWrapper.isEnabled(any(Context.class))).thenReturn(false);
mActivity.handleSafetyCenterRedirection();
-
verify(mActivity, times(0)).startActivity(any());
}
+
+ @Test
+ public void onCreateWithAdvancedIntent_whenSafetyCenterDisabled_doesntRedirectToSafetyCenter()
+ throws Exception {
+ startActivityUsingIntent(ACTION_PRIVACY_ADVANCED_SETTINGS);
+ when(mSafetyCenterManagerWrapper.isEnabled(any(Context.class))).thenReturn(true);
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ mActivity.handleSafetyCenterRedirection();
+ verify(mActivity, times(0)).startActivity(any());
+ }
+
+ private void startActivityUsingIntent(String intentAction) throws Exception {
+ MockitoAnnotations.initMocks(this);
+ SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
+ final Intent intent = new Intent();
+ intent.setAction(intentAction);
+ intent.setClass(InstrumentationRegistry.getInstrumentation().getTargetContext(),
+ Settings.PrivacyDashboardActivity.class);
+ intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, DEFAULT_FRAGMENT_CLASSNAME);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ try {
+ Settings.PrivacyDashboardActivity activity =
+ (Settings.PrivacyDashboardActivity) InstrumentationRegistry
+ .getInstrumentation().newActivity(
+ getClass().getClassLoader(),
+ Settings.PrivacyDashboardActivity.class.getName(),
+ intent);
+ activity.setIntent(intent);
+ mActivity = spy(activity);
+ } catch (Exception e) {
+ throw new RuntimeException(e); // nothing to do
+ }
+ });
+ doNothing().when(mActivity).startActivity(any(Intent.class));
+ }
}