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