diff --git a/res/drawable-night/content_protection_preference_illustration.xml b/res/drawable-night/content_protection_preference_illustration.xml
new file mode 100644
index 00000000000..ebc74231e8c
--- /dev/null
+++ b/res/drawable-night/content_protection_preference_illustration.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/content_protection_preference_illustration.xml b/res/drawable/content_protection_preference_illustration.xml
new file mode 100644
index 00000000000..1083c1f9e5a
--- /dev/null
+++ b/res/drawable/content_protection_preference_illustration.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/content_protection_preference_fragment.xml b/res/layout/content_protection_preference_fragment.xml
new file mode 100644
index 00000000000..a412d8618a4
--- /dev/null
+++ b/res/layout/content_protection_preference_fragment.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/xml/more_security_privacy_settings.xml b/res/xml/more_security_privacy_settings.xml
index 8358c734c59..822b03dde5b 100644
--- a/res/xml/more_security_privacy_settings.xml
+++ b/res/xml/more_security_privacy_settings.xml
@@ -119,6 +119,15 @@
android:key="security_category"
android:title="@string/security_header" />
+
+
\ No newline at end of file
+
diff --git a/src/com/android/settings/security/ContentProtectionPreferenceController.java b/src/com/android/settings/security/ContentProtectionPreferenceController.java
new file mode 100644
index 00000000000..01298003f6b
--- /dev/null
+++ b/src/com/android/settings/security/ContentProtectionPreferenceController.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.view.contentprotection.flags.Flags.settingUiEnabled;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class ContentProtectionPreferenceController extends BasePreferenceController {
+
+ public ContentProtectionPreferenceController(@NonNull Context context, @NonNull String key) {
+ super(context, key);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ // TODO(b/306565942): Add a resource value check.
+ return settingUiEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+}
diff --git a/src/com/android/settings/security/ContentProtectionPreferenceFragment.java b/src/com/android/settings/security/ContentProtectionPreferenceFragment.java
new file mode 100644
index 00000000000..a58f6e5efb0
--- /dev/null
+++ b/src/com/android/settings/security/ContentProtectionPreferenceFragment.java
@@ -0,0 +1,64 @@
+/*
+ * 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 android.content.Context;
+import android.app.settings.SettingsEnums;
+
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+import android.os.Bundle;
+
+@SearchIndexable
+public class ContentProtectionPreferenceFragment extends DashboardFragment {
+ private static final String TAG = "ContentProtectionPreferenceFragment";
+
+ // 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);
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ // TODO(b/304681048): Update the toggles' behavior according to user's profile
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.CONTENT_PROTECTION_PREFERENCE;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.layout.content_protection_preference_fragment;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/security/ContentProtectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ContentProtectionPreferenceControllerTest.java
new file mode 100644
index 00000000000..5cc931e557e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/ContentProtectionPreferenceControllerTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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 android.view.contentprotection.flags.Flags.FLAG_SETTING_UI_ENABLED;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+public class ContentProtectionPreferenceControllerTest {
+
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ private Context mContext;
+ private ContentProtectionPreferenceController mController;
+ private Preference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = new ContentProtectionPreferenceController(mContext, "key");
+ mPreference = new Preference(mContext);
+ mPreference.setKey(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void isAvailable_flagSettingUiDisabled_isFalse() {
+ mSetFlagsRule.disableFlags(FLAG_SETTING_UI_ENABLED);
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_flagSettingUiEnabled_isTrue() {
+ mSetFlagsRule.enableFlags(FLAG_SETTING_UI_ENABLED);
+ assertThat(mController.isAvailable()).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/security/ContentProtectionPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/security/ContentProtectionPreferenceFragmentTest.java
new file mode 100644
index 00000000000..431dd0ca533
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/ContentProtectionPreferenceFragmentTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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 android.app.settings.SettingsEnums.CONTENT_PROTECTION_PREFERENCE;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.R;
+import com.android.settings.testutils.XmlTestUtils;
+import com.android.settings.testutils.shadow.ShadowDashboardFragment;
+
+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.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowDashboardFragment.class)
+public class ContentProtectionPreferenceFragmentTest {
+
+ @Mock
+ private ContentProtectionPreferenceFragment mMockFragment;
+ private Context mContext;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mMockFragment = spy(new ContentProtectionPreferenceFragment());
+
+ doReturn(mContext).when(mMockFragment).getContext();
+ }
+
+ @Test
+ public void getMetricsCategory() {
+ assertThat(mMockFragment.getMetricsCategory()).isEqualTo(CONTENT_PROTECTION_PREFERENCE);
+ }
+
+ @Test
+ public void getPreferenceScreenResId(){
+ assertThat(mMockFragment.getPreferenceScreenResId())
+ .isEqualTo(R.layout.content_protection_preference_fragment);
+ }
+
+ @Test
+ public void getNonIndexableKeys_existInXmlLayout() {
+ final List nonIndexableKeys =
+ ContentProtectionPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getNonIndexableKeys(mContext);
+ final List allKeys =
+ XmlTestUtils.getKeysFromPreferenceXml(mContext,
+ R.layout.content_protection_preference_fragment);
+
+ assertThat(allKeys).containsAtLeastElementsIn(nonIndexableKeys);
+ }
+
+ @Test
+ public void searchIndexProvider_shouldIndexResource() {
+ final List indexRes =
+ ContentProtectionPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getXmlResourcesToIndex(mContext, /* enabled = */ true);
+
+ assertThat(indexRes).isNotNull();
+ assertThat(indexRes).isNotEmpty();
+ assertThat(indexRes.get(0).xmlResId).isEqualTo(mMockFragment.getPreferenceScreenResId());
+ }
+}