Add new Cellular Network Security page


Test: m & atest CellularSecurityNotificationsDividerControllerTest CellularSecurityNotificationsPreferenceControllerTest CellularSecurityEncryptionDividerControllerTest CellularSecurityPreferenceControllerTest
Bug: b/318428717
Change-Id: I4a6ec5f47beb36bd455e04c2e6c4cea0ba65110f
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 2f6f04a..4c2ee67 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -348,6 +348,7 @@
         /* empty */
     }
 
+    public static class CellularSecuritySettingsActivity extends SettingsActivity { /* empty */ }
     public static class SatelliteSettingActivity extends SettingsActivity { /* empty */ }
     public static class ApnSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiCallingSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index e08e856..8b3dbf4 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -144,6 +144,7 @@
 import com.android.settings.network.NetworkProviderSettings;
 import com.android.settings.network.apn.ApnEditor;
 import com.android.settings.network.apn.ApnSettings;
+import com.android.settings.network.telephony.CellularSecuritySettingsFragment;
 import com.android.settings.network.telephony.MobileNetworkSettings;
 import com.android.settings.network.telephony.NetworkSelectSettings;
 import com.android.settings.network.telephony.SatelliteSetting;
@@ -388,6 +389,7 @@
             ScreenTimeoutSettings.class.getName(),
             ResetNetwork.class.getName(),
             VibrationIntensitySettingsFragment.class.getName(),
+            CellularSecuritySettingsFragment.class.getName(),
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/network/CellularSecurityPreferenceController.java b/src/com/android/settings/network/CellularSecurityPreferenceController.java
new file mode 100644
index 0000000..237e704
--- /dev/null
+++ b/src/com/android/settings/network/CellularSecurityPreferenceController.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2024 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.network;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.safetycenter.SafetyCenterManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.telephony.flags.Flags;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.network.telephony.CellularSecuritySettingsFragment;
+
+/**
+ * {@link BasePreferenceController} for accessing Cellular Security settings from Network &
+ * Internet Settings menu.
+ */
+public class CellularSecurityPreferenceController extends BasePreferenceController {
+
+    private static final String LOG_TAG = "CellularSecurityPreferenceController";
+
+    private @Nullable TelephonyManager mTelephonyManager;
+
+    /**
+     * Class constructor of "Cellular Security" preference.
+     *
+     * @param context of settings
+     * @param prefKey     assigned within UI entry of XML file
+     */
+    public CellularSecurityPreferenceController(@NonNull Context context, @NonNull String prefKey) {
+        super(context, prefKey);
+        mTelephonyManager = context.getSystemService(TelephonyManager.class);
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!Flags.enableIdentifierDisclosureTransparencyUnsolEvents()
+                || !Flags.enableModemCipherTransparencyUnsolEvents()
+                || !Flags.enableIdentifierDisclosureTransparency()
+                || !Flags.enableModemCipherTransparency()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+        if (mTelephonyManager == null) {
+            Log.w(LOG_TAG, "Telephony manager not yet initialized");
+            mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        }
+
+        boolean isNullCipherDisablementAvailable = false;
+        boolean areCellSecNotificationsAvailable = false;
+        try {
+            mTelephonyManager.isNullCipherAndIntegrityPreferenceEnabled();
+            isNullCipherDisablementAvailable = true; // true because it doesn't throw an exception,
+                                                     // we don't want the value of
+                                                     // isNullCipherAndIntegrityEnabled()
+        } catch (UnsupportedOperationException e) {
+            Log.i(LOG_TAG, "Null cipher enablement is unsupported, hiding divider: "
+                    + e.getMessage());
+        } catch (Exception e) {
+            Log.e(LOG_TAG,
+                    "Failed isNullCipherAndIntegrityEnabled. Setting availability to "
+                            + "CONDITIONALLY_UNAVAILABLE. Exception: "
+                            + e.getMessage());
+        }
+
+        try {
+            // Must call both APIs, as we can't use the combined toggle if both aren't available
+            areNotificationsEnabled();
+            areCellSecNotificationsAvailable = true; // true because it doesn't throw an exception
+                                                     // and we don't want the value of
+                                                     // areNotificationsEnabled()
+        } catch (UnsupportedOperationException e) {
+            Log.i(LOG_TAG, "Cellular security notifications are unsupported, hiding divider: "
+                    + e.getMessage());
+        }
+
+        if (isNullCipherDisablementAvailable || areCellSecNotificationsAvailable) {
+            return AVAILABLE;
+        } else {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(@NonNull Preference preference) {
+        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+            return super.handlePreferenceTreeClick(preference);
+        }
+        boolean isSafetyCenterSupported = isSafetyCenterSupported();
+        if (isSafetyCenterSupported) {
+            Intent safetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER);
+            safetyCenterIntent.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID,
+                    "AndroidCellularNetworkSecuritySources");
+            mContext.startActivity(safetyCenterIntent);
+        } else {
+            final Bundle bundle = new Bundle();
+            bundle.putString(CellularSecuritySettingsFragment.KEY_CELLULAR_SECURITY_PREFERENCE, "");
+
+            new SubSettingLauncher(mContext)
+                     .setDestination(CellularSecuritySettingsFragment.class.getName())
+                     .setArguments(bundle)
+                     .setSourceMetricsCategory(SettingsEnums.CELLULAR_SECURITY_SETTINGS)
+                     .launch();
+        }
+        return true;
+    }
+
+    @VisibleForTesting
+    protected boolean isSafetyCenterSupported() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+            return false;
+        }
+        SafetyCenterManager safetyCenterManager = mContext.getSystemService(
+                SafetyCenterManager.class);
+        if (safetyCenterManager == null) {
+            return false;
+        }
+        return safetyCenterManager.isSafetyCenterEnabled();
+    }
+
+    @VisibleForTesting
+    protected boolean areNotificationsEnabled() {
+        if (mTelephonyManager == null) {
+            Log.w(LOG_TAG, "Telephony manager not yet initialized");
+            mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        }
+
+        return mTelephonyManager.isNullCipherNotificationsEnabled()
+            && mTelephonyManager.isCellularIdentifierDisclosureNotificationsEnabled();
+    }
+}
diff --git a/src/com/android/settings/network/telephony/CellularSecurityEncryptionDividerController.java b/src/com/android/settings/network/telephony/CellularSecurityEncryptionDividerController.java
new file mode 100644
index 0000000..6d31c72
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CellularSecurityEncryptionDividerController.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 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.network.telephony;
+
+import android.content.Context;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.flags.FeatureFlagsImpl;
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * {@link BasePreferenceController} for visibility of Encryption divider on Cellular Security
+ * settings page.
+ */
+public class CellularSecurityEncryptionDividerController extends
+                BasePreferenceController {
+
+    private static final String LOG_TAG = "CellularSecurityEncryptionDividerController";
+
+    private TelephonyManager mTelephonyManager;
+
+    protected final FeatureFlags mFeatureFlags = new FeatureFlagsImpl();
+
+    /**
+     * Class constructor of "Cellular Security" preference.
+     *
+     * @param context of settings
+     * @param prefKey assigned within UI entry of XML file
+     */
+    public CellularSecurityEncryptionDividerController(
+            @NonNull Context context, @NonNull String prefKey) {
+        super(context, prefKey);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+    }
+
+    /**
+     * Initialization.
+     */
+    public CellularSecurityEncryptionDividerController init() {
+        return this;
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mTelephonyManager == null) {
+            Log.w(LOG_TAG,
+                    "Telephony manager not yet initialized. Marking availability as "
+                            + "CONDITIONALLY_UNAVAILABLE");
+            mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+
+        try {
+            mTelephonyManager.isNullCipherAndIntegrityPreferenceEnabled();
+        } catch (UnsupportedOperationException e) {
+            Log.i(LOG_TAG, "Null cipher enablement is unsupported, hiding divider: "
+                    + e.getMessage());
+            return UNSUPPORTED_ON_DEVICE;
+        } catch (Exception e) {
+            Log.e(LOG_TAG,
+                    "Failed isNullCipherAndIntegrityEnabled. Setting availability to "
+                            + "CONDITIONALLY_UNAVAILABLE. Exception: "
+                            + e.getMessage());
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        return AVAILABLE;
+    }
+}
diff --git a/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java b/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java
new file mode 100644
index 0000000..bbe954c
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2024 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.network.telephony;
+
+import android.content.Context;
+import android.os.Build;
+import android.safetycenter.SafetyCenterManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.telephony.flags.Flags;
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * {@link BasePreferenceController} for visibility of Notifications divider on Cellular Security
+ * settings page.
+ */
+public class CellularSecurityNotificationsDividerController extends
+                BasePreferenceController {
+
+    private static final String LOG_TAG = "CellularSecurityNotificationsDividerController";
+
+    private TelephonyManager mTelephonyManager;
+    @VisibleForTesting
+    protected SafetyCenterManager mSafetyCenterManager;
+
+    /**
+     * Class constructor of "Cellular Security" preference.
+     *
+     * @param context of settings
+     * @param prefKey assigned within UI entry of XML file
+     */
+    public CellularSecurityNotificationsDividerController(
+            @NonNull Context context, @NonNull String prefKey) {
+        super(context, prefKey);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        mSafetyCenterManager = mContext.getSystemService(SafetyCenterManager.class);
+    }
+
+    /**
+     * Initialization.
+     */
+    public CellularSecurityNotificationsDividerController init() {
+        return this;
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!Flags.enableIdentifierDisclosureTransparencyUnsolEvents()
+                || !Flags.enableModemCipherTransparencyUnsolEvents()
+                || !Flags.enableIdentifierDisclosureTransparency()
+                || !Flags.enableModemCipherTransparency()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+        if (!isSafetyCenterSupported()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+        if (mTelephonyManager == null) {
+            Log.w(LOG_TAG, "Telephony manager not yet initialized");
+            mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        }
+        // Checking for hardware support, i.e. IRadio AIDL version must be >= 2.2
+        try {
+            // Must call both APIs, as we can't use the combined toggle if both aren't available
+            areNotificationsEnabled();
+        } catch (UnsupportedOperationException e) {
+            Log.i(LOG_TAG, "Cellular security notifications are unsupported, hiding divider: "
+                    + e.getMessage());
+            return UNSUPPORTED_ON_DEVICE;
+        }
+
+        return AVAILABLE;
+    }
+
+    @VisibleForTesting
+    protected boolean areNotificationsEnabled() {
+        return mTelephonyManager.isNullCipherNotificationsEnabled()
+            && mTelephonyManager.isCellularIdentifierDisclosureNotificationsEnabled();
+    }
+
+    protected boolean isSafetyCenterSupported() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+            return false;
+        }
+        mSafetyCenterManager = mContext.getSystemService(
+                SafetyCenterManager.class);
+        if (mSafetyCenterManager == null) {
+            return false;
+        }
+        return mSafetyCenterManager.isSafetyCenterEnabled();
+    }
+}
diff --git a/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java b/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java
new file mode 100644
index 0000000..520e7c5
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2024 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.network.telephony;
+
+import android.content.Context;
+import android.os.Build;
+import android.safetycenter.SafetyCenterManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.telephony.flags.Flags;
+
+/**
+ * {@link TelephonyTogglePreferenceController} for accessing Cellular Security settings through
+ * Safety Center.
+ */
+public class CellularSecurityNotificationsPreferenceController extends
+                TelephonyTogglePreferenceController {
+
+    private static final String LOG_TAG = "CellularSecurityNotificationsPreferenceController";
+
+    private TelephonyManager mTelephonyManager;
+    @VisibleForTesting
+    protected SafetyCenterManager mSafetyCenterManager;
+
+    /**
+     * Class constructor of "Cellular Security" preference.
+     *
+     * @param context of settings
+     * @param prefKey assigned within UI entry of XML file
+     */
+    public CellularSecurityNotificationsPreferenceController(
+            @NonNull Context context, @NonNull String prefKey) {
+        super(context, prefKey);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        mSafetyCenterManager = mContext.getSystemService(SafetyCenterManager.class);
+    }
+
+    /**
+     * Initialization based on a given subscription id.
+     *
+     * @param subId is the subscription id
+     * @return this instance after initialization
+     */
+    public CellularSecurityNotificationsPreferenceController init(@NonNull int subId) {
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(subId);
+        return this;
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+    }
+
+    @Override
+    public int getAvailabilityStatus(int subId) {
+        if (!isSafetyCenterSupported()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+
+        if (!areFlagsEnabled()) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+        if (mTelephonyManager == null) {
+            Log.w(LOG_TAG, "Telephony manager not yet initialized");
+            mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        }
+
+        // Checking for hardware support, i.e. IRadio AIDL version must be >= 2.2
+        try {
+            areNotificationsEnabled();
+        } catch (UnsupportedOperationException e) {
+            Log.i(LOG_TAG, "Cellular security notifications are unsupported: " + e.getMessage());
+            return UNSUPPORTED_ON_DEVICE;
+        }
+
+        return AVAILABLE;
+    }
+
+    /**
+     * Return {@code true} if cellular security notifications are on
+     *
+     * <p><b>NOTE:</b> This method returns the active state of the preference controller and is not
+     * the parameter passed into {@link #setChecked(boolean)}, which is instead the requested future
+     * state.
+     */
+    @Override
+    public boolean isChecked() {
+        if (!areFlagsEnabled()) {
+            return false;
+        }
+
+        try {
+            // Note: the default behavior for this toggle is disabled (as the underlying
+            // TelephonyManager APIs are disabled by default)
+            return areNotificationsEnabled();
+        } catch (Exception e) {
+            Log.e(LOG_TAG,
+                    "Failed isNullCipherNotificationsEnabled and "
+                            + "isCellularIdentifierDisclosureNotificationsEnabled."
+                            + "Defaulting toggle to checked = true. Exception: "
+                            + e.getMessage());
+            return false;
+        }
+    }
+
+    /**
+     * Called when a user preference changes on the toggle. We pass this info on to the Telephony
+     * Framework so that the modem can be updated with the user's preference.
+     *
+     * <p>See {@link com.android.settings.core.TogglePreferenceController#setChecked(boolean)} for
+     * details.
+     *
+     * @param isChecked The toggle value that we're being requested to enforce. A value of {@code
+     *                  true} denotes that both (1) null cipher/integrity notifications, and
+     *                  (2) IMSI disclosure notifications will be enabled by the modem after this
+     *                  function completes, if they are not already.
+     */
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        if (isChecked) {
+            Log.i(LOG_TAG, "Enabling cellular security notifications.");
+        } else {
+            Log.i(LOG_TAG, "Disabling cellular security notifications.");
+        }
+
+        // Check flag status
+        if (!areFlagsEnabled()) {
+            return false;
+        }
+
+        try {
+            setNotifications(isChecked);
+        } catch (Exception e) {
+            Log.e(LOG_TAG,
+                    "Failed setCellularIdentifierDisclosureNotificationEnabled or "
+                            + " setNullCipherNotificationsEnabled. Setting not updated. Exception: "
+                            + e.getMessage());
+            // Reset to defaults so we don't end up in an inconsistent state
+            setNotifications(!isChecked);
+            return false;
+        }
+        return true;
+    }
+
+    private void setNotifications(boolean isChecked) {
+        mTelephonyManager.setEnableCellularIdentifierDisclosureNotifications(isChecked);
+        mTelephonyManager.setNullCipherNotificationsEnabled(isChecked);
+    }
+
+    private boolean areNotificationsEnabled() {
+        return mTelephonyManager.isNullCipherNotificationsEnabled()
+            && mTelephonyManager.isCellularIdentifierDisclosureNotificationsEnabled();
+    }
+
+    private boolean areFlagsEnabled() {
+        if (!Flags.enableIdentifierDisclosureTransparencyUnsolEvents()
+                || !Flags.enableModemCipherTransparencyUnsolEvents()
+                || !Flags.enableIdentifierDisclosureTransparency()
+                || !Flags.enableModemCipherTransparency()) {
+            return false;
+        }
+        return true;
+    }
+
+    protected boolean isSafetyCenterSupported() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+            return false;
+        }
+        mSafetyCenterManager = mContext.getSystemService(
+                SafetyCenterManager.class);
+        if (mSafetyCenterManager == null) {
+            return false;
+        }
+        return mSafetyCenterManager.isSafetyCenterEnabled();
+    }
+}
diff --git a/src/com/android/settings/network/telephony/CellularSecuritySettingsFragment.java b/src/com/android/settings/network/telephony/CellularSecuritySettingsFragment.java
new file mode 100644
index 0000000..3e37352
--- /dev/null
+++ b/src/com/android/settings/network/telephony/CellularSecuritySettingsFragment.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 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.network.telephony;
+
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+/**
+ * Cellular Security features (insecure network notifications, network security controls, etc)
+ */
+@SearchIndexable
+public class CellularSecuritySettingsFragment extends DashboardFragment {
+
+    private static final String TAG = "CellularSecuritySettingsFragment";
+
+    public static final String KEY_CELLULAR_SECURITY_PREFERENCE = "cellular_security";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.CELLULAR_SECURITY_SETTINGS;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.cellular_security;
+    }
+
+    @Override
+    public void onCreatePreferences(Bundle bundle, String rootKey) {
+        super.onCreatePreferences(bundle, rootKey);
+        setPreferencesFromResource(R.xml.cellular_security, rootKey);
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.cellular_security);
+}