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