1 /*
2  * Copyright (C) 2022 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 package com.android.settings.network.telephony;
17 
18 import android.content.Context;
19 import android.provider.DeviceConfig;
20 import android.telephony.TelephonyManager;
21 import android.util.Log;
22 
23 /**
24  * Preference controller for "Require Encryption"
25  *
26  * <p>This preference controller is toggling null algorithms. This applies to all active SIMs.
27  */
28 public class NullAlgorithmsPreferenceController extends TelephonyTogglePreferenceController {
29 
30     // log tags have a char limit of 24 so we can't use the class name
31     private static final String LOG_TAG = "NullAlgosController";
32 
33     private TelephonyManager mTelephonyManager;
34 
35     /**
36      * Class constructor of "Require Encryption" toggle.
37      *
38      * @param context of settings
39      * @param key     assigned within UI entry of XML file
40      */
NullAlgorithmsPreferenceController(Context context, String key)41     public NullAlgorithmsPreferenceController(Context context, String key) {
42         super(context, key);
43         mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
44     }
45 
46     /**
47      * Get the {@link com.android.settings.core.BasePreferenceController.AvailabilityStatus} for
48      * this preference given a {@code subId}. This dictates whether the setting is available on
49      * the device, and if it is not, offers some context as to why.
50      */
51     @Override
getAvailabilityStatus(int subId)52     public int getAvailabilityStatus(int subId) {
53         if (mTelephonyManager == null) {
54             Log.w(LOG_TAG,
55                     "Telephony manager not yet initialized. Marking availability as "
56                             + "CONDITIONALLY_UNAVAILABLE");
57             mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
58             return CONDITIONALLY_UNAVAILABLE;
59         }
60 
61         if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CELLULAR_SECURITY,
62                 TelephonyManager.PROPERTY_ENABLE_NULL_CIPHER_TOGGLE, true)) {
63             Log.i(LOG_TAG, "Null cipher toggle is disabled by DeviceConfig");
64             return CONDITIONALLY_UNAVAILABLE;
65         }
66 
67         try {
68             mTelephonyManager.isNullCipherAndIntegrityPreferenceEnabled();
69         } catch (UnsupportedOperationException e) {
70             Log.i(LOG_TAG, "Null cipher enablement is unsupported: " + e.getMessage());
71             return UNSUPPORTED_ON_DEVICE;
72         } catch (Exception e) {
73             Log.e(LOG_TAG,
74                     "Failed isNullCipherAndIntegrityEnabled. Setting availability to "
75                             + "CONDITIONALLY_UNAVAILABLE. Exception: "
76                             + e.getMessage());
77             return CONDITIONALLY_UNAVAILABLE;
78         }
79 
80         return AVAILABLE;
81     }
82 
83     /**
84      * Return {@code true} if encryption is required (null algorithms not allowed)
85      *
86      * <p><b>NOTE:</b> This method returns the active state of the preference controller and is not
87      * the parameter passed into {@link #setChecked(boolean)}, which is instead the requested future
88      * state.
89      */
90     @Override
isChecked()91     public boolean isChecked() {
92         try {
93             return !mTelephonyManager.isNullCipherAndIntegrityPreferenceEnabled();
94         } catch (Exception e) {
95             Log.e(LOG_TAG,
96                     "Failed isNullCipherAndIntegrityEnabled. Defaulting toggle to "
97                             + "checked = true. Exception: "
98                             + e.getMessage());
99         }
100         // The default behavior for this toggle is enabled
101         return true;
102     }
103 
104     /**
105      * Called when a user preference changes on the toggle. We pass this info on to the Telephony
106      * Framework so that the modem can be updated with the user's preference.
107      *
108      * <p>See {@link com.android.settings.core.TogglePreferenceController#setChecked(boolean)} for
109      * details.
110      *
111      * @param isChecked The toggle value that we're being requested to enforce. A value of {@code
112      *                  true} denotes that null ciphers will be disabled by the modem after this
113      *                  function completes, if it is not already.
114      */
115     @Override
setChecked(boolean isChecked)116     public boolean setChecked(boolean isChecked) {
117         if (isChecked) {
118             Log.i(LOG_TAG, "Encryption required. Disabling null algorithms.");
119         } else {
120             Log.i(LOG_TAG, "Encryption not required. Enabling null algorithms.");
121         }
122         try {
123             mTelephonyManager.setNullCipherAndIntegrityEnabled(!isChecked);
124         } catch (Exception e) {
125             Log.e(LOG_TAG,
126                     "Failed setNullCipherAndIntegrityEnabled. Setting not updated. Exception: "
127                             + e.getMessage());
128             return false;
129         }
130         return true;
131     }
132 }
133