Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e26d2187 authored by Jay Sullivan's avatar Jay Sullivan Committed by Android (Google) Code Review
Browse files

Merge "Implement "More privacy settings"" into tm-dev

parents 98fa9deb ecc0a45a
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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>
+96 −0
Original line number Diff line number Diff line
<?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
+4 −1
Original line number Diff line number Diff line
@@ -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 @@ public class Settings extends SettingsActivity {
        /** 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();
+23 −12
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROF
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.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@SearchIndexable
@@ -72,12 +74,6 @@ public class PrivacyDashboardFragment extends DashboardFragment {
        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 @@ public class PrivacyDashboardFragment extends DashboardFragment {
        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 class PrivacyDashboardFragment extends DashboardFragment {
    }

    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);
                }
            };
}
+51 −26
Original line number Diff line number Diff line
@@ -44,54 +44,79 @@ import org.mockito.MockitoAnnotations;

@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));
    }
}