From 58dcca98441d83a88190aa504e48c4c05b0aad7b Mon Sep 17 00:00:00 2001 From: tmfang Date: Wed, 3 Jul 2019 20:44:42 +0800 Subject: [PATCH 1/5] Improve Settings launch performance From traces analysis, we found getFreeBytes was taking a long time to return. getFreeBytes was used when storage controller tried to get storage information. In order to prevent this case, we put the action which takes too much time in background thread. Test: I can't reproduce it locally. From code view, this is a reasonable root cause. Fixes: 136268875 Change-Id: I78e42cde88553c003f198cffb5747b352055f59a (cherry picked from commit 0c37f019f61f37b67e2297e99d96e8396d962f40) --- .../TopLevelStoragePreferenceController.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java index c6fc23b1df2..fdc5feb573e 100644 --- a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java +++ b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java @@ -20,10 +20,13 @@ import android.content.Context; import android.os.storage.StorageManager; import android.text.format.Formatter; +import androidx.preference.Preference; + import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.deviceinfo.PrivateStorageInfo; import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider; +import com.android.settingslib.utils.ThreadUtils; import java.text.NumberFormat; @@ -44,14 +47,22 @@ public class TopLevelStoragePreferenceController extends BasePreferenceControlle } @Override - public CharSequence getSummary() { - // TODO: Register listener. - final NumberFormat percentageFormat = NumberFormat.getPercentInstance(); - final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo( - mStorageManagerVolumeProvider); - double privateUsedBytes = info.totalBytes - info.freeBytes; - return mContext.getString(R.string.storage_summary, - percentageFormat.format(privateUsedBytes / info.totalBytes), - Formatter.formatFileSize(mContext, info.freeBytes)); + protected void refreshSummary(Preference preference) { + if (preference == null) { + return; + } + + ThreadUtils.postOnBackgroundThread(() -> { + final NumberFormat percentageFormat = NumberFormat.getPercentInstance(); + final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo( + mStorageManagerVolumeProvider); + final double privateUsedBytes = info.totalBytes - info.freeBytes; + + ThreadUtils.postOnMainThread(() -> { + preference.setSummary(mContext.getString(R.string.storage_summary, + percentageFormat.format(privateUsedBytes / info.totalBytes), + Formatter.formatFileSize(mContext, info.freeBytes))); + }); + }); } } From 8d2baf64c7d3bc6fc1167a574f989c6476467db5 Mon Sep 17 00:00:00 2001 From: Antony Sargent Date: Thu, 11 Jul 2019 11:04:09 -0700 Subject: [PATCH 2/5] Fix erasing of eSIMs for some devices Doing a factory data reset used to always erase eSIMs. Then a few months ago we added a default-on checkbox to let users opt out of erasing the eSIM during this process, but only had it show for some devices (ones which support the "fastboot oem esim_erase" command) by adding a system property named masterclear.allow_retain_esim_profiles_after_fdr. When recently updating the strings shown in the factory data reset screen and the confirmation dialog, we changed the code so that if that the checkbox is hidden we'll pass false for the ERASE_ESIMS_EXTRA parameter sent to the factory data reset confirmation dialog. This had the unintended side effect of making devices that don't specify true for masterclear.allow_retain_esim_profiles_after_fdr skip erasing the eSIM. This CL fixes that by removing the "is the checkbox hidden" check, going back to the previous behavior of just using the checkbox value, which is on by default even if hidden. Fixes: 135284765 Test: make RunSettingsRoboTests Change-Id: Ia9f335920e4e3c4a90f0a6a49d1722a0c19ea83d (cherry picked from commit 5f612a4b442494d08259a976eccb7192ffa0c534) --- src/com/android/settings/MasterClear.java | 3 +-- tests/robotests/src/com/android/settings/MasterClearTest.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java index 14a6aed9e79..0df39842f9d 100644 --- a/src/com/android/settings/MasterClear.java +++ b/src/com/android/settings/MasterClear.java @@ -182,8 +182,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL void showFinalConfirmation() { final Bundle args = new Bundle(); args.putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked()); - args.putBoolean(ERASE_ESIMS_EXTRA, - mEsimStorageContainer.getVisibility() == View.VISIBLE && mEsimStorage.isChecked()); + args.putBoolean(ERASE_ESIMS_EXTRA, mEsimStorage.isChecked()); new SubSettingLauncher(getContext()) .setDestination(MasterClearConfirm.class.getName()) .setArguments(args) diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java index 813e4aafa67..73adf937c86 100644 --- a/tests/robotests/src/com/android/settings/MasterClearTest.java +++ b/tests/robotests/src/com/android/settings/MasterClearTest.java @@ -163,7 +163,7 @@ public class MasterClearTest { verify(context).startActivity(intent.capture()); assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false)) - .isFalse(); + .isTrue(); } @Test From ad27235404c6e75638e55bb305cb0910b65adb3b Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Fri, 19 Jul 2019 01:46:36 +0800 Subject: [PATCH 3/5] Support new regulatory label for location Fixes: 137348817 Test: visual, robotests Change-Id: I165b1e859891c7897e837d82702582458cecbb0d (cherry picked from commit 49b1bc15450d823e86ee4b2b77d77dc9eeca388e) --- .../RegulatoryInfoDisplayActivity.java | 25 ++++-- .../res/drawable/regulatory_info.png | Bin 0 -> 159 bytes .../res/drawable/regulatory_info_sku.png | Bin 0 -> 159 bytes .../res/drawable/regulatory_info_sku1_coo.png | Bin 0 -> 159 bytes .../RegulatoryInfoDisplayActivityTest.java | 83 ++++++++++++++++++ 5 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 tests/robotests/res/drawable/regulatory_info.png create mode 100644 tests/robotests/res/drawable/regulatory_info_sku.png create mode 100644 tests/robotests/res/drawable/regulatory_info_sku1_coo.png create mode 100644 tests/robotests/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java diff --git a/src/com/android/settings/RegulatoryInfoDisplayActivity.java b/src/com/android/settings/RegulatoryInfoDisplayActivity.java index 8bc1cefec5d..4c7515d10f6 100644 --- a/src/com/android/settings/RegulatoryInfoDisplayActivity.java +++ b/src/com/android/settings/RegulatoryInfoDisplayActivity.java @@ -119,7 +119,8 @@ public class RegulatoryInfoDisplayActivity extends Activity implements } } - private int getResourceId() { + @VisibleForTesting + int getResourceId() { // Use regulatory_info by default. int resId = getResources().getIdentifier( REGULATORY_INFO_RESOURCE, "drawable", getPackageName()); @@ -134,6 +135,18 @@ public class RegulatoryInfoDisplayActivity extends Activity implements resId = id; } } + + // When hardware coo property exists, use regulatory_info__ resource if valid. + final String coo = getCoo(); + if (!TextUtils.isEmpty(coo) && !TextUtils.isEmpty(sku)) { + final String regulatory_info_coo_res = + REGULATORY_INFO_RESOURCE + "_" + sku.toLowerCase() + "_" + coo.toLowerCase(); + final int id = getResources().getIdentifier( + regulatory_info_coo_res, "drawable", getPackageName()); + if (id != 0) { + resId = id; + } + } return resId; } @@ -142,13 +155,15 @@ public class RegulatoryInfoDisplayActivity extends Activity implements finish(); // close the activity } - @VisibleForTesting - public static String getSku() { + private String getCoo() { + return SystemProperties.get("ro.boot.hardware.coo", ""); + } + + private String getSku() { return SystemProperties.get("ro.boot.hardware.sku", ""); } - @VisibleForTesting - public static String getRegulatoryInfoImageFileName() { + private String getRegulatoryInfoImageFileName() { final String sku = getSku(); if (TextUtils.isEmpty(sku)) { return DEFAULT_REGULATORY_INFO_FILEPATH; diff --git a/tests/robotests/res/drawable/regulatory_info.png b/tests/robotests/res/drawable/regulatory_info.png new file mode 100644 index 0000000000000000000000000000000000000000..65de26c0eb28b05d6d0d6903288e1bbbce409d18 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1SBVv2j2s6ii6yp7}lMWc?slj7I;J!Gca%q zgD@k*tT_@uLG}_)Usv`!oI*kxYUgfUzX24IEOCt}an8@pP0cG|a4t$sEJ;mKD9 Date: Tue, 23 Jul 2019 10:27:47 -0700 Subject: [PATCH 4/5] Remove prerelease driver option from Settings UI. BUG: 134881329 Test: Verified with Settings UI. Change-Id: Id610cbaec9b9a5a8be201e7952cb7715d2fe2eb4 (cherry picked from commit c2dfba01ca5dc94a00ed5d7b6aa2ba20759459fd) --- res/values/strings.xml | 2 -- .../GameDriverAppPreferenceControllerTest.java | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index bed96d80816..41e90ac0af5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10664,13 +10664,11 @@ @string/game_driver_app_preference_default @string/game_driver_app_preference_game_driver - @string/game_driver_app_preference_prerelease_driver @string/game_driver_app_preference_default @string/game_driver_app_preference_game_driver - @string/game_driver_app_preference_prerelease_driver @string/game_driver_app_preference_system diff --git a/tests/robotests/src/com/android/settings/development/gamedriver/GameDriverAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/gamedriver/GameDriverAppPreferenceControllerTest.java index f007ce257a2..dd5af2b6045 100644 --- a/tests/robotests/src/com/android/settings/development/gamedriver/GameDriverAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/gamedriver/GameDriverAppPreferenceControllerTest.java @@ -56,8 +56,7 @@ public class GameDriverAppPreferenceControllerTest { private static final int DEFAULT = 0; private static final int GAME_DRIVER = 1; - private static final int PRERELEASE_DRIVER = 2; - private static final int SYSTEM = 3; + private static final int SYSTEM = 2; private static final String TEST_APP_NAME = "testApp"; private static final String TEST_PKG_NAME = "testPkg"; @@ -80,6 +79,7 @@ public class GameDriverAppPreferenceControllerTest { private GameDriverAppPreferenceController mController; private CharSequence[] mValueList; private String mDialogTitle; + private String mPreferencePrereleaseDriver; @Before public void setUp() { @@ -89,6 +89,8 @@ public class GameDriverAppPreferenceControllerTest { mValueList = mContext.getResources().getStringArray(R.array.game_driver_app_preference_values); mDialogTitle = mContext.getResources().getString(R.string.game_driver_app_preference_title); + mPreferencePrereleaseDriver = + mContext.getResources().getString(R.string.game_driver_app_preference_prerelease_driver); } @Test @@ -207,9 +209,7 @@ public class GameDriverAppPreferenceControllerTest { assertThat(preference.getDialogTitle()).isEqualTo(mDialogTitle); assertThat(preference.getEntries()).isEqualTo(mValueList); assertThat(preference.getEntryValues()).isEqualTo(mValueList); - assertThat(preference.getEntry()).isEqualTo(mValueList[PRERELEASE_DRIVER]); - assertThat(preference.getValue()).isEqualTo(mValueList[PRERELEASE_DRIVER]); - assertThat(preference.getSummary()).isEqualTo(mValueList[PRERELEASE_DRIVER]); + assertThat(preference.getSummary()).isEqualTo(mPreferencePrereleaseDriver); } @Test From adef4840f3ffdc97503fe1ac0943381d43efe10d Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 26 Jul 2019 11:20:10 -0700 Subject: [PATCH 5/5] Do not request cancel authentication unless currently authenticating Currently we always send cancel() if ConfirmDeviceCredentialActivity goes into the background. However, if the biometric state is no longer authenticating, requesting cancel() in this state will result in an inconsistent state between BiometricService/client and ConfirmDeviceCredentials. BiometricService/client will receive the ERROR_CANCELED message incorrectly, while ConfirmDeviceCredential is showing / pending user password. When the password is entered, its result is ignored. The correct behavior is for ConfirmDeviceCredentialActivity to invoke cancel() only if it's still authenticating. Otherwise BiometricService and its client will receive ERROR_CANCELED, instead of the actual password auth result. Bug: 138279856 Test: BiometricPromptDemo, enable device credential fallback, get into lockout state, successfully enter password. API result is success instead of "canceled" now. Change-Id: I6521e896d0402fe856dc85476f51149c9b3084a8 Merged-In: I6521e896d0402fe856dc85476f51149c9b3084a8 (cherry picked from commit 49c7d0765090750f88f11153dfcf9ec378b0c84d) --- src/com/android/settings/password/BiometricFragment.java | 8 ++++++++ .../password/ConfirmDeviceCredentialActivity.java | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java index bd5a10de464..66b665b337e 100644 --- a/src/com/android/settings/password/BiometricFragment.java +++ b/src/com/android/settings/password/BiometricFragment.java @@ -58,11 +58,13 @@ public class BiometricFragment extends InstrumentedFragment { private Bundle mBundle; private BiometricPrompt mBiometricPrompt; private CancellationSignal mCancellationSignal; + private boolean mAuthenticating; private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() { @Override public void onAuthenticationError(int error, @NonNull CharSequence message) { + mAuthenticating = false; mClientExecutor.execute(() -> { mClientCallback.onAuthenticationError(error, message); }); @@ -71,6 +73,7 @@ public class BiometricFragment extends InstrumentedFragment { @Override public void onAuthenticationSucceeded(AuthenticationResult result) { + mAuthenticating = false; mClientExecutor.execute(() -> { mClientCallback.onAuthenticationSucceeded(result); }); @@ -134,6 +137,10 @@ public class BiometricFragment extends InstrumentedFragment { } } + boolean isAuthenticating() { + return mAuthenticating; + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -180,6 +187,7 @@ public class BiometricFragment extends InstrumentedFragment { mCancellationSignal = new CancellationSignal(); // TODO: CC doesn't use crypto for now + mAuthenticating = true; mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor, mAuthenticationCallback, mUserId, mCancelCallback); } diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java index 53841e89beb..8476f924291 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java @@ -251,7 +251,10 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity { if (!isChangingConfigurations()) { mGoingToBackground = true; if (mBiometricFragment != null) { - mBiometricFragment.cancel(); + Log.d(TAG, "Authenticating: " + mBiometricFragment.isAuthenticating()); + if (mBiometricFragment.isAuthenticating()) { + mBiometricFragment.cancel(); + } } if (mIsFallback && !mCCLaunched) {