From 1c1366e9681d633188b4bea62ec296a71b39af4c Mon Sep 17 00:00:00 2001 From: Pawan Wagh Date: Fri, 23 Feb 2024 21:10:26 +0000 Subject: Show dialog to OEM unlock the device for 16k dev option Device should be OEM unlocked before using dev option. Show dialog to user to perform OEM unlock. This also checks if user has permission to do OEM unlock and it is allowed by carrier. Test: m Settings && adb install -r $ANDROID_PRODUCT_OUT/system_ext/priv-app/Settings/Settings.apk Bug: 295035851 Bug: 320705365 Change-Id: I6470bf7d02424a26621ed67f19f2cd14fa9eea50 --- res/values/strings.xml | 3 + .../development/Enable16KOemUnlockDialog.java | 77 ++++++++++++++++++++++ .../Enable16kPagesPreferenceController.java | 35 ++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/com/android/settings/development/Enable16KOemUnlockDialog.java diff --git a/res/values/strings.xml b/res/values/strings.xml index f0794dd197f..1212aca855f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11345,6 +11345,9 @@ 16K developer option is supported with ext4 filesystem. Device will be wiped and filesystem will be changed to ext4 after confirmation. Failed to reformat and wipe the data partiton to ext4. + + OEM unlock required + Device needs to be OEM unlocked before using 16K developer option. OEM unlock will also require formatting userdata. Please OEM unlock the device and try again. diff --git a/src/com/android/settings/development/Enable16KOemUnlockDialog.java b/src/com/android/settings/development/Enable16KOemUnlockDialog.java new file mode 100644 index 00000000000..65690df7ab4 --- /dev/null +++ b/src/com/android/settings/development/Enable16KOemUnlockDialog.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import android.app.Dialog; +import android.app.settings.SettingsEnums; +import android.content.DialogInterface; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; + +/** Dialog when user interacts 16K pages developer option and device is not OEM unlocked */ +public class Enable16KOemUnlockDialog extends InstrumentedDialogFragment + implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { + + public static final String TAG = "Enable16KOemUnlockDialog"; + + /** This method is used to prompt user to do OEM unlock before using 16k */ + public static void show(@NonNull Fragment hostFragment) { + final FragmentManager manager = hostFragment.getActivity().getSupportFragmentManager(); + Fragment existingFragment = manager.findFragmentByTag(TAG); + if (existingFragment == null) { + existingFragment = new Enable16KOemUnlockDialog(); + } + + if (existingFragment instanceof Enable16KOemUnlockDialog) { + existingFragment.setTargetFragment(hostFragment, 0 /* requestCode */); + ((Enable16KOemUnlockDialog) existingFragment).show(manager, TAG); + } + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.DIALOG_ENABLE_16K_PAGES; + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + return new AlertDialog.Builder(getActivity()) + .setTitle(R.string.confirm_oem_unlock_for_16k_title) + .setMessage(R.string.confirm_oem_unlock_for_16k_text) + .setPositiveButton(android.R.string.ok, this /* onClickListener */) + .create(); + } + + @Override + public void onClick(@NonNull DialogInterface dialog, int buttonId) { + // Do nothing. OEM unlock has to be done by user + } + + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + super.onDismiss(dialog); + } +} diff --git a/src/com/android/settings/development/Enable16kPagesPreferenceController.java b/src/com/android/settings/development/Enable16kPagesPreferenceController.java index 7049e79e5d4..bed5c0439cd 100644 --- a/src/com/android/settings/development/Enable16kPagesPreferenceController.java +++ b/src/com/android/settings/development/Enable16kPagesPreferenceController.java @@ -28,7 +28,10 @@ import android.os.SystemUpdateManager; import android.os.UpdateEngine; import android.os.UpdateEngineStable; import android.os.UpdateEngineStableCallback; +import android.os.UserHandle; +import android.os.UserManager; import android.provider.Settings; +import android.service.oemlock.OemLockManager; import android.util.Log; import android.widget.LinearLayout; import android.widget.ProgressBar; @@ -116,6 +119,12 @@ public class Enable16kPagesPreferenceController extends DeveloperOptionsPreferen @Override public boolean onPreferenceChange(Preference preference, Object newValue) { mEnable16k = (Boolean) newValue; + // Prompt user to do oem unlock first + if (!isDeviceOEMUnlocked()) { + Enable16KOemUnlockDialog.show(mFragment); + return false; + } + if (isDataf2fs()) { EnableExt4WarningDialog.show(mFragment, this); return false; @@ -418,4 +427,30 @@ public class Enable16kPagesPreferenceController extends DeveloperOptionsPreferen return false; } + + private boolean isDeviceOEMUnlocked() { + // OEM unlock is checked for bootloader, carrier and user. Check all three to ensure + // that device is unlocked and it is also allowed by user as well as carrier + final OemLockManager oemLockManager = mContext.getSystemService(OemLockManager.class); + final UserManager userManager = mContext.getSystemService(UserManager.class); + if (oemLockManager == null || userManager == null) { + Log.e(TAG, "Required services not found on device to check for OEM unlock state."); + return false; + } + + // If either of device or carrier is not allowed to unlock, return false + if (!oemLockManager.isDeviceOemUnlocked() + || !oemLockManager.isOemUnlockAllowedByCarrier()) { + Log.e(TAG, "Device is not OEM unlocked or it is not allowed by carrier"); + return false; + } + + final UserHandle userHandle = UserHandle.of(UserHandle.myUserId()); + if (userManager.hasBaseUserRestriction(UserManager.DISALLOW_FACTORY_RESET, userHandle)) { + Log.e(TAG, "Factory reset is not allowed for user."); + return false; + } + + return true; + } } -- cgit v1.2.3