Commit a2f2f112 authored by Tanmoy Mollik's avatar Tanmoy Mollik Committed by Commit Bot

[Android] Create preference for SyncErrorCard

This cl creates the SyncErrorCardPreference and resources that will be
used by ManageSyncSettings. The onClickListeners for the buttons in the
preference will be added on a separate cl. The button clicks will
be handled by ManageSyncSettings.

Screenshot: https://crbug.com/1107420#c2

Bug: 1107420
Change-Id: I13b22baefee474051cbb779c6eecfe4c40e3cb25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2339323
Commit-Queue: Tanmoy Mollik <triploblastic@chromium.org>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarAlice Wang <aliceywang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800192}
parent 66e308c2
......@@ -736,6 +736,7 @@ chrome_java_resources = [
"java/res/drawable/ic_signal_cellular_4_bar.xml",
"java/res/drawable/ic_site_timer.xml",
"java/res/drawable/ic_swap_vert_round.xml",
"java/res/drawable/ic_sync_badge_error_20dp.xml",
"java/res/drawable/ic_sync_badge_off_20dp.xml",
"java/res/drawable/ic_sync_error_48dp.xml",
"java/res/drawable/ic_sync_error_legacy_40dp.xml",
......
......@@ -1495,6 +1495,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java",
"java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncErrorCardPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncPromoPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java",
......
<?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"
android:width="20dp"
android:height="20dp"
tools:targetApi="21"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:strokeWidth="1"
android:pathData="M11,21.5C16.799,21.5 21.5,16.799 21.5,11C21.5,5.201 16.799,0.5 11,0.5C5.201,0.5 0.5,5.201 0.5,11C0.5,16.799 5.201,21.5 11,21.5Z"
android:fillColor="@color/default_text_color_error"
android:strokeColor="@color/default_bg_color"/>
<path
android:pathData="M9.7501,7.4688V6.1625C9.2501,6.2937 8.7814,6.5 8.3563,6.7625L9.2689,7.675C9.4251,7.6 9.5814,7.525 9.7501,7.4688ZM5.2876,6.8812L6.7626,8.3562C6.2814,9.1187 6.0001,10.025 6.0001,11C6.0001,12.3812 6.5689,13.625 7.4751,14.525L6.0001,16H9.7501V12.25L8.3501,13.65C7.6751,12.9688 7.2501,12.0375 7.2501,11C7.2501,10.375 7.4064,9.7875 7.6751,9.2688L12.7251,14.3187C12.5688,14.4 12.4126,14.475 12.2438,14.5312V15.8375C12.7438,15.7063 13.2126,15.5 13.6376,15.2375L15.1126,16.7125L15.9063,15.9188L6.0876,6.0875L5.2876,6.8812ZM16.0001,6H12.2501V9.75L13.6501,8.35C14.3251,9.0313 14.7501,9.9625 14.7501,11C14.7501,11.625 14.5938,12.2125 14.3251,12.7313L15.2376,13.6437C15.7188,12.8812 16.0001,11.975 16.0001,11C16.0001,9.6187 15.4313,8.375 14.5251,7.475L16.0001,6Z"
android:fillColor="@color/default_bg_color"/>
</vector>
// 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.
package org.chromium.chrome.browser.sync.settings;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.IdentityServicesProvider;
import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
import org.chromium.chrome.browser.signin.ProfileDataCache;
import org.chromium.chrome.browser.sync.AndroidSyncSettings;
import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.chrome.browser.sync.settings.SyncSettingsUtils.SyncError;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.identitymanager.ConsentLevel;
import java.util.Collections;
public class SyncErrorCardPreference extends Preference
implements AndroidSyncSettings.AndroidSyncSettingsObserver,
ProfileSyncService.SyncStateChangedListener, ProfileDataCache.Observer {
/**
* Listener for the buttons in the error card.
*/
public interface SyncErrorCardPreferenceListener {
/**
* Called when the user clicks the primary button.
*/
void onSyncErrorCardPrimaryButtonClicked();
/**
* Called when the user clicks the secondary button. This button is only shown for
* {@link SyncError.SYNC_SETUP_INCOMPLETE} error.
*/
void onSyncErrorCardSecondaryButtonClicked();
}
private final ProfileDataCache mProfileDataCache;
private SyncErrorCardPreferenceListener mButtonListener;
private @SyncError int mSyncError;
public SyncErrorCardPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mProfileDataCache = ProfileDataCache.createProfileDataCache(
context, R.drawable.ic_sync_badge_error_20dp);
setLayoutResource(R.layout.personalized_signin_promo_view_settings);
mSyncError = SyncError.NO_ERROR;
}
@Override
public void onAttached() {
super.onAttached();
mProfileDataCache.addObserver(this);
AndroidSyncSettings.get().registerObserver(this);
ProfileSyncService syncService = ProfileSyncService.get();
if (syncService != null) {
syncService.addSyncStateChangedListener(this);
}
update();
}
@Override
public void onDetached() {
super.onDetached();
mProfileDataCache.removeObserver(this);
AndroidSyncSettings.get().unregisterObserver(this);
ProfileSyncService syncService = ProfileSyncService.get();
if (syncService != null) {
syncService.removeSyncStateChangedListener(this);
}
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
if (mSyncError == SyncError.NO_ERROR) {
return;
}
PersonalizedSigninPromoView errorCardView =
(PersonalizedSigninPromoView) holder.findViewById(R.id.signin_promo_view_container);
setupSyncErrorCardView(errorCardView);
}
private void update() {
// If feature is not enabled keep the preference at the default hidden state.
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) {
return;
}
mSyncError = SyncSettingsUtils.getSyncError();
if (mSyncError == SyncError.NO_ERROR) {
setVisible(false);
} else {
setVisible(true);
notifyChanged();
}
}
private void setupSyncErrorCardView(PersonalizedSigninPromoView errorCardView) {
String signedInAccount = CoreAccountInfo.getEmailFrom(
IdentityServicesProvider.get()
.getIdentityManager(Profile.getLastUsedRegularProfile())
.getPrimaryAccountInfo(ConsentLevel.SYNC));
assert signedInAccount != null : "There should be a signed in account";
mProfileDataCache.update(Collections.singletonList(signedInAccount));
Drawable accountImage =
mProfileDataCache.getProfileDataOrDefault(signedInAccount).getImage();
errorCardView.getImage().setImageDrawable(accountImage);
errorCardView.getDismissButton().setVisibility(View.GONE);
errorCardView.getStatusMessage().setVisibility(View.VISIBLE);
errorCardView.getStatusMessage().setText(R.string.sync_error_card_title);
errorCardView.getDescription().setText(
SyncSettingsUtils.getSyncErrorHint(getContext(), mSyncError));
errorCardView.getPrimaryButton().setText(
SyncSettingsUtils.getSyncErrorCardButtonLabel(getContext(), mSyncError));
errorCardView.getPrimaryButton().setOnClickListener(
v -> mButtonListener.onSyncErrorCardPrimaryButtonClicked());
if (mSyncError == SyncError.SYNC_SETUP_INCOMPLETE) {
errorCardView.getSecondaryButton().setOnClickListener(
v -> mButtonListener.onSyncErrorCardSecondaryButtonClicked());
errorCardView.getSecondaryButton().setText(
R.string.sync_setup_incomplete_error_card_cancel_button);
} else {
errorCardView.getSecondaryButton().setVisibility(View.GONE);
}
}
public void setSyncErrorCardPreferenceListener(SyncErrorCardPreferenceListener listener) {
mButtonListener = listener;
}
public @SyncError int getSyncError() {
return mSyncError;
}
/**
* {@link ProfileSyncServiceListener} implementation.
*/
@Override
public void syncStateChanged() {
update();
}
/**
* {@link AndroidSyncSettings.AndroidSyncSettingsObserver} implementation.
*/
@Override
public void androidSyncSettingsChanged() {
update();
}
/**
* {@link ProfileDataCache.Observer} implementation.
*/
@Override
public void onProfileDataUpdated(String accountId) {
update();
}
}
......@@ -141,7 +141,10 @@ public class SyncSettingsUtils {
return context.getString(R.string.hint_passphrase_required);
case SyncError.TRUSTED_VAULT_KEY_REQUIRED_FOR_EVERYTHING:
case SyncError.TRUSTED_VAULT_KEY_REQUIRED_FOR_PASSWORDS:
return context.getString(R.string.hint_sync_retrieve_keys);
return context.getString(
ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)
? R.string.hint_sync_retrieve_keys
: R.string.hint_sync_retrieve_keys_legacy);
case SyncError.SYNC_SETUP_INCOMPLETE:
return context.getString(R.string.hint_sync_settings_not_confirmed_description);
case SyncError.NO_ERROR:
......@@ -156,6 +159,8 @@ public class SyncSettingsUtils {
case SyncError.ANDROID_SYNC_DISABLED:
return context.getString(R.string.android_sync_disabled_error_card_button);
case SyncError.AUTH_ERROR:
case SyncError.OTHER_ERRORS:
// Both these errors should be resolved by signing the user again.
return context.getString(R.string.auth_error_card_button);
case SyncError.CLIENT_OUT_OF_DATE:
return context.getString(R.string.client_out_of_date_error_card_button,
......@@ -167,7 +172,6 @@ public class SyncSettingsUtils {
return context.getString(R.string.trusted_vault_error_card_button);
case SyncError.SYNC_SETUP_INCOMPLETE:
return context.getString(R.string.sync_setup_incomplete_error_card_confirm_button);
case SyncError.OTHER_ERRORS:
case SyncError.NO_ERROR:
default:
return null;
......
......@@ -1679,9 +1679,12 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_HINT_SYNC_AUTH_ERROR" desc="Hint message to resolve sync auth error.">
Sign in again to start sync
</message>
<message name="IDS_HINT_SYNC_RETRIEVE_KEYS" desc="Hint message to resolve sync encryption error.">
<message name="IDS_HINT_SYNC_RETRIEVE_KEYS_LEGACY" desc="Hint message to resolve sync encryption error.">
Fix now
</message>
<message name="IDS_HINT_SYNC_RETRIEVE_KEYS" desc="Hint message to resolve sync encryption error.">
Error syncing passwords
</message>
<message name="IDS_HINT_PASSPHRASE_REQUIRED" desc="Hint message to resolve passphrase required error.">
Enter your passphrase to start sync
</message>
......@@ -1711,6 +1714,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_SYNC_SETUP_INCOMPLETE_ERROR_CARD_CONFIRM_BUTTON" desc="Positive button text for advanced sync interrupted error in sync error cards.">
Confirm sync
</message>
<message name="IDS_SYNC_SETUP_INCOMPLETE_ERROR_CARD_CANCEL_BUTTON" desc="Negative button text for advanced sync interrupted error in sync error cards. This button turns off Sync.">
Cancel sync setup
</message>
<message name="IDS_TRUSTED_VAULT_ERROR_CARD_BUTTON" desc="Button text for trusted vault error in sync error cards.">
Unlock with Screen Lock
</message>
......
4f2e743dff46b212f4c688b74a6956206c58d426
\ No newline at end of file
db6a020704f635af736f9724f5de4f072c33e8f2
\ No newline at end of file
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