1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.network; 18 19 import android.app.settings.SettingsEnums; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.PackageManager; 23 import android.os.Build; 24 import android.os.Bundle; 25 import android.safetycenter.SafetyCenterManager; 26 import android.telephony.TelephonyManager; 27 import android.text.TextUtils; 28 import android.util.Log; 29 30 import androidx.annotation.NonNull; 31 import androidx.annotation.Nullable; 32 import androidx.annotation.VisibleForTesting; 33 import androidx.preference.Preference; 34 import androidx.preference.PreferenceScreen; 35 36 import com.android.internal.telephony.flags.Flags; 37 import com.android.settings.core.BasePreferenceController; 38 import com.android.settings.core.SubSettingLauncher; 39 import com.android.settings.network.telephony.CellularSecuritySettingsFragment; 40 41 /** 42 * {@link BasePreferenceController} for accessing Cellular Security settings from Network & 43 * Internet Settings menu. 44 */ 45 public class CellularSecurityPreferenceController extends BasePreferenceController { 46 47 private static final String LOG_TAG = "CellularSecurityPreferenceController"; 48 49 private @Nullable TelephonyManager mTelephonyManager; 50 51 /** 52 * Class constructor of "Cellular Security" preference. 53 * 54 * @param context of settings 55 * @param prefKey assigned within UI entry of XML file 56 */ CellularSecurityPreferenceController(@onNull Context context, @NonNull String prefKey)57 public CellularSecurityPreferenceController(@NonNull Context context, @NonNull String prefKey) { 58 super(context, prefKey); 59 mTelephonyManager = context.getSystemService(TelephonyManager.class); 60 } 61 62 @Override displayPreference(@onNull PreferenceScreen screen)63 public void displayPreference(@NonNull PreferenceScreen screen) { 64 super.displayPreference(screen); 65 } 66 67 @Override getAvailabilityStatus()68 public int getAvailabilityStatus() { 69 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY) 70 || !Flags.enableIdentifierDisclosureTransparencyUnsolEvents() 71 || !Flags.enableModemCipherTransparencyUnsolEvents() 72 || !Flags.enableIdentifierDisclosureTransparency() 73 || !Flags.enableModemCipherTransparency()) { 74 return UNSUPPORTED_ON_DEVICE; 75 } 76 if (mTelephonyManager == null) { 77 Log.w(LOG_TAG, "Telephony manager not yet initialized"); 78 mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 79 } 80 81 boolean isNullCipherDisablementAvailable = false; 82 boolean areCellSecNotificationsAvailable = false; 83 try { 84 mTelephonyManager.isNullCipherAndIntegrityPreferenceEnabled(); 85 isNullCipherDisablementAvailable = true; // true because it doesn't throw an exception, 86 // we don't want the value of 87 // isNullCipherAndIntegrityEnabled() 88 } catch (UnsupportedOperationException e) { 89 Log.i(LOG_TAG, "Null cipher enablement is unsupported, hiding divider: " 90 + e.getMessage()); 91 } catch (Exception e) { 92 Log.e(LOG_TAG, 93 "Failed isNullCipherAndIntegrityEnabled. Setting availability to " 94 + "CONDITIONALLY_UNAVAILABLE. Exception: " 95 + e.getMessage()); 96 } 97 98 try { 99 // Must call both APIs, as we can't use the combined toggle if both aren't available 100 areNotificationsEnabled(); 101 areCellSecNotificationsAvailable = true; // true because it doesn't throw an exception 102 // and we don't want the value of 103 // areNotificationsEnabled() 104 } catch (UnsupportedOperationException e) { 105 Log.i(LOG_TAG, "Cellular security notifications are unsupported, hiding divider: " 106 + e.getMessage()); 107 } 108 109 if (isNullCipherDisablementAvailable || areCellSecNotificationsAvailable) { 110 return AVAILABLE; 111 } else { 112 return UNSUPPORTED_ON_DEVICE; 113 } 114 } 115 116 @Override handlePreferenceTreeClick(@onNull Preference preference)117 public boolean handlePreferenceTreeClick(@NonNull Preference preference) { 118 if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { 119 return super.handlePreferenceTreeClick(preference); 120 } 121 boolean isSafetyCenterSupported = isSafetyCenterSupported(); 122 if (isSafetyCenterSupported) { 123 Intent safetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER); 124 safetyCenterIntent.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, 125 "AndroidCellularNetworkSecuritySources"); 126 mContext.startActivity(safetyCenterIntent); 127 } else { 128 final Bundle bundle = new Bundle(); 129 bundle.putString(CellularSecuritySettingsFragment.KEY_CELLULAR_SECURITY_PREFERENCE, ""); 130 131 new SubSettingLauncher(mContext) 132 .setDestination(CellularSecuritySettingsFragment.class.getName()) 133 .setArguments(bundle) 134 .setSourceMetricsCategory(SettingsEnums.CELLULAR_SECURITY_SETTINGS) 135 .launch(); 136 } 137 return true; 138 } 139 140 @VisibleForTesting isSafetyCenterSupported()141 protected boolean isSafetyCenterSupported() { 142 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { 143 return false; 144 } 145 SafetyCenterManager safetyCenterManager = mContext.getSystemService( 146 SafetyCenterManager.class); 147 if (safetyCenterManager == null) { 148 return false; 149 } 150 return safetyCenterManager.isSafetyCenterEnabled(); 151 } 152 153 @VisibleForTesting areNotificationsEnabled()154 protected boolean areNotificationsEnabled() { 155 if (mTelephonyManager == null) { 156 Log.w(LOG_TAG, "Telephony manager not yet initialized"); 157 mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 158 } 159 160 return mTelephonyManager.isNullCipherNotificationsEnabled() 161 && mTelephonyManager.isCellularIdentifierDisclosureNotificationsEnabled(); 162 } 163 } 164