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

Commit bd073bc1 authored by Wa Gao's avatar Wa Gao Committed by Android (Google) Code Review
Browse files

Merge "Hide the setting from the search when feature is disabled." into main

parents 30e841ce 6ffb674f
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -19,13 +19,10 @@ package com.android.settings.security;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.os.UserManager;

import androidx.annotation.VisibleForTesting;
import androidx.preference.SwitchPreference;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
@@ -36,8 +33,10 @@ public class ContentProtectionPreferenceFragment extends DashboardFragment {

    // Required by @SearchIndexable to make the fragment and preferences to be indexed.
    // Do not rename.
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.layout.content_protection_preference_fragment);
    @VisibleForTesting
    public static final ContentProtectionSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new ContentProtectionSearchIndexProvider(
                    R.layout.content_protection_preference_fragment);

    @Override
    public void onAttach(Context context) {
@@ -63,4 +62,17 @@ public class ContentProtectionPreferenceFragment extends DashboardFragment {
    protected String getLogTag() {
        return TAG;
    }

    public static class ContentProtectionSearchIndexProvider extends BaseSearchIndexProvider {

        public ContentProtectionSearchIndexProvider(int xmlRes) {
            super(xmlRes);
        }

        @Override
        @VisibleForTesting
        public boolean isPageSearchEnabled(Context context) {
            return ContentProtectionPreferenceUtils.isAvailable(context);
        }
    }
}
+63 −0
Original line number Diff line number Diff line
/*
 * 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.security;

import static com.android.internal.R.string.config_defaultContentProtectionService;

import android.content.ComponentName;
import android.content.Context;
import android.provider.DeviceConfig;
import android.view.contentcapture.ContentCaptureManager;

import androidx.annotation.Nullable;
import androidx.annotation.NonNull;

/** Util class for content protection preference. */
public class ContentProtectionPreferenceUtils {

    /**
     * Whether or not the content protection setting page is available.
     */
    public static boolean isAvailable(@NonNull Context context) {
        if (!settingUiEnabled() || getContentProtectionServiceComponentName(context) == null) {
            return false;
        }
        return true;
    }

    private static String getContentProtectionServiceFlatComponentName(@NonNull Context context) {
        return context.getString(config_defaultContentProtectionService);
    }

    @Nullable
    private static ComponentName getContentProtectionServiceComponentName(@NonNull Context context) {
        String flatComponentName = getContentProtectionServiceFlatComponentName(context);
        if (flatComponentName == null) {
            return null;
        }
        return ComponentName.unflattenFromString(flatComponentName);
    }

    /**
     * Whether or not the content protection UI is enabled.
     */
    private static boolean settingUiEnabled() {
        return DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                ContentCaptureManager.DEFAULT_ENABLE_CONTENT_PROTECTION_RECEIVER);
    }
}
+72 −2
Original line number Diff line number Diff line
@@ -18,22 +18,28 @@ package com.android.settings.security;

import static android.app.settings.SettingsEnums.CONTENT_PROTECTION_PREFERENCE;

import static com.android.internal.R.string.config_defaultContentProtectionService;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

import android.content.ComponentName;
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.SearchIndexableResource;
import android.view.contentcapture.ContentCaptureManager;

import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;

import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowDashboardFragment;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowUtils;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,8 +55,15 @@ import java.util.List;
        shadows = {
            ShadowDashboardFragment.class,
            ShadowUtils.class,
            ShadowDeviceConfig.class,
        })
public class ContentProtectionPreferenceFragmentTest {
    private static final String PACKAGE_NAME = "com.test.package";

    private static final ComponentName COMPONENT_NAME =
            new ComponentName(PACKAGE_NAME, "TestClass");

    private String mConfigDefaultContentProtectionService = COMPONENT_NAME.flattenToString();
    private ContentProtectionPreferenceFragment mFragment;
    private Context mContext;
    private PreferenceScreen mScreen;
@@ -67,6 +80,11 @@ public class ContentProtectionPreferenceFragmentTest {
        doReturn(mScreen).when(mFragment).getPreferenceScreen();
    }

    @After
    public void tearDown() {
        ShadowDeviceConfig.reset();
    }

    @Test
    public void getMetricsCategory() {
        assertThat(mFragment.getMetricsCategory()).isEqualTo(CONTENT_PROTECTION_PREFERENCE);
@@ -79,7 +97,16 @@ public class ContentProtectionPreferenceFragmentTest {
    }

    @Test
    public void getNonIndexableKeys_existInXmlLayout() {
    public void getNonIndexableKeys_uiEnabled_existInXmlLayout() {
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "true",
                /* makeDefault= */ false);
        doReturn(mConfigDefaultContentProtectionService)
                .when(mContext)
                .getString(config_defaultContentProtectionService);

        final List<String> nonIndexableKeys =
                ContentProtectionPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
                        mContext);
@@ -90,6 +117,24 @@ public class ContentProtectionPreferenceFragmentTest {
        assertThat(allKeys).containsAtLeastElementsIn(nonIndexableKeys);
    }

    @Test
    public void getNonIndexableKeys_uiDisabled_notExisted() {
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "false",
                /* makeDefault= */ false);

        final List<String> nonIndexableKeys =
                ContentProtectionPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
                        mContext);
        final List<String> allKeys =
                XmlTestUtils.getKeysFromPreferenceXml(
                        mContext, R.layout.content_protection_preference_fragment);

        assertThat(nonIndexableKeys).containsAnyIn(allKeys);
    }

    @Test
    public void searchIndexProvider_shouldIndexResource() {
        final List<SearchIndexableResource> indexRes =
@@ -100,4 +145,29 @@ public class ContentProtectionPreferenceFragmentTest {
        assertThat(indexRes).isNotEmpty();
        assertThat(indexRes.get(0).xmlResId).isEqualTo(mFragment.getPreferenceScreenResId());
    }

    @Test
    public void isPageSearchEnabled_uiDisabled_returnsFalse() {
        boolean isSearchEnabled =
                mFragment.SEARCH_INDEX_DATA_PROVIDER.isPageSearchEnabled(mContext);

        assertThat(isSearchEnabled).isFalse();
    }

    @Test
    public void isPageSearchEnabled_uiEnabled_returnsTrue() {
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "true",
                /* makeDefault= */ false);
        doReturn(mConfigDefaultContentProtectionService)
                .when(mContext)
                .getString(config_defaultContentProtectionService);

        boolean isSearchEnabled =
                mFragment.SEARCH_INDEX_DATA_PROVIDER.isPageSearchEnabled(mContext);

        assertThat(isSearchEnabled).isTrue();
    }
}
+148 −0
Original line number Diff line number Diff line
/*
 * 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.security;

import static com.android.internal.R.string.config_defaultContentProtectionService;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.content.Context;
import android.provider.DeviceConfig;
import android.view.contentcapture.ContentCaptureManager;

import com.android.settings.testutils.shadow.ShadowDeviceConfig;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
@Config(
        shadows = {
            ShadowDeviceConfig.class,
        })
public class ContentProtectionPreferenceUtilsTest {
    private static final String PACKAGE_NAME = "com.test.package";

    private static final ComponentName COMPONENT_NAME =
            new ComponentName(PACKAGE_NAME, "TestClass");

    private String mConfigDefaultContentProtectionService = COMPONENT_NAME.flattenToString();

    @Mock private Context mMockContext;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @After
    public void tearDown() {
        ShadowDeviceConfig.reset();
    }

    @Test
    public void isAvailable_bothEnabled_true() {
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "true",
                /* makeDefault= */ false);
        when(mMockContext.getString(config_defaultContentProtectionService))
                .thenReturn(mConfigDefaultContentProtectionService);

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isTrue();
    }

    @Test
    public void isAvailable_onlyUiEnabled_false() {
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "true",
                /* makeDefault= */ false);

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isFalse();
    }

    @Test
    public void isAvailable_onlyServiceEnabled_false() {
        when(mMockContext.getString(config_defaultContentProtectionService))
                .thenReturn(mConfigDefaultContentProtectionService);
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "false",
                /* makeDefault= */ false);

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isFalse();
    }

    @Test
    public void isAvailable_emptyComponentName_false() {
        when(mMockContext.getString(config_defaultContentProtectionService))
                .thenReturn("");
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "true",
                /* makeDefault= */ false);

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isFalse();
    }

    @Test
    public void isAvailable_blankComponentName_false() {
	when(mMockContext.getString(config_defaultContentProtectionService))
                .thenReturn("   ");
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "true",
                /* makeDefault= */ false);

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isFalse();
    }

    @Test
    public void isAvailable_invalidComponentName_false() {
        when(mMockContext.getString(config_defaultContentProtectionService))
                .thenReturn("invalid");

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isFalse();
    }


    @Test
    public void isAvailable_bothDisabled_false() {
        DeviceConfig.setProperty(
                DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER,
                "false",
                /* makeDefault= */ false);

        assertThat(ContentProtectionPreferenceUtils.isAvailable(mMockContext)).isFalse();
    }
}