From c3c6d6d876f7d611165941346b00ee603aa4d561 Mon Sep 17 00:00:00 2001 From: Tim Peng Date: Wed, 23 Jun 2021 16:01:14 +0800 Subject: [PATCH 01/11] Sound panel doesn't match material next design for Android S -title layout/margin/font size adjustment -remove panel gap on left and right sides -apply round corner 28dp only on top two corners Bug: 191317779 Test: make -j50 RunSettingsRoboTests Change-Id: I8ebd9238a7e746a48ae6baa4361600b5a21446c1 --- ...gs_panel_rounded_top_corner_background.xml | 26 +++++++++++++++++++ res/layout/panel_layout.xml | 18 ++++++++----- res/values/dimens.xml | 4 +++ 3 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 res/drawable/settings_panel_rounded_top_corner_background.xml diff --git a/res/drawable/settings_panel_rounded_top_corner_background.xml b/res/drawable/settings_panel_rounded_top_corner_background.xml new file mode 100644 index 00000000000..1c234cca9b3 --- /dev/null +++ b/res/drawable/settings_panel_rounded_top_corner_background.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/layout/panel_layout.xml b/res/layout/panel_layout.xml index 674e20ecaf3..9e15f151eda 100644 --- a/res/layout/panel_layout.xml +++ b/res/layout/panel_layout.xml @@ -20,7 +20,7 @@ android:id="@+id/panel_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/settings_panel_background" > + android:background="@drawable/settings_panel_rounded_top_corner_background" > @@ -51,14 +55,13 @@ android:id="@+id/header_layout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" android:orientation="vertical"> + android:textSize="24sp" + android:fontFamily="sans-serif-reqular"/> 52dp 16dp + + 28dp + 24dp + 24dp From e92f5df3be0d8111fe5bd83891bb6aad52986dc8 Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Wed, 23 Jun 2021 10:36:17 +0100 Subject: [PATCH 02/11] Update CA certificate warning to material next spec * Fix colour extraction * Update landscape mode * Update logo Screenshots: * https://screenshot.googleplex.com/5mwbKLJeFVecrpi * https://screenshot.googleplex.com/9z62Sw26NX5Zfwu Bug: 191845997 Test: Manual testing with Settings Change-Id: Id9988dbce9eabc2b69dba4bd20ca7a6729601147 --- res/drawable-hdpi/ic_warning_googred_48dp.png | Bin 603 -> 0 bytes res/drawable/ic_alert_red.xml | 31 ++++++++++++++++++ res/layout/ca_certificate_warning_dialog.xml | 27 ++++----------- res/values/strings.xml | 2 +- .../security/InstallCaCertificateWarning.java | 5 +++ 5 files changed, 44 insertions(+), 21 deletions(-) delete mode 100644 res/drawable-hdpi/ic_warning_googred_48dp.png create mode 100644 res/drawable/ic_alert_red.xml diff --git a/res/drawable-hdpi/ic_warning_googred_48dp.png b/res/drawable-hdpi/ic_warning_googred_48dp.png deleted file mode 100644 index 70381dd06bba417985d62217728f0f53ebdf05aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 603 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAjKZ-7sT>uneF!GoMdE~^0@rdJZ= z7tG+rdhc+;^(R{&RR=)$Hm%u_;l%YQx@7`4v&wTjZxz zV>dtBFRH$>$1G&a*AG)qDeYb#k``wE%*S{0`l&Oo<`!@3yLjDsxAE>ZufDC6nR(T> zpjRTIR=5Amt7SXfd$#Q3QeL}DxMgC{UCB=!K95%$Tw1l;!8l3tw^q-VSI=I!i7Z<0 zA$s=eu(jaGeZay=&9@O}pyXcu(KQXsBuD Vb1`@l2QX3?JYD@<);T3K0RTxy6iomC diff --git a/res/drawable/ic_alert_red.xml b/res/drawable/ic_alert_red.xml new file mode 100644 index 00000000000..7b991fb38ef --- /dev/null +++ b/res/drawable/ic_alert_red.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/res/layout/ca_certificate_warning_dialog.xml b/res/layout/ca_certificate_warning_dialog.xml index d863b08aa4b..2bb2b706db5 100644 --- a/res/layout/ca_certificate_warning_dialog.xml +++ b/res/layout/ca_certificate_warning_dialog.xml @@ -18,37 +18,24 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/setup_wizard_layout" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:icon="@drawable/ic_alert_red"> - - - - + android:orientation="vertical"> diff --git a/res/values/strings.xml b/res/values/strings.xml index 92a90cea302..83c80c57b77 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6792,7 +6792,7 @@ Your data won\u2019t be private - CA certificates are used by websites, apps, and VPNs for encryption. Only install CA certificates from organizations you trust. \n\n If you install a CA certificate, the certificate owner could access your data, such as passwords or credit card details, from websites you visit or apps you use – even if your data is encrypted. + CA certificates are used by websites, apps, and VPNs for encryption. Only install CA certificates from organizations you trust. \n\nIf you install a CA certificate, the certificate owner could access your data, such as passwords or credit card details, from websites you visit or apps you use – even if your data is encrypted. Don\u2019t install diff --git a/src/com/android/settings/security/InstallCaCertificateWarning.java b/src/com/android/settings/security/InstallCaCertificateWarning.java index 91faae1f6a1..38548756a31 100644 --- a/src/com/android/settings/security/InstallCaCertificateWarning.java +++ b/src/com/android/settings/security/InstallCaCertificateWarning.java @@ -25,10 +25,12 @@ import android.view.View; import android.widget.Toast; import com.android.settings.R; +import com.android.settings.SetupWizardUtils; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupdesign.GlifLayout; +import com.google.android.setupdesign.util.ThemeHelper; /** * Creates a warning dialog explaining the consequences of installing a CA certificate @@ -40,8 +42,11 @@ public class InstallCaCertificateWarning extends Activity { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setTheme(SetupWizardUtils.getTheme(this, getIntent())); + ThemeHelper.trySetDynamicColor(this); setContentView(R.layout.ca_certificate_warning_dialog); final GlifLayout layout = findViewById(R.id.setup_wizard_layout); + layout.setHeaderText(R.string.ca_certificate_warning_title); final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class); mixin.setSecondaryButton( From 7025a83f39ca0780192cc09cf8168c067386a9f1 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 22 Jun 2021 19:58:58 -0600 Subject: [PATCH 03/11] Update to modern Bluetooth permissions. The Settings app offers several Bluetooth intents, and they need to be updated to enforce the new "Nearby devices" runtime permission model, since the old BLUETOOTH and BLUETOOTH_ADMIN permissions have been deprecated. Bug: 191174082 Test: TH Change-Id: I0d812f486bc3dadc517d5b04d3082d4f56f60ef4 --- AndroidManifest.xml | 15 +++++++-------- .../bluetooth/BluetoothPermissionActivity.java | 2 +- .../bluetooth/BluetoothPermissionRequest.java | 2 +- .../settings/bluetooth/DevicePickerFragment.java | 2 +- .../BluetoothPermissionActivityTest.java | 2 +- .../bluetooth/DevicePickerFragmentTest.java | 2 +- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6f6482daeb5..01d1c039201 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,8 +17,7 @@ - - + @@ -2222,7 +2221,7 @@ @@ -2265,7 +2264,7 @@ @@ -2280,7 +2279,7 @@ + android:permission="android.permission.BLUETOOTH_CONNECT"> @@ -2290,7 +2289,7 @@ @@ -3545,7 +3544,7 @@ + android:permission="android.permission.BLUETOOTH_CONNECT"> @@ -3750,7 +3749,7 @@ + android:permission="android.permission.BLUETOOTH_CONNECT"> /> diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java index 211bcc6f4b4..c8f71c400b9 100644 --- a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java +++ b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java @@ -221,7 +221,7 @@ public class BluetoothPermissionActivity extends AlertActivity implements intent.putExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, always); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, mRequestType); - sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_ADMIN); + sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_CONNECT); } public void onClick(DialogInterface dialog, int which) { diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java index ff1c1471c02..bd33261fdd1 100644 --- a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java +++ b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java @@ -293,6 +293,6 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver { : BluetoothDevice.CONNECTION_ACCESS_NO); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, mRequestType); - mContext.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_ADMIN); + mContext.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_CONNECT); } } diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java index 02b5d5c90f0..602b79b2ae9 100644 --- a/src/com/android/settings/bluetooth/DevicePickerFragment.java +++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java @@ -212,6 +212,6 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment { } } - mContext.sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN); + mContext.sendBroadcast(intent, Manifest.permission.BLUETOOTH_CONNECT); } } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java index 35b8f1f00a1..6f027531d65 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPermissionActivityTest.java @@ -53,6 +53,6 @@ public class BluetoothPermissionActivityTest { mActivity.sendReplyIntentToReceiver(true, true); verify(mContext).sendBroadcast(intentCaptor.capture(), - eq("android.permission.BLUETOOTH_ADMIN")); + eq("android.permission.BLUETOOTH_CONNECT")); } } diff --git a/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java index a05ec87b71b..8cd465ca007 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/DevicePickerFragmentTest.java @@ -82,7 +82,7 @@ public class DevicePickerFragmentTest { mFragment.onDeviceBondStateChanged(cachedDevice, BluetoothDevice.BOND_BONDED); verify(mContext).sendBroadcast(intentCaptor.capture(), - eq("android.permission.BLUETOOTH_ADMIN")); + eq("android.permission.BLUETOOTH_CONNECT")); assertThat(intentCaptor.getValue().getComponent().getPackageName()) .isEqualTo(mFragment.mLaunchPackage); } From e619d227c9b1625e0267503cc18ab3b4cb10148b Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Wed, 23 Jun 2021 16:08:47 -0700 Subject: [PATCH 04/11] isCarrierNetworkActive() should check if the carrier network is default WifiPickerTrackerHelper should use MergedCarrierEntry.isDefaultNetwork() for isCarrierNetworkActive(). Bug: 191090765 Test: atest WifiPickerTrackerHelperTest Change-Id: I44d8eed3af019a8d6a30a4b743cad468d1f0469b --- src/com/android/settings/wifi/WifiPickerTrackerHelper.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/com/android/settings/wifi/WifiPickerTrackerHelper.java b/src/com/android/settings/wifi/WifiPickerTrackerHelper.java index 424c818cb65..03795c25971 100644 --- a/src/com/android/settings/wifi/WifiPickerTrackerHelper.java +++ b/src/com/android/settings/wifi/WifiPickerTrackerHelper.java @@ -142,11 +142,7 @@ public class WifiPickerTrackerHelper implements LifecycleObserver { /** Confirms connection of the carrier network connected with the internet access */ public boolean isCarrierNetworkActive() { final MergedCarrierEntry mergedCarrierEntry = mWifiPickerTracker.getMergedCarrierEntry(); - if (mergedCarrierEntry != null) { - return mergedCarrierEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED - && mergedCarrierEntry.hasInternetAccess(); - } - return false; + return (mergedCarrierEntry != null && mergedCarrierEntry.isDefaultNetwork()); } /** Return the carrier network ssid */ From d3a07c29bf4f19af7e07260421f86fe5bdfbc0f8 Mon Sep 17 00:00:00 2001 From: Curtis Belmonte Date: Wed, 23 Jun 2021 14:16:22 -0700 Subject: [PATCH 05/11] Fix face education UX for both grid and traffic light Makes the following adjustments to the UI of the Face Unlock education screen for both the grid and traffic light enrollment flows: - Fixes issues with text being overlapped by illustrations - Prevents views from moving vertically due to state changes - Ensures no scroll is required for default locale and scaling - Adjusts the color and content of the a11y setup toggle Test: Manual: 1. Start grid-based face enrollment (e.g. from Settings > Security) 2. Proceed to "How to set up Face Unlock" screen 3. Tap "Setup for limited vision or head motion" 4. Toggle "Setup for limited vision or head motion" switch off and on 5. Repeat steps 1-4 for traffic light face enrollment Fixes: 191105436 Fixes: 191317385 Change-Id: Ie80f5b3130b5b0aeceb889f53cc2dec8c7423e47 --- .../face_enroll_accessibility_toggle.xml | 10 +++-- res/layout/face_enroll_education.xml | 7 +-- .../biometrics/face/FaceEnrollEducation.java | 44 +++---------------- 3 files changed, 18 insertions(+), 43 deletions(-) diff --git a/res/layout/face_enroll_accessibility_toggle.xml b/res/layout/face_enroll_accessibility_toggle.xml index bb3a7ffb99d..a56655dafb9 100644 --- a/res/layout/face_enroll_accessibility_toggle.xml +++ b/res/layout/face_enroll_accessibility_toggle.xml @@ -30,15 +30,18 @@ + android:layout_height="wrap_content" + android:textColor="?android:attr/textColorPrimary" + android:textSize="@dimen/sud_description_text_size" + /> + android:text="@string/security_settings_face_enroll_introduction_accessibility_expanded" + android:textColor="?android:attr/textColorSecondary"/> + android:layout_height="match_parent" + app:sucHeaderText="@string/security_settings_face_enroll_education_title"> + android:layout_marginTop="-24dp"> + app:messageText="@string/security_settings_face_enroll_introduction_accessibility"/> diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index 8e2d3f4b6bc..65ab2e7c783 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -16,20 +16,17 @@ package com.android.settings.biometrics.face; -import android.annotation.StringRes; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Intent; import android.hardware.face.FaceManager; import android.os.Bundle; -import android.os.Handler; import android.os.UserHandle; import android.text.TextUtils; import android.view.View; import android.view.accessibility.AccessibilityManager; import android.widget.Button; import android.widget.CompoundButton; -import android.widget.TextView; import com.android.settings.R; import com.android.settings.Utils; @@ -41,14 +38,10 @@ import com.airbnb.lottie.LottieAnimationView; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.util.WizardManagerHelper; -import com.google.android.setupdesign.GlifLayout; import com.google.android.setupdesign.view.IllustrationVideoView; public class FaceEnrollEducation extends BiometricEnrollBase { - private static final String TAG = "FaceEducation"; - private static final int ON = 1; - private static final int OFF = 0; private FaceManager mFaceManager; private FaceEnrollAccessibilityToggle mSwitchDiversity; @@ -57,28 +50,18 @@ public class FaceEnrollEducation extends BiometricEnrollBase { private IllustrationVideoView mIllustrationDefault; private LottieAnimationView mIllustrationLottie; private View mIllustrationAccessibility; - private Handler mHandler; private Intent mResultIntent; - private TextView mDescriptionText; private boolean mNextClicked; private boolean mAccessibilityEnabled; - private CompoundButton.OnCheckedChangeListener mSwitchDiversityListener = + private final CompoundButton.OnCheckedChangeListener mSwitchDiversityListener = new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - final int headerRes; - final int descriptionRes; - if (isChecked) { - headerRes = R.string - .security_settings_face_enroll_education_title_accessibility; - descriptionRes = R.string - .security_settings_face_enroll_education_message_accessibility; - } else { - headerRes = R.string.security_settings_face_enroll_education_title; - descriptionRes = R.string.security_settings_face_enroll_education_message; - } - updateHeaders(headerRes, descriptionRes); + final int descriptionRes = isChecked + ? R.string.security_settings_face_enroll_education_message_accessibility + : R.string.security_settings_face_enroll_education_message; + setDescriptionText(descriptionRes); if (isChecked) { hideDefaultIllustration(); @@ -95,18 +78,14 @@ public class FaceEnrollEducation extends BiometricEnrollBase { super.onCreate(savedInstanceState); setContentView(R.layout.face_enroll_education); - final int headerRes = R.string.security_settings_face_enroll_education_title; - final int descriptionRes = R.string.security_settings_face_enroll_education_message; - updateHeaders(headerRes, descriptionRes); - - mHandler = new Handler(); + setTitle(R.string.security_settings_face_enroll_education_title); + setDescriptionText(R.string.security_settings_face_enroll_education_message); mFaceManager = Utils.getFaceManagerOrNull(this); mIllustrationDefault = findViewById(R.id.illustration_default); mIllustrationLottie = findViewById(R.id.illustration_lottie); mIllustrationAccessibility = findViewById(R.id.illustration_accessibility); - mDescriptionText = findViewById(R.id.sud_layout_description); mIsUsingLottie = getResources().getBoolean(R.bool.config_face_education_use_lottie); if (mIsUsingLottie) { @@ -259,15 +238,6 @@ public class FaceEnrollEducation extends BiometricEnrollBase { return SettingsEnums.FACE_ENROLL_INTRO; } - private void updateHeaders(@StringRes int headerRes, @StringRes int descriptionRes) { - final CharSequence headerText = getText(headerRes); - setTitle(headerText); - - final GlifLayout layout = getLayout(); - layout.setHeaderText(headerText); - layout.setDescriptionText(descriptionRes); - } - private void hideDefaultIllustration() { if (mIsUsingLottie) { mIllustrationLottie.cancelAnimation(); From e461e673ac24b19a10a17fe7770d3ebd81497d5b Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Wed, 23 Jun 2021 23:54:12 +0800 Subject: [PATCH 06/11] Fix crashes when clearing storage for a protected package When clearing storage for a protected package, ActivityManager throws a SecurityException. This change catches the exception then shows a dialog with the message "Couldn't clear storage for app". Bug: 191806850 Test: manual visual 1. Lock the device. 2. Clear storage for a protected package. Change-Id: Ic3e2c2237c6ee6dc945b03dac35b3b96a26129a9 --- .../android/settings/applications/AppStorageSettings.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java index d095e37a5bf..91eeace0fd3 100644 --- a/src/com/android/settings/applications/AppStorageSettings.java +++ b/src/com/android/settings/applications/AppStorageSettings.java @@ -368,7 +368,12 @@ public class AppStorageSettings extends AppInfoWithHeader } ActivityManager am = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE); - boolean res = am.clearApplicationUserData(packageName, mClearDataObserver); + boolean res = false; + try { + res = am.clearApplicationUserData(packageName, mClearDataObserver); + } catch (SecurityException e) { + Log.i(TAG, "Failed to clear application user data: " + e); + } if (!res) { // Clearing data failed for some obscure reason. Just log error for now Log.i(TAG, "Couldn't clear application user data for package:" + packageName); From 4f1d2ebfdf5624e05f26e367453564b0c97e5211 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Wed, 23 Jun 2021 20:32:25 +0800 Subject: [PATCH 07/11] Tweak UI of profile tab layout - Change color & shape of indicator. - Add margin around tab layout. - Remove divider below the tab layout. Bug: 188589806 Bug: 188589053 Test: manual visual Change-Id: I644a4aeb951daa6eb601229fa5f1096dcbdc86ca --- res/drawable/tabs_indicator_background.xml | 24 ++++++++++++++++++++++ res/layout/preference_list_fragment.xml | 14 +++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 res/drawable/tabs_indicator_background.xml diff --git a/res/drawable/tabs_indicator_background.xml b/res/drawable/tabs_indicator_background.xml new file mode 100644 index 00000000000..d326e650fe2 --- /dev/null +++ b/res/drawable/tabs_indicator_background.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/res/layout/preference_list_fragment.xml b/res/layout/preference_list_fragment.xml index f8ffa8f2e47..03ba735db97 100644 --- a/res/layout/preference_list_fragment.xml +++ b/res/layout/preference_list_fragment.xml @@ -19,6 +19,7 @@ - Date: Wed, 23 Jun 2021 00:26:34 +0800 Subject: [PATCH 08/11] Fix a flicker problem on top app bar The height of top app bar area is dependent on the line count of multiline title. This mechanism is always triggered when entering either subsetting page or rotating the screen, regardless the state of collapsing toolbar. That is saying this mechanism caused a flicker problem or a title in wrong color. The mechanism will be updated to check the state of collapsing toolbar to make sure that it is only triggered if the collapsing toolbar is in expanded state. Fix: 186419089 Fix: 187709056 Test: visual verified 1) Navigate to a subsetting page with multiline title 2) Rotate the screen to landscape mode and collapse the title 3) Rotate the screen to portrait mode and see if the title is in collapsed state Change-Id: I3da2403fa43913469e64bd37e761b41a083efd38 --- .../settings/core/SettingsBaseActivity.java | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java index fb6b49f966e..fd6ca5069a1 100644 --- a/src/com/android/settings/core/SettingsBaseActivity.java +++ b/src/com/android/settings/core/SettingsBaseActivity.java @@ -48,7 +48,8 @@ import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupdesign.util.ThemeHelper; /** Base activity for Settings pages */ -public class SettingsBaseActivity extends FragmentActivity implements CategoryHandler { +public class SettingsBaseActivity extends FragmentActivity implements CategoryHandler, + AppBarLayout.OnOffsetChangedListener { /** * What type of page transition should be apply. @@ -58,11 +59,15 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa protected static final boolean DEBUG_TIMING = false; private static final String TAG = "SettingsBaseActivity"; private static final int DEFAULT_REQUEST = -1; + private static final int FULLY_EXPANDED_OFFSET = 0; + private static final int TOOLBAR_MAX_LINE_NUMBER = 2; + private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed"; protected CategoryMixin mCategoryMixin; protected CollapsingToolbarLayout mCollapsingToolbarLayout; protected AppBarLayout mAppBarLayout; private Toolbar mToolbar; + private boolean mIsToolbarCollapsed; @Override public CategoryMixin getCategoryMixin() { @@ -100,6 +105,11 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa super.setContentView(R.layout.collapsing_toolbar_base_layout); mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar); mAppBarLayout = findViewById(R.id.app_bar); + mAppBarLayout.addOnOffsetChangedListener(this); + if (savedInstanceState != null) { + mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED); + } + initCollapsingToolbar(); disableCollapsingToolbarLayoutScrollingBehavior(); } else { super.setContentView(R.layout.settings_base_layout); @@ -191,6 +201,23 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa } } + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int offset) { + if (offset == FULLY_EXPANDED_OFFSET) { + mIsToolbarCollapsed = false; + } else { + mIsToolbarCollapsed = true; + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (isChangingConfigurations()) { + outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed); + } + } + /** * SubSetting page should show a toolbar by default. If the page wouldn't show a toolbar, * override this method and return false value. @@ -238,6 +265,9 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa } private void disableCollapsingToolbarLayoutScrollingBehavior() { + if (mAppBarLayout == null) { + return; + } final CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams(); final AppBarLayout.Behavior behavior = new AppBarLayout.Behavior(); @@ -254,4 +284,39 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa private int getTransitionType(Intent intent) { return intent.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_NONE); } + + @SuppressWarnings("RestrictTo") + private void initCollapsingToolbar() { + if (mCollapsingToolbarLayout == null || mAppBarLayout == null) { + return; + } + mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + v.removeOnLayoutChangeListener(this); + if (mIsToolbarCollapsed) { + return; + } + final int count = mCollapsingToolbarLayout.getLineCount(); + if (count > TOOLBAR_MAX_LINE_NUMBER) { + final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams(); + lp.height = getResources() + .getDimensionPixelSize(R.dimen.toolbar_three_lines_height); + mCollapsingToolbarLayout.setScrimVisibleHeightTrigger( + getResources().getDimensionPixelSize( + R.dimen.scrim_visible_height_trigger_three_lines)); + mCollapsingToolbarLayout.setLayoutParams(lp); + } else if (count == TOOLBAR_MAX_LINE_NUMBER) { + final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams(); + lp.height = getResources() + .getDimensionPixelSize(R.dimen.toolbar_two_lines_height); + mCollapsingToolbarLayout.setScrimVisibleHeightTrigger( + getResources().getDimensionPixelSize( + R.dimen.scrim_visible_height_trigger_two_lines)); + mCollapsingToolbarLayout.setLayoutParams(lp); + } + } + }); + } } From 0358562a9b069d0021eaca1cc6b88ff5f6ea0e60 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Thu, 24 Jun 2021 07:45:15 +0000 Subject: [PATCH 09/11] Revert "Fix 'No Apps' UI issues of ManageApplications" This reverts commit 4a97095e364f279194af6b7d5721e8892ae12cf9. Reason for revert: Bug: 191945032 Bug: 191944934 Change-Id: Id6c71fbec4f490034bc07f6d8c9efabcb877d110 --- res/layout/manage_applications_apps.xml | 61 +++++++++-------- res/values/dimens.xml | 2 + .../applications/RunningServices.java | 6 +- .../ManageApplications.java | 52 +++++++++----- .../widget/LoadingViewController.java | 68 +++---------------- .../ManageApplicationsTest.java | 28 +++++++- 6 files changed, 102 insertions(+), 115 deletions(-) diff --git a/res/layout/manage_applications_apps.xml b/res/layout/manage_applications_apps.xml index 055e4b453e3..d814164647a 100644 --- a/res/layout/manage_applications_apps.xml +++ b/res/layout/manage_applications_apps.xml @@ -14,7 +14,7 @@ limitations under the License. --> - + android:elevation="2dp"/> - + android:layout_height="match_parent" + android:visibility="gone"> - + - + - + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index b1f5b302e99..eb0d46b7f10 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -149,6 +149,8 @@ 182dp 32dp 24dp + + 80dp 88dip diff --git a/src/com/android/settings/applications/RunningServices.java b/src/com/android/settings/applications/RunningServices.java index b1689d5c591..4d13241126f 100644 --- a/src/com/android/settings/applications/RunningServices.java +++ b/src/com/android/settings/applications/RunningServices.java @@ -72,11 +72,7 @@ public class RunningServices extends SettingsPreferenceFragment { public void onResume() { super.onResume(); boolean haveData = mRunningProcessesView.doResume(this, mRunningProcessesAvail); - if (haveData) { - mLoadingViewController.showContent(false /* animate */); - } else { - mLoadingViewController.showLoadingView(); - } + mLoadingViewController.handleLoadingContainer(haveData /* done */, false /* animate */); } @Override diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index 43e929b8054..6d675240b64 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -208,6 +208,7 @@ public class ManageApplications extends InstrumentedFragment private ApplicationsAdapter mApplications; private View mLoadingContainer; + private View mListContainer; private SearchView mSearchView; // Size resource used for packages whose size computation failed for some reason @@ -401,21 +402,25 @@ public class ManageApplications extends InstrumentedFragment mRootView = inflater.inflate(R.layout.manage_applications_apps, null); mLoadingContainer = mRootView.findViewById(R.id.loading_container); - mEmptyView = mRootView.findViewById(android.R.id.empty); - mRecyclerView = mRootView.findViewById(R.id.apps_list); + mListContainer = mRootView.findViewById(R.id.list_container); + if (mListContainer != null) { + // Create adapter and list view here + mEmptyView = mListContainer.findViewById(android.R.id.empty); - mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter, - savedInstanceState); - if (savedInstanceState != null) { - mApplications.mHasReceivedLoadEntries = - savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false); - mApplications.mHasReceivedBridgeCallback = - savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); + mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter, + savedInstanceState); + if (savedInstanceState != null) { + mApplications.mHasReceivedLoadEntries = + savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false); + mApplications.mHasReceivedBridgeCallback = + savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); + } + mRecyclerView = mListContainer.findViewById(R.id.apps_list); + mRecyclerView.setItemAnimator(null); + mRecyclerView.setLayoutManager(new LinearLayoutManager( + getContext(), RecyclerView.VERTICAL, false /* reverseLayout */)); + mRecyclerView.setAdapter(mApplications); } - mRecyclerView.setItemAnimator(null); - mRecyclerView.setLayoutManager(new LinearLayoutManager( - getContext(), RecyclerView.VERTICAL, false /* reverseLayout */)); - mRecyclerView.setAdapter(mApplications); // We have to do this now because PreferenceFrameLayout looks at it // only when the view is added. @@ -980,8 +985,16 @@ public class ManageApplications extends InstrumentedFragment // overlapped by floating filter. if (hasFilter) { mManageApplications.mSpinnerHeader.setVisibility(View.VISIBLE); + mManageApplications.mRecyclerView.setPadding(0 /* left */, + mContext.getResources().getDimensionPixelSize( + R.dimen.app_bar_height) /* top */, + 0 /* right */, + 0 /* bottom */); } else { mManageApplications.mSpinnerHeader.setVisibility(View.GONE); + mManageApplications.mRecyclerView.setPadding(0 /* left */, 0 /* top */, + 0 /* right */, + 0 /* bottom */); } } } @@ -1031,8 +1044,7 @@ public class ManageApplications extends InstrumentedFragment mManageApplications = manageApplications; mLoadingViewController = new LoadingViewController( mManageApplications.mLoadingContainer, - mManageApplications.mRecyclerView, - mManageApplications.mEmptyView + mManageApplications.mListContainer ); mContext = manageApplications.getActivity(); mIconDrawableFactory = IconDrawableFactory.newInstance(mContext); @@ -1291,9 +1303,11 @@ public class ManageApplications extends InstrumentedFragment mOriginalEntries = entries; notifyDataSetChanged(); if (getItemCount() == 0) { - mLoadingViewController.showEmpty(false /* animate */); + mManageApplications.mRecyclerView.setVisibility(View.GONE); + mManageApplications.mEmptyView.setVisibility(View.VISIBLE); } else { - mLoadingViewController.showContent(false /* animate */); + mManageApplications.mEmptyView.setVisibility(View.GONE); + mManageApplications.mRecyclerView.setVisibility(View.VISIBLE); if (mManageApplications.mSearchView != null && mManageApplications.mSearchView.isVisibleToUser()) { @@ -1310,6 +1324,10 @@ public class ManageApplications extends InstrumentedFragment mLastIndex = -1; } + if (mSession.getAllApps().size() != 0 + && mManageApplications.mListContainer.getVisibility() != View.VISIBLE) { + mLoadingViewController.showContent(true /* animate */); + } if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) { // No enabled or disabled filters for usage access. return; diff --git a/src/com/android/settings/widget/LoadingViewController.java b/src/com/android/settings/widget/LoadingViewController.java index 66eebf387ba..294e55e7ea8 100644 --- a/src/com/android/settings/widget/LoadingViewController.java +++ b/src/com/android/settings/widget/LoadingViewController.java @@ -22,66 +22,34 @@ import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; -import androidx.annotation.Nullable; - /** - * A helper class that manages show/hide loading spinner, content view and empty view (optional). + * A helper class that manages show/hide loading spinner. */ public class LoadingViewController { private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L; - private final Handler mFgHandler; - private final View mLoadingView; - private final View mContentView; - private final View mEmptyView; + public final Handler mFgHandler; + public final View mLoadingView; + public final View mContentView; public LoadingViewController(View loadingView, View contentView) { - this(loadingView, contentView, null /* emptyView*/); - } - - public LoadingViewController(View loadingView, View contentView, @Nullable View emptyView) { mLoadingView = loadingView; mContentView = contentView; - mEmptyView = emptyView; mFgHandler = new Handler(Looper.getMainLooper()); } private Runnable mShowLoadingContainerRunnable = new Runnable() { public void run() { - showLoadingView(); + handleLoadingContainer(false /* done */, false /* animate */); } }; - /** - * Shows content view and hides loading view & empty view. - */ public void showContent(boolean animate) { // Cancel any pending task to show the loading animation and show the list of // apps directly. mFgHandler.removeCallbacks(mShowLoadingContainerRunnable); - handleLoadingContainer(true /* showContent */, false /* showEmpty*/, animate); - } - - /** - * Shows empty view and hides loading view & content view. - */ - public void showEmpty(boolean animate) { - if (mEmptyView == null) { - return; - } - - // Cancel any pending task to show the loading animation and show the list of - // apps directly. - mFgHandler.removeCallbacks(mShowLoadingContainerRunnable); - handleLoadingContainer(false /* showContent */, true /* showEmpty */, animate); - } - - /** - * Shows loading view and hides content view & empty view. - */ - public void showLoadingView() { - handleLoadingContainer(false /* showContent */, false /* showEmpty */, false /* animate */); + handleLoadingContainer(true /* show */, animate); } public void showLoadingViewDelayed() { @@ -89,9 +57,8 @@ public class LoadingViewController { mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS); } - private void handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate) { - handleLoadingContainer(mLoadingView, mContentView, mEmptyView, - showContent, showEmpty, animate); + public void handleLoadingContainer(boolean done, boolean animate) { + handleLoadingContainer(mLoadingView, mContentView, done, animate); } /** @@ -108,25 +75,6 @@ public class LoadingViewController { setViewShown(content, done, animate); } - /** - * Show/hide loading view and content view and empty view. - * - * @param loading The loading spinner view - * @param content The content view - * @param empty The empty view shows no item summary to users. - * @param showContent If true, content is set visible and loading is set invisible. - * @param showEmpty If true, empty is set visible and loading is set invisible. - * @param animate Whether or not content/loading views should animate in/out. - */ - public static void handleLoadingContainer(View loading, View content, View empty, - boolean showContent, boolean showEmpty, boolean animate) { - if (empty != null) { - setViewShown(empty, showEmpty, animate); - } - setViewShown(content, showContent, animate); - setViewShown(loading, !showContent && !showEmpty, animate); - } - private static void setViewShown(final View view, boolean shown, boolean animate) { if (animate) { Animation animation = AnimationUtils.loadAnimation(view.getContext(), diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java index 25eca7adb22..86f5fe83c6c 100644 --- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java +++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java @@ -28,6 +28,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -48,6 +49,7 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; import android.widget.SearchView; import androidx.fragment.app.FragmentActivity; @@ -153,6 +155,22 @@ public class ManageApplicationsTest { assertThat(mMenu.findItem(R.id.sort_order_frequent_notification).isVisible()).isFalse(); } + @Test + public void onCreateView_shouldNotShowLoadingContainer() { + ReflectionHelpers.setField(mFragment, "mResetAppsHelper", mock(ResetAppsHelper.class)); + doNothing().when(mFragment).createHeader(); + + final LayoutInflater layoutInflater = mock(LayoutInflater.class); + final View view = mock(View.class); + final View loadingContainer = mock(View.class); + when(layoutInflater.inflate(anyInt(), eq(null))).thenReturn(view); + when(view.findViewById(R.id.loading_container)).thenReturn(loadingContainer); + + mFragment.onCreateView(layoutInflater, mock(ViewGroup.class), null); + + verify(loadingContainer, never()).setVisibility(View.VISIBLE); + } + @Test public void onCreateOptionsMenu_shouldSetSearchQueryListener() { final SearchView searchView = mock(SearchView.class); @@ -203,6 +221,7 @@ public class ManageApplicationsTest { @Test public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() { ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class)); + ReflectionHelpers.setField(mFragment, "mListContainer", mock(View.class)); final ManageApplications.ApplicationsAdapter adapter = spy(new ManageApplications.ApplicationsAdapter(mState, mFragment, AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle())); @@ -224,6 +243,7 @@ public class ManageApplicationsTest { @Test public void updateLoading_appNotLoaded_shouldDelayCallToHandleLoadingContainer() { ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class)); + ReflectionHelpers.setField(mFragment, "mListContainer", mock(View.class)); final ManageApplications.ApplicationsAdapter adapter = spy(new ManageApplications.ApplicationsAdapter(mState, mFragment, AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle())); @@ -252,6 +272,7 @@ public class ManageApplicationsTest { when(listContainer.getVisibility()).thenReturn(View.INVISIBLE); when(listContainer.getContext()).thenReturn(context); ReflectionHelpers.setField(mFragment, "mLoadingContainer", loadingContainer); + ReflectionHelpers.setField(mFragment, "mListContainer", listContainer); final ManageApplications.ApplicationsAdapter adapter = spy(new ManageApplications.ApplicationsAdapter(mState, mFragment, AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle())); @@ -275,7 +296,7 @@ public class ManageApplicationsTest { adapter.onRebuildComplete(null); - verify(loadingViewController).showEmpty(false /* animate */); + verify(loadingViewController).showContent(true /* animate */); } @Test @@ -283,16 +304,15 @@ public class ManageApplicationsTest { final String query = "Test"; final RecyclerView recyclerView = mock(RecyclerView.class); final View emptyView = mock(View.class); - final View loadingContainer = mock(View.class); ReflectionHelpers.setField(mFragment, "mRecyclerView", recyclerView); ReflectionHelpers.setField(mFragment, "mEmptyView", emptyView); - ReflectionHelpers.setField(mFragment, "mLoadingContainer", loadingContainer); final SearchView searchView = mock(SearchView.class); ReflectionHelpers.setField(mFragment, "mSearchView", searchView); when(searchView.isVisibleToUser()).thenReturn(true); when(searchView.getQuery()).thenReturn(query); final View listContainer = mock(View.class); when(listContainer.getVisibility()).thenReturn(View.VISIBLE); + ReflectionHelpers.setField(mFragment, "mListContainer", listContainer); ReflectionHelpers.setField( mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class)); final ArrayList appList = new ArrayList<>(); @@ -471,6 +491,8 @@ public class ManageApplicationsTest { mFragment.mFilterAdapter.updateFilterView(true); assertThat(mFragment.mSpinnerHeader.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mFragment.mRecyclerView.getPaddingTop()).isEqualTo( + mContext.getResources().getDimensionPixelSize(R.dimen.app_bar_height)); } @Test From b6b2485796c53e0633e8b345eeed9cc46173a962 Mon Sep 17 00:00:00 2001 From: prochinwang Date: Wed, 23 Jun 2021 18:08:12 +0800 Subject: [PATCH 10/11] To hide the soft input window when press skip button on Skip setup for PIN and face dialog of Set a PIN screen to avoid flash during transition. bug:191181054 Test: SUW Test: make -j RunSettingsRoboTests Change-Id: I229b190de5e6dc714bbb8408e91c363e90b18f30 --- .../settings/password/SetupChooseLockPassword.java | 7 ++++++- .../android/settings/password/SetupSkipDialog.java | 13 ++++++++++++- .../password/SetupChooseLockPasswordTest.java | 6 ++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/password/SetupChooseLockPassword.java b/src/com/android/settings/password/SetupChooseLockPassword.java index 7cf90c09929..cca50e0e543 100644 --- a/src/com/android/settings/password/SetupChooseLockPassword.java +++ b/src/com/android/settings/password/SetupChooseLockPassword.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; +import android.view.inputmethod.InputMethodManager; import android.widget.Button; import androidx.annotation.Nullable; @@ -112,7 +113,6 @@ public class SetupChooseLockPassword extends ChooseLockPassword { .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false); final boolean forBiometrics = intent .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false); - final SetupSkipDialog dialog = SetupSkipDialog.newInstance( frpSupported, /* isPatternMode= */ false, @@ -120,6 +120,11 @@ public class SetupChooseLockPassword extends ChooseLockPassword { forFingerprint, forFace, forBiometrics); + + InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( + Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + dialog.show(getFragmentManager()); return; } diff --git a/src/com/android/settings/password/SetupSkipDialog.java b/src/com/android/settings/password/SetupSkipDialog.java index dc4516a07ad..a0fe9617f3c 100644 --- a/src/com/android/settings/password/SetupSkipDialog.java +++ b/src/com/android/settings/password/SetupSkipDialog.java @@ -21,6 +21,8 @@ import android.app.Dialog; import android.app.settings.SettingsEnums; import android.content.DialogInterface; import android.os.Bundle; +import android.view.View; +import android.view.inputmethod.InputMethodManager; import androidx.annotation.NonNull; import androidx.annotation.StringRes; @@ -190,12 +192,21 @@ public class SetupSkipDialog extends InstrumentedDialogFragment @Override public void onClick(DialogInterface dialog, int button) { + Activity activity = getActivity(); switch (button) { case DialogInterface.BUTTON_POSITIVE: - Activity activity = getActivity(); activity.setResult(RESULT_SKIP); activity.finish(); break; + case DialogInterface.BUTTON_NEGATIVE: + View view = activity.getCurrentFocus(); + if(view != null) { + view.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity + .getSystemService(Activity.INPUT_METHOD_SERVICE); + imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); + } + break; } } diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java index af4ae0b8a30..29ec9987819 100644 --- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java @@ -24,6 +24,7 @@ import static org.robolectric.RuntimeEnvironment.application; import android.content.Intent; import android.os.Bundle; import android.view.View; +import android.view.inputmethod.InputMethodManager; import android.widget.Button; import androidx.appcompat.app.AlertDialog; @@ -55,6 +56,7 @@ import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowActivity; import org.robolectric.shadows.ShadowDialog; +import org.robolectric.shadows.ShadowInputMethodManager; import java.util.Collections; import java.util.List; @@ -149,6 +151,9 @@ public class SetupChooseLockPasswordTest { @Test public void createActivity_skipButtonInIntroductionStage_shouldBeVisible() { SetupChooseLockPassword activity = createSetupChooseLockPassword(); + final InputMethodManager inputMethodManager = activity + .getSystemService(InputMethodManager.class); + final ShadowInputMethodManager shadowImm = Shadows.shadowOf(inputMethodManager); final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout); final Button skipOrClearButton = @@ -159,6 +164,7 @@ public class SetupChooseLockPasswordTest { skipOrClearButton.performClick(); final AlertDialog chooserDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); assertThat(chooserDialog).isNotNull(); + assertThat(shadowImm.isSoftInputVisible()).isFalse(); } @Test From 273a7d96a377b2f4c2e3601c2bfee4e6aaa65244 Mon Sep 17 00:00:00 2001 From: "Wesley.CW Wang" Date: Thu, 24 Jun 2021 19:24:39 +0800 Subject: [PATCH 11/11] Remove unnecessary converting us to ms - Pick from pagit/1951738 - The class "Estimate" has the menber estimateMillis and the unit of batteryUsageStats.getBatteryTimeRemainingMs() is millisecond, so converting from us to ms is unnecessary. Bug: 187379252 Bug: 184916537 Test: make RunSettingsRoboTests Change-Id: I2e8e03451352d7ad4cd44f72d5261dad35a81eb9 --- src/com/android/settings/fuelgauge/BatteryInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java index f1b19322856..92151c0c58d 100644 --- a/src/com/android/settings/fuelgauge/BatteryInfo.java +++ b/src/com/android/settings/fuelgauge/BatteryInfo.java @@ -204,7 +204,7 @@ public class BatteryInfo { } final long prediction = discharging ? batteryUsageStats.getBatteryTimeRemainingMs() : 0; final Estimate estimate = new Estimate( - PowerUtil.convertUsToMs(prediction), + prediction, false, /* isBasedOnUsage */ EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN); BatteryUtils.logRuntime(LOG_TAG, "time for regular BatteryInfo", startTime);