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