From d12075a9493b3840d809eaf882729f67eda6e398 Mon Sep 17 00:00:00 2001 From: Michele Berionne Date: Mon, 1 Feb 2021 22:48:12 +0000 Subject: [PATCH 1/2] Hide keyguard when SIM transitions to READY The keyguard is not properly updated when the SIM PIN verification is performed using different means than the UI. Additional states are used before READY, so simWasLocked might be false. Bug: 160784387 Test: manual Change-Id: Ibca04e3d6a61c27d4b40f94a8a6223d9739b15ac --- .../keyguard/KeyguardViewMediator.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 5a918d4808d66..c55fdf4783e3b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -67,6 +67,7 @@ import android.telephony.TelephonyManager; import android.util.EventLog; import android.util.Log; import android.util.Slog; +import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.view.IRemoteAnimationFinishedCallback; import android.view.RemoteAnimationTarget; @@ -306,6 +307,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, */ private final SparseIntArray mLastSimStates = new SparseIntArray(); + /** + * Indicates if a SIM card had the SIM PIN enabled during the initialization, before + * reaching the SIM_STATE_READY state. The flag is reset to false at SIM_STATE_READY. + * Index is the slotId - in case of multiple SIM cards. + */ + private final SparseBooleanArray mSimWasLocked = new SparseBooleanArray(); + private boolean mDeviceInteractive; private boolean mGoingToSleep; @@ -477,10 +485,10 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } } - boolean simWasLocked; + boolean lastSimStateWasLocked; synchronized (KeyguardViewMediator.this) { int lastState = mLastSimStates.get(slotId); - simWasLocked = (lastState == TelephonyManager.SIM_STATE_PIN_REQUIRED + lastSimStateWasLocked = (lastState == TelephonyManager.SIM_STATE_PIN_REQUIRED || lastState == TelephonyManager.SIM_STATE_PUK_REQUIRED); mLastSimStates.append(slotId, simState); } @@ -504,17 +512,19 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, if (simState == TelephonyManager.SIM_STATE_ABSENT) { // MVNO SIMs can become transiently NOT_READY when switching networks, // so we should only lock when they are ABSENT. - if (simWasLocked) { + if (lastSimStateWasLocked) { if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to ABSENT when the " + "previous state was locked. Reset the state."); resetStateLocked(); } + mSimWasLocked.append(slotId, false); } } break; case TelephonyManager.SIM_STATE_PIN_REQUIRED: case TelephonyManager.SIM_STATE_PUK_REQUIRED: synchronized (KeyguardViewMediator.this) { + mSimWasLocked.append(slotId, true); if (!mShowing) { if (DEBUG_SIM_STATES) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't " @@ -541,9 +551,10 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, case TelephonyManager.SIM_STATE_READY: synchronized (KeyguardViewMediator.this) { if (DEBUG_SIM_STATES) Log.d(TAG, "READY, reset state? " + mShowing); - if (mShowing && simWasLocked) { + if (mShowing && mSimWasLocked.get(slotId, false)) { if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to READY when the " - + "previous state was locked. Reset the state."); + + "previously was locked. Reset the state."); + mSimWasLocked.append(slotId, false); resetStateLocked(); } } From 726fa0a5f400f95558dcb31effbb98fee67b54ed Mon Sep 17 00:00:00 2001 From: Michele Berionne Date: Thu, 19 Nov 2020 22:46:42 +0000 Subject: [PATCH 2/2] Add new API for unattended reboot. Details of the feature are available at: go/pin-after-ota CTS-Coverage-Bug: 179310594 Bug: 160784387 Test: manual Change-Id: I59b7ff7afec9846a114ee8d20f14d22cf69f0680 --- core/api/current.txt | 1 + core/api/system-current.txt | 4 ++ core/res/res/values/config.xml | 6 ++ core/res/res/values/symbols.xml | 1 + .../telephony/CarrierConfigManager.java | 16 +++++ .../android/telephony/TelephonyManager.java | 63 +++++++++++++++++++ .../internal/telephony/ITelephony.aidl | 14 +++++ 7 files changed, 105 insertions(+) diff --git a/core/api/current.txt b/core/api/current.txt index 28b7f9b79d490..92441e0e4c403 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -40334,6 +40334,7 @@ package android.telephony { field public static final String KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL = "simplified_network_settings_bool"; field public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool"; field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool"; + field public static final String KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL = "store_sim_pin_for_unattended_reboot_bool"; field public static final String KEY_SUPPORTS_CALL_COMPOSER_BOOL = "supports_call_composer_bool"; field public static final String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool"; field public static final String KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL = "support_add_conference_participants_bool"; diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 5bb3e05170329..058e5a872b6ae 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -11869,6 +11869,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String); method public boolean needsOtaServiceProvisioning(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled(); + method @RequiresPermission(android.Manifest.permission.REBOOT) public int prepareForUnattendedReboot(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean); method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); @@ -11993,6 +11994,9 @@ package android.telephony { field public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; // 0x2 field public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; // 0x3 field public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; // 0x1 + field public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2; // 0x2 + field public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1; // 0x1 + field public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0; // 0x0 field public static final int RADIO_POWER_OFF = 0; // 0x0 field public static final int RADIO_POWER_ON = 1; // 0x1 field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2 diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 25e7951efe284..2f63bf81d0198 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4707,4 +4707,10 @@ false + + + false + + + true diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9a165bb6fc302..eb853de5bfab4 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2647,6 +2647,7 @@ + diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index ac584c175c59d..21cf3e57115d0 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -4748,6 +4748,21 @@ public class CarrierConfigManager { public static final String KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL = "network_temp_not_metered_supported_bool"; + /* + * Boolean indicating whether the SIM PIN can be stored and verified + * seamlessly after an unattended reboot. + * + * The device configuration value {@code config_allow_pin_storage_for_unattended_reboot} + * ultimately controls whether this carrier configuration option is used. Where + * {@code config_allow_pin_storage_for_unattended_reboot} is false, the value of the + * {@link #KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL} carrier configuration option is + * ignored. + * + * @hide + */ + public static final String KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL = + "store_sim_pin_for_unattended_reboot_bool"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -5304,6 +5319,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_USE_ACS_FOR_RCS_BOOL, false); sDefaults.putBoolean(KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, true); sDefaults.putInt(KEY_DEFAULT_RTT_MODE_INT, 0); + sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true); } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 65b8de2b22168..441446cdc48da 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -14994,6 +14994,7 @@ public class TelephonyManager { } return THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR; } + /** * Registers a listener object to receive notification of changes * in specified telephony states. @@ -15350,4 +15351,66 @@ public class TelephonyManager { return PhoneCapability.DEFAULT_SSSS_CAPABILITY; } } + + /** + * The unattended reboot was prepared successfully. + * @hide + */ + @SystemApi + public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0; + + /** + * The unattended reboot was prepared, but the user will need to manually + * enter the PIN code of at least one SIM card present in the device. + * @hide + */ + @SystemApi + public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1; + + /** + * The unattended reboot was not prepared due to generic error. + * @hide + */ + @SystemApi + public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"}, + value = { + PREPARE_UNATTENDED_REBOOT_SUCCESS, + PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED, + PREPARE_UNATTENDED_REBOOT_ERROR + }) + public @interface PrepareUnattendedRebootResult {} + + /** + * Prepare TelephonyManager for an unattended reboot. The reboot is required to be done + * shortly (e.g. within 15 seconds) after the API is invoked. + * + *

Requires Permission: + * {@link android.Manifest.permission#REBOOT} + * + * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success. + * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains + * at least one SIM card for which the user needs to manually enter the PIN + * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case + * of error. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.REBOOT) + @PrepareUnattendedRebootResult + public int prepareForUnattendedReboot() { + try { + ITelephony service = getITelephony(); + if (service != null) { + return service.prepareForUnattendedReboot(); + } + } catch (RemoteException e) { + Log.e(TAG, "Telephony#prepareForUnattendedReboot RemoteException", e); + e.rethrowFromSystemServer(); + } + return PREPARE_UNATTENDED_REBOOT_ERROR; + } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 0cd17da3c0c5e..1d049530ba774 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2387,4 +2387,18 @@ interface ITelephony { * Gets the current phone capability. */ PhoneCapability getPhoneCapability(); + + /** + * Prepare TelephonyManager for an unattended reboot. The reboot is + * required to be done shortly after the API is invoked. + * + * Requires system privileges. + * + * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success. + * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains + * at least one SIM card for which the user needs to manually enter the PIN + * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case + * of error. + */ + int prepareForUnattendedReboot(); }