Commit 3f4942f2 authored by Eleonora Rocchi's avatar Eleonora Rocchi Committed by Commit Bot

[PwdCheckAndroid] Add illustration to the status header in Check

passwords.

This CL adds the illustration to the header of Check Passwords. It also
adds the tests to verify the correct illustration is shown.

Screenshots in the linked bug.

Bug: 1109691, 1092444
Change-Id: Ib55745974464d195a32da1394c95c755aa67ec31
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2340920
Commit-Queue: Eleonora Rocchi <erocchi@google.com>
Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795914}
parent 78ff0e21
...@@ -100,8 +100,10 @@ android_resources("java_resources") { ...@@ -100,8 +100,10 @@ android_resources("java_resources") {
] ]
sources = [ sources = [
"java/res/drawable-night/password_check_positive.xml",
"java/res/drawable/ic_autofill_assistant_white_24dp.xml", "java/res/drawable/ic_autofill_assistant_white_24dp.xml",
"java/res/drawable/ic_check_circle_filled_green_24dp.xml", "java/res/drawable/ic_check_circle_filled_green_24dp.xml",
"java/res/drawable/password_check_positive.xml",
"java/res/layout/password_check_compromised_credential_item.xml", "java/res/layout/password_check_compromised_credential_item.xml",
"java/res/layout/password_check_compromised_credential_with_script_item.xml", "java/res/layout/password_check_compromised_credential_with_script_item.xml",
"java/res/layout/password_check_header_item.xml", "java/res/layout/password_check_header_item.xml",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="21"
tools:ignore="VectorRaster"
android:width="360dp"
android:height="120dp"
android:viewportWidth="360"
android:viewportHeight="120">
<path android:pathData="M0 0h360v120H0z"
android:fillColor="#28282B"
android:fillType="evenOdd"/>
<path android:pathData="M288.585 52.215V47c10.735 0 19.175-3 25.09-8.955 9.29-9.36 9.325-23.015 9.325-23.15l5.25-0.04c0 0.645 0 15.9-10.815 26.82-6.935 6.995-16.645 10.54-28.85 10.54z"
android:fillColor="#414447"/>
<path android:pathData="M253.87 83h-5.245a40.45 40.45 0 0 1 5-18c4.605-8.21 14.4-18 34.96-18v5.215c-14.465 0-24.685 5.17-30.385 15.36A35.345 35.345 0 0 0 253.87 83z"
android:fillColor="#81C995"/>
<path android:pathData="M56 57.915H38.175v-0.27a8.91 8.91 0 0 1 17.82 0L56 57.915zm-17.275-0.54H55.45a8.37 8.37 0 0 0-16.73 0h0.005zM335 88.66h20v4h-20z"
android:fillColor="#414447"/>
<path android:pathData="M338.268 98.32l10-17.32 3.464 2-10 17.32z"
android:fillColor="#414447"/>
<path android:pathData="M348.268 100.32l-10-17.32 3.464-2 10 17.32z"
android:fillColor="#414447"/>
<path android:pathData="M254.61 94.5h-90.72V32.325a2.65 2.65 0 0 1 2.64-2.64h85.44a2.65 2.65 0 0 1 2.64 2.64V94.5z"
android:strokeWidth=".5"
android:fillColor="#262628"
android:strokeColor="#4E5154"/>
<path android:pathData="M250.29 30.225A3.785 3.785 0 0 1 254.07 34v59.945h-89.64V34a3.785 3.785 0 0 1 3.78-3.78h82.08m0-0.54h-82.08a4.335 4.335 0 0 0-4.32 4.32v60.5h90.72V34a4.335 4.335 0 0 0-4.32-4.32zm-99.36 68.585h116.64v0.54H150.93v-0.54z"
android:fillColor="#414447"/>
<path android:pathData="M118 18h56a6 6 0 0 1 6 6v80a6 6 0 0 1-6 6h-56a6 6 0 0 1-6-6V24a6 6 0 0 1 6-6z"
android:strokeWidth=".5"
android:fillColor="#262628"
android:strokeColor="#4E5154"/>
<path android:pathData="M224.75 56c1.242 0.002 2.249 1.075 2.25 2.4v19.2c-0.001 1.325-1.008 2.398-2.25 2.4h-76.5c-1.242-0.002-2.249-1.075-2.25-2.4V58.4c0.001-1.325 1.008-2.398 2.25-2.4h76.5z"
android:strokeWidth=".5"
android:fillColor="#262628"
android:strokeColor="#4E5154"/>
<path android:pathData="M216 62a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1 1 1 0 0 1-1-1V63a1 1 0 0 1 1-1zm-45 5h10v2h-10z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M172.634 71.83l5-8.66 1.732 1-5 8.66z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M177.634 72.83l-5-8.66 1.732-1 5 8.66zM185 67h10v2h-10z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M186.634 71.83l5-8.66 1.732 1-5 8.66z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M191.634 72.83l-5-8.66 1.732-1 5 8.66zM199 67h10v2h-10z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M200.634 71.83l5-8.66 1.732 1-5 8.66z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M205.634 72.83l-5-8.66 1.732-1 5 8.66z"
android:fillColor="#8AB4F8"/>
<path android:pathData="M126 68a20 20 0 1 1 40 0 20 20 0 1 1-40 0"
android:fillColor="#81C995"/>
<path android:pathData="M143.214 74.75l-6.964-6.478 1.964-1.827 5 4.638 10.572-9.833 1.964 1.84z"
android:fillColor="#28282B"
android:fillType="evenOdd"/>
<path android:pathData="M146 10a7 7 0 0 1 7 7v7h-14v-7a7 7 0 0 1 7-7z"
android:strokeWidth=".5"
android:fillColor="#262628"
android:strokeColor="#4E5154"/>
<path android:pathData="M143 17a3 3 0 1 1 6 0 3 3 0 1 1-6 0m19 7h-32a6 6 0 0 0-6 6v4h44v-4a6 6 0 0 0-6-6z"
android:strokeWidth=".5"
android:fillColor="#262628"
android:strokeColor="#4E5154"/>
<path android:pathData="M79.6 58.42a12.935 12.935 0 0 0-10.1 4.82A8.62 8.62 0 0 0 58 71.38h34.56c0-7.158-5.802-12.96-12.96-12.96z"
android:fillColor="#28282B"/>
<path android:pathData="M92.83 71.65h-35.1v-0.27a8.89 8.89 0 0 1 11.695-8.455A13.23 13.23 0 0 1 92.83 71.38v0.27zm-34.555-0.54h34a12.69 12.69 0 0 0-22.56-7.7l-0.12 0.15-0.18-0.065A8.35 8.35 0 0 0 58.26 71.11h0.015z"
android:fillColor="#4E5154"/>
<path android:pathData="M38.12 82.36l3.705-3.705c7.59 7.59 15.69 11.43 24.075 11.41 13.17-0.03 22.855-9.655 22.95-9.75l3.735 3.675c-0.45 0.46-11.235 11.25-26.61 11.315C56.12 95.345 46.75 91 38.12 82.36z"
android:fillColor="#F7BB2A"/>
<path android:pathData="M-8.2 79.58l-3.705-3.705a40.45 40.45 0 0 1 16.25-9.18c9.075-2.57 22.945-2.58 37.5 11.96L38.14 82.36C27.89 72.13 17 68.555 5.77 71.735A35.345 35.345 0 0 0-8.2 79.58z"
android:fillColor="#414447"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:targetApi="21"
tools:ignore="VectorRaster"
android:width="360dp"
android:height="120dp"
android:viewportWidth="360"
android:viewportHeight="120">
<path android:pathData="M0 0h360v120H0z"
android:fillColor="#F8F9FA"
android:fillType="evenOdd"/>
<path android:pathData="M288.585 52.215V47c10.735 0 19.175-3 25.09-8.955 9.29-9.36 9.325-23.015 9.325-23.15l5.25-0.04c0 0.645 0 15.9-10.815 26.82-6.935 6.995-16.645 10.54-28.85 10.54z"
android:fillColor="#E8E9EB"/>
<path android:pathData="M253.87 83h-5.245a40.45 40.45 0 0 1 5-18c4.605-8.21 14.4-18 34.96-18v5.215c-14.465 0-24.685 5.17-30.385 15.36A35.345 35.345 0 0 0 253.87 83z"
android:fillColor="#34A751"/>
<path android:pathData="M56 57.915H38.175v-0.27a8.91 8.91 0 0 1 17.82 0L56 57.915zm-17.275-0.54H55.45a8.37 8.37 0 0 0-16.73 0h0.005z"
android:fillColor="#BDC0C5"/>
<path android:pathData="M335 88.66h20v4h-20z"
android:fillColor="#E8E9EB"/>
<path android:pathData="M338.268 98.32l10-17.32 3.464 2-10 17.32z"
android:fillColor="#E8E9EB"/>
<path android:pathData="M348.268 100.32l-10-17.32 3.464-2 10 17.32z"
android:fillColor="#E8E9EB"/>
<path android:pathData="M254.61 94.5h-90.72V32.325a2.65 2.65 0 0 1 2.64-2.64h85.44a2.65 2.65 0 0 1 2.64 2.64V94.5z"
android:fillColor="#F8F9FA"/>
<path android:pathData="M250.29 30.225A3.785 3.785 0 0 1 254.07 34v59.945h-89.64V34a3.785 3.785 0 0 1 3.78-3.78h82.08m0-0.54h-82.08a4.335 4.335 0 0 0-4.32 4.32v60.5h90.72V34a4.335 4.335 0 0 0-4.32-4.32zm-99.36 68.585h116.64v0.54H150.93v-0.54z"
android:fillColor="#BDC0C5"/>
<path android:pathData="M118 18h56a6 6 0 0 1 6 6v80a6 6 0 0 1-6 6h-56a6 6 0 0 1-6-6V24a6 6 0 0 1 6-6z"
android:strokeWidth=".5"
android:fillColor="#F8F9FA"
android:strokeColor="#BDC0C5"/>
<path android:pathData="M224.75 55.75h-76.5c-0.692 0-1.319 0.299-1.773 0.783a2.728 2.728 0 0 0-0.727 1.867v19.2c0 0.73 0.28 1.39 0.727 1.867 0.454 0.484 1.081 0.782 1.773 0.783h76.5c0.692 0 1.319-0.299 1.773-0.783a2.728 2.728 0 0 0 0.727-1.867V58.4c0-0.73-0.28-1.39-0.727-1.867a2.426 2.426 0 0 0-1.773-0.783z"
android:strokeWidth=".5"
android:fillColor="#F8F9FA"
android:strokeColor="#BDC0C5"/>
<path android:pathData="M216 62a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1 1 1 0 0 1-1-1V63a1 1 0 0 1 1-1zm-45 5h10v2h-10z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M172.634 71.83l5-8.66 1.732 1-5 8.66z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M177.634 72.83l-5-8.66 1.732-1 5 8.66zM185 67h10v2h-10z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M186.634 71.83l5-8.66 1.732 1-5 8.66z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M191.634 72.83l-5-8.66 1.732-1 5 8.66zM199 67h10v2h-10z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M200.634 71.83l5-8.66 1.732 1-5 8.66z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M205.634 72.83l-5-8.66 1.732-1 5 8.66z"
android:fillColor="#3A7BEE"/>
<path android:pathData="M126 68a20 20 0 1 1 40 0 20 20 0 1 1-40 0"
android:fillColor="#34A751"
android:fillType="evenOdd"/>
<path android:pathData="M143.214 74.75l-6.964-6.478 1.964-1.827 5 4.638 10.572-9.833 1.964 1.84z"
android:fillColor="#FFF"
android:fillType="evenOdd"/>
<path android:pathData="M146 10a7 7 0 0 1 7 7v7h-14v-7a7 7 0 0 1 7-7z"
android:strokeWidth=".5"
android:fillColor="#F8F9FA"
android:strokeColor="#BDC0C5"/>
<path android:pathData="M143 17a3 3 0 1 1 6 0 3 3 0 1 1-6 0m19 7h-32a6 6 0 0 0-6 6v4h44v-4a6 6 0 0 0-6-6z"
android:strokeWidth=".5"
android:fillColor="#F8F9FA"
android:strokeColor="#BDC0C5"/>
<path android:pathData="M79.6 58.42a12.935 12.935 0 0 0-10.1 4.82A8.62 8.62 0 0 0 58 71.38h34.56c0-7.158-5.802-12.96-12.96-12.96z"
android:fillColor="#FFF"/>
<path android:pathData="M92.83 71.65h-35.1v-0.27a8.89 8.89 0 0 1 11.695-8.455A13.23 13.23 0 0 1 92.83 71.38v0.27zm-34.555-0.54h34a12.69 12.69 0 0 0-22.56-7.7l-0.12 0.15-0.18-0.065A8.35 8.35 0 0 0 58.26 71.11h0.015z"
android:fillColor="#BDC0C5"/>
<path android:pathData="M38.12 82.36l3.705-3.705c7.59 7.59 15.69 11.43 24.075 11.41 13.17-0.03 22.855-9.655 22.95-9.75l3.735 3.675c-0.45 0.46-11.235 11.25-26.61 11.315C56.12 95.345 46.75 91 38.12 82.36z"
android:fillColor="#F7BB2A"/>
<path android:pathData="M-8.2 79.58l-3.705-3.705a40.45 40.45 0 0 1 16.25-9.18c9.075-2.57 22.945-2.58 37.5 11.96L38.14 82.36C27.89 72.13 17 68.555 5.77 71.735A35.345 35.345 0 0 0-8.2 79.58z"
android:fillColor="#E8E9EB"/>
</vector>
...@@ -8,6 +8,21 @@ ...@@ -8,6 +8,21 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/password_check_neutral_background"
android:orientation="horizontal">
<ImageView android:id="@+id/check_status_illustration"
android:importantForAccessibility="no"
android:layout_width="@dimen/check_status_illustration_width"
android:layout_height="@dimen/check_status_illustration_height"
android:layout_gravity="start"
android:visibility="visible"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
<dimen name="check_status_description_margin_top">2dp</dimen> <dimen name="check_status_description_margin_top">2dp</dimen>
<dimen name="check_status_icon_margin_horizontal">16dp</dimen> <dimen name="check_status_icon_margin_horizontal">16dp</dimen>
<dimen name="check_status_icon_size">24dp</dimen> <dimen name="check_status_icon_size">24dp</dimen>
<dimen name="check_status_illustration_height">120dp</dimen>
<dimen name="check_status_illustration_width">360dp</dimen>
<dimen name="check_status_restart_button_clickable_surface_size">48dp</dimen> <dimen name="check_status_restart_button_clickable_surface_size">48dp</dimen>
<dimen name="check_status_restart_button_margin_end">4dp</dimen> <dimen name="check_status_restart_button_margin_end">4dp</dimen>
......
...@@ -171,15 +171,15 @@ class PasswordCheckViewBinder { ...@@ -171,15 +171,15 @@ class PasswordCheckViewBinder {
if (key == CHECK_PROGRESS) { if (key == CHECK_PROGRESS) {
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress);
} else if (key == CHECK_STATUS) { } else if (key == CHECK_STATUS) {
// TODO(crbug.com/1109691): Set illustration based on status.
updateActionButton(view, status); updateActionButton(view, status);
updateStatusIcon(view, status, compromisedCredentialsCount); updateStatusIcon(view, status, compromisedCredentialsCount);
updateStatusIllustration(view, status, compromisedCredentialsCount);
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress);
} else if (key == CHECK_TIMESTAMP) { } else if (key == CHECK_TIMESTAMP) {
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress);
} else if (key == COMPROMISED_CREDENTIALS_COUNT) { } else if (key == COMPROMISED_CREDENTIALS_COUNT) {
// TODO(crbug.com/1109691): Set illustration based on compromised credentials count.
updateStatusIcon(view, status, compromisedCredentialsCount); updateStatusIcon(view, status, compromisedCredentialsCount);
updateStatusIllustration(view, status, compromisedCredentialsCount);
updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress); updateStatusText(view, status, compromisedCredentialsCount, checkTimestamp, progress);
} else { } else {
assert false : "Unhandled update to property:" + key; assert false : "Unhandled update to property:" + key;
...@@ -360,6 +360,36 @@ class PasswordCheckViewBinder { ...@@ -360,6 +360,36 @@ class PasswordCheckViewBinder {
return status == PasswordCheckUIStatus.IDLE ? View.VISIBLE : View.GONE; return status == PasswordCheckUIStatus.IDLE ? View.VISIBLE : View.GONE;
} }
private static void updateStatusIllustration(
View view, @PasswordCheckUIStatus int status, Integer compromisedCredentialsCount) {
// TODO(crbug.com/1114051): Set default values for header properties.
if (status == PasswordCheckUIStatus.IDLE && compromisedCredentialsCount == null) return;
ImageView statusIllustration = view.findViewById(R.id.check_status_illustration);
statusIllustration.setImageResource(
getIllustrationResource(status, compromisedCredentialsCount));
}
private static int getIllustrationResource(
@PasswordCheckUIStatus int status, Integer compromisedCredentialsCount) {
switch (status) {
case PasswordCheckUIStatus.IDLE:
assert compromisedCredentialsCount != null;
return compromisedCredentialsCount == 0 ? R.drawable.password_check_positive
: R.drawable.password_checkup_warning;
case PasswordCheckUIStatus.RUNNING:
case PasswordCheckUIStatus.ERROR_OFFLINE:
case PasswordCheckUIStatus.ERROR_NO_PASSWORDS:
case PasswordCheckUIStatus.ERROR_SIGNED_OUT:
case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT:
case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT_ACCOUNT_CHECK:
case PasswordCheckUIStatus.ERROR_UNKNOWN:
return R.drawable.password_check_neutral;
default:
assert false : "Unhandled check status " + status + "on illustration update";
}
return 0;
}
private static ListMenu createCredentialMenu(Context context, CompromisedCredential credential, private static ListMenu createCredentialMenu(Context context, CompromisedCredential credential,
PasswordCheckCoordinator.CredentialEventHandler credentialHandler) { PasswordCheckCoordinator.CredentialEventHandler credentialHandler) {
MVCListAdapter.ModelList menuItems = new MVCListAdapter.ModelList(); MVCListAdapter.ModelList menuItems = new MVCListAdapter.ModelList();
......
...@@ -147,6 +147,34 @@ public class PasswordCheckViewTest { ...@@ -147,6 +147,34 @@ public class PasswordCheckViewTest {
is(getString(org.chromium.chrome.R.string.more))); is(getString(org.chromium.chrome.R.string.more)));
} }
@Test
@MediumTest
public void testStatusIllustrationPositive() {
Long checkTimestamp = System.currentTimeMillis();
runOnUiThreadBlocking(
() -> { mModel.get(ITEMS).add(buildHeader(IDLE, 0, checkTimestamp)); });
waitForListViewToHaveLength(1);
assertIllustration(R.drawable.password_check_positive);
}
@Test
@MediumTest
public void testStatusIllustrationWarning() {
Long checkTimestamp = System.currentTimeMillis();
runOnUiThreadBlocking(
() -> { mModel.get(ITEMS).add(buildHeader(IDLE, LEAKS_COUNT, checkTimestamp)); });
waitForListViewToHaveLength(1);
assertIllustration(R.drawable.password_checkup_warning);
}
@Test
@MediumTest
public void testStatusIllustrationNeutral() {
runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildHeader(ERROR_OFFLINE)); });
waitForListViewToHaveLength(1);
assertIllustration(R.drawable.password_check_neutral);
}
@Test @Test
@MediumTest @MediumTest
public void testStatusDisplaysIconOnIdleNoLeaks() { public void testStatusDisplaysIconOnIdleNoLeaks() {
...@@ -478,6 +506,18 @@ public class PasswordCheckViewTest { ...@@ -478,6 +506,18 @@ public class PasswordCheckViewTest {
.sameAs(getBitmap(icon, widthPx, heightPx))); .sameAs(getBitmap(icon, widthPx, heightPx)));
} }
private void assertIllustration(int resourceId) {
Drawable illustration =
((ImageView) getStatus().findViewById(R.id.check_status_illustration))
.getDrawable();
int widthPx = illustration.getIntrinsicWidth();
int heightPx = illustration.getIntrinsicHeight();
assertTrue(getBitmap(
AppCompatResources.getDrawable(mPasswordCheckView.getContext(), resourceId),
widthPx, heightPx)
.sameAs(getBitmap(illustration, widthPx, heightPx)));
}
private View getStatus() { private View getStatus() {
return mPasswordCheckView.getListView().getChildAt(0); return mPasswordCheckView.getListView().getChildAt(0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment