• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.development;
18 
19 import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_CODE_ENABLE_OEM_UNLOCK;
20 
21 import android.app.Activity;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.res.Resources;
25 import android.os.SystemProperties;
26 import android.os.UserHandle;
27 import android.os.UserManager;
28 import android.service.oemlock.OemLockManager;
29 import android.telephony.TelephonyManager;
30 import android.text.TextUtils;
31 import android.util.Log;
32 
33 import androidx.annotation.VisibleForTesting;
34 import androidx.preference.Preference;
35 import androidx.preference.PreferenceScreen;
36 
37 import com.android.settings.R;
38 import com.android.settings.core.PreferenceControllerMixin;
39 import com.android.settings.password.ChooseLockSettingsHelper;
40 import com.android.settingslib.RestrictedSwitchPreference;
41 import com.android.settingslib.development.DeveloperOptionsPreferenceController;
42 
43 public class OemUnlockPreferenceController extends DeveloperOptionsPreferenceController implements
44         Preference.OnPreferenceChangeListener, PreferenceControllerMixin, OnActivityResultListener {
45 
46     private static final String PREFERENCE_KEY = "oem_unlock_enable";
47     private static final String TAG = "OemUnlockPreferenceController";
48     private static final String OEM_UNLOCK_SUPPORTED_KEY = "ro.oem_unlock_supported";
49     private static final String UNSUPPORTED = "-9999";
50     private static final String SUPPORTED = "1";
51 
52     private final OemLockManager mOemLockManager;
53     private final UserManager mUserManager;
54     private final TelephonyManager mTelephonyManager;
55     private final DevelopmentSettingsDashboardFragment mFragment;
56     private final ChooseLockSettingsHelper mChooseLockSettingsHelper;
57     private RestrictedSwitchPreference mPreference;
58 
OemUnlockPreferenceController(Context context, Activity activity, DevelopmentSettingsDashboardFragment fragment)59     public OemUnlockPreferenceController(Context context, Activity activity,
60             DevelopmentSettingsDashboardFragment fragment) {
61         super(context);
62 
63         if (!TextUtils.equals(SystemProperties.get(OEM_UNLOCK_SUPPORTED_KEY, UNSUPPORTED),
64                 SUPPORTED)) {
65             mOemLockManager = null;
66             Log.w(TAG, "oem_unlock not supported.");
67         } else {
68             mOemLockManager = (OemLockManager) context.getSystemService(Context.OEM_LOCK_SERVICE);
69         }
70         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
71         mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
72         mFragment = fragment;
73         if (activity != null || mFragment != null) {
74             mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity, mFragment);
75         } else {
76             mChooseLockSettingsHelper = null;
77         }
78     }
79 
80     @Override
isAvailable()81     public boolean isAvailable() {
82         return mOemLockManager != null;
83     }
84 
85     @Override
getPreferenceKey()86     public String getPreferenceKey() {
87         return PREFERENCE_KEY;
88     }
89 
90     @Override
displayPreference(PreferenceScreen screen)91     public void displayPreference(PreferenceScreen screen) {
92         super.displayPreference(screen);
93 
94         mPreference = screen.findPreference(getPreferenceKey());
95     }
96 
97     @Override
onPreferenceChange(Preference preference, Object newValue)98     public boolean onPreferenceChange(Preference preference, Object newValue) {
99         boolean isUnlocked = (Boolean) newValue;
100         if (isUnlocked) {
101             if (!showKeyguardConfirmation(mContext.getResources(),
102                     REQUEST_CODE_ENABLE_OEM_UNLOCK)) {
103                 confirmEnableOemUnlock();
104             }
105         } else {
106             mOemLockManager.setOemUnlockAllowedByUser(false);
107             OemLockInfoDialog.show(mFragment);
108         }
109         return true;
110     }
111 
112     @Override
updateState(Preference preference)113     public void updateState(Preference preference) {
114         super.updateState(preference);
115         mPreference.setChecked(isOemUnlockedAllowed());
116         updateOemUnlockSettingDescription();
117         // Showing mEnableOemUnlock preference as device has persistent data block.
118         mPreference.setDisabledByAdmin(null);
119         mPreference.setEnabled(enableOemUnlockPreference());
120         if (mPreference.isEnabled()) {
121             // Check restriction, disable mEnableOemUnlock and apply policy transparency.
122             mPreference.checkRestrictionAndSetDisabled(UserManager.DISALLOW_FACTORY_RESET);
123         }
124     }
125 
126     @Override
onActivityResult(int requestCode, int resultCode, Intent data)127     public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
128         if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) {
129             if (resultCode == Activity.RESULT_OK) {
130                 if (mPreference.isChecked()) {
131                     confirmEnableOemUnlock();
132                 } else {
133                     mOemLockManager.setOemUnlockAllowedByUser(false);
134                 }
135             }
136             return true;
137         }
138         return false;
139     }
140 
141     @Override
onDeveloperOptionsSwitchEnabled()142     protected void onDeveloperOptionsSwitchEnabled() {
143         handleDeveloperOptionsToggled();
144     }
145 
onOemUnlockConfirmed()146     public void onOemUnlockConfirmed() {
147         mOemLockManager.setOemUnlockAllowedByUser(true);
148     }
149 
onOemUnlockDismissed()150     public void onOemUnlockDismissed() {
151         if (mPreference == null) {
152             return;
153         }
154         updateState(mPreference);
155     }
156 
handleDeveloperOptionsToggled()157     private void handleDeveloperOptionsToggled() {
158         mPreference.setEnabled(enableOemUnlockPreference());
159         if (mPreference.isEnabled()) {
160             // Check restriction, disable mEnableOemUnlock and apply policy transparency.
161             mPreference.checkRestrictionAndSetDisabled(UserManager.DISALLOW_FACTORY_RESET);
162         }
163     }
164 
updateOemUnlockSettingDescription()165     private void updateOemUnlockSettingDescription() {
166         int oemUnlockSummary = R.string.oem_unlock_enable_summary;
167         if (isBootloaderUnlocked()) {
168             oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_bootloader_unlocked;
169         } else if (isSimLockedDevice()) {
170             oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_sim_locked_device;
171         } else if (!isOemUnlockAllowedByUserAndCarrier()) {
172             // If the device isn't SIM-locked but OEM unlock is disallowed by some party, this
173             // means either some other carrier restriction is in place or the device hasn't been
174             // able to confirm which restrictions (SIM-lock or otherwise) apply.
175             oemUnlockSummary =
176                     R.string.oem_unlock_enable_disabled_summary_connectivity_or_locked;
177         }
178         mPreference.setSummary(mContext.getResources().getString(oemUnlockSummary));
179     }
180 
181     /** Returns {@code true} if the device is SIM-locked. Otherwise, returns {@code false}. */
isSimLockedDevice()182     private boolean isSimLockedDevice() {
183         int phoneCount = mTelephonyManager.getPhoneCount();
184         for (int i = 0; i < phoneCount; i++) {
185             if (mTelephonyManager.getAllowedCarriers(i).size() > 0) {
186                 return true;
187             }
188         }
189         return false;
190     }
191 
192     /**
193      * Returns {@code true} if the bootloader has been unlocked. Otherwise, returns {code false}.
194      */
195     @VisibleForTesting
isBootloaderUnlocked()196     boolean isBootloaderUnlocked() {
197         return mOemLockManager.isDeviceOemUnlocked();
198     }
199 
enableOemUnlockPreference()200     private boolean enableOemUnlockPreference() {
201         return !isBootloaderUnlocked() && isOemUnlockAllowedByUserAndCarrier();
202     }
203 
204 
205     @VisibleForTesting
showKeyguardConfirmation(Resources resources, int requestCode)206     boolean showKeyguardConfirmation(Resources resources, int requestCode) {
207         return mChooseLockSettingsHelper.launchConfirmationActivity(
208                 requestCode, resources.getString(R.string.oem_unlock_enable));
209     }
210 
211     @VisibleForTesting
confirmEnableOemUnlock()212     void confirmEnableOemUnlock() {
213         EnableOemUnlockSettingWarningDialog.show(mFragment);
214     }
215 
216     /**
217      * Returns whether OEM unlock is allowed by the user and carrier.
218      *
219      * This does not take into account any restrictions imposed by the device policy.
220      */
221     @VisibleForTesting
isOemUnlockAllowedByUserAndCarrier()222     boolean isOemUnlockAllowedByUserAndCarrier() {
223         final UserHandle userHandle = UserHandle.of(UserHandle.myUserId());
224         return mOemLockManager.isOemUnlockAllowedByCarrier()
225                 && !mUserManager.hasBaseUserRestriction(UserManager.DISALLOW_FACTORY_RESET,
226                 userHandle);
227     }
228 
229     @VisibleForTesting
isOemUnlockedAllowed()230     boolean isOemUnlockedAllowed() {
231         return mOemLockManager.isOemUnlockAllowed();
232     }
233 
234 }
235