Commit 20ac8ea8 authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

[PwdCheckAndroid] Move change password code into helper

This change should not affect any behavior.

This CL moves the change password code out of the coordinator. This
keeps the coordinator clean from any logic and helper code so that it
remains focused on assembling the component and forwarding events.

Bug: 1092444
Change-Id: I2e380cf06403cfe91c39e02e9a65cc3352a44aec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2352920
Commit-Queue: Friedrich [CET] <fhorschig@chromium.org>
Reviewed-by: default avatarIoana Pandele <ioanap@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798611}
parent d238c894
...@@ -88,6 +88,7 @@ android_library("internal_java") { ...@@ -88,6 +88,7 @@ android_library("internal_java") {
"java/src/org/chromium/chrome/browser/password_check/PasswordCheckProperties.java", "java/src/org/chromium/chrome/browser/password_check/PasswordCheckProperties.java",
"java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java", "java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java",
"java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewHolder.java", "java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewHolder.java",
"java/src/org/chromium/chrome/browser/password_check/helper/PasswordCheckChangePasswordHelper.java",
"java/src/org/chromium/chrome/browser/password_check/helper/PasswordCheckReauthenticationHelper.java", "java/src/org/chromium/chrome/browser/password_check/helper/PasswordCheckReauthenticationHelper.java",
] ]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
......
...@@ -4,44 +4,23 @@ ...@@ -4,44 +4,23 @@
package org.chromium.chrome.browser.password_check; package org.chromium.chrome.browser.password_check;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Browser;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleObserver;
import org.chromium.base.IntentUtils;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.LaunchIntentDispatcher;
import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckChangePasswordHelper;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper; import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import java.util.Objects;
/** /**
* Creates the PasswordCheckComponentUi. This class is responsible for managing the UI for the check * Creates the PasswordCheckComponentUi. This class is responsible for managing the UI for the check
* of the leaked password. * of the leaked password.
*/ */
class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObserver, class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObserver {
PasswordCheckComponentUi.ChangePasswordDelegate {
private static final String AUTOFILL_ASSISTANT_PACKAGE =
"org.chromium.chrome.browser.autofill_assistant.";
private static final String AUTOFILL_ASSISTANT_ENABLED_KEY =
AUTOFILL_ASSISTANT_PACKAGE + "ENABLED";
private static final String PASSWORD_CHANGE_USERNAME_PARAMETER = "PASSWORD_CHANGE_USERNAME";
private static final String INTENT_PARAMETER = "INTENT";
private static final String INTENT = "PASSWORD_CHANGE";
private final PasswordCheckFragmentView mFragmentView; private final PasswordCheckFragmentView mFragmentView;
private final PasswordCheckReauthenticationHelper mReauthenticationHelper; private final PasswordCheckReauthenticationHelper mReauthenticationHelper;
private final PasswordCheckMediator mMediator; private final PasswordCheckMediator mMediator;
...@@ -89,7 +68,9 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObs ...@@ -89,7 +68,9 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObs
mReauthenticationHelper = new PasswordCheckReauthenticationHelper( mReauthenticationHelper = new PasswordCheckReauthenticationHelper(
mFragmentView.getActivity(), mFragmentView.getParentFragmentManager()); mFragmentView.getActivity(), mFragmentView.getParentFragmentManager());
mMediator = new PasswordCheckMediator(this, mReauthenticationHelper); mMediator = new PasswordCheckMediator(
new PasswordCheckChangePasswordHelper(mFragmentView.getActivity()),
mReauthenticationHelper);
} }
@Override @Override
...@@ -146,82 +127,4 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObs ...@@ -146,82 +127,4 @@ class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObs
PropertyModelChangeProcessor.create( PropertyModelChangeProcessor.create(
model, view, PasswordCheckViewBinder::bindPasswordCheckView); model, view, PasswordCheckViewBinder::bindPasswordCheckView);
} }
/**
* Launches a CCT that points to the change password form or home page of |origin|.
* @param credential A {@link CompromisedCredential} to be changed in an App or in a CCT.
*/
@Override
public void launchAppOrCctWithChangePasswordUrl(CompromisedCredential credential) {
// TODO(crbug.com/1092444): Always launch the URL if possible and let Android handle the
// match to open it.
IntentUtils.safeStartActivity(mFragmentView.getActivity(),
credential.getAssociatedApp().isEmpty()
? buildIntent(credential.getPasswordChangeUrl())
: getPackageLaunchIntent(credential.getAssociatedApp()));
}
@Override
public boolean canManuallyChangeCredential(CompromisedCredential credential) {
return !credential.getPasswordChangeUrl().isEmpty()
|| getPackageLaunchIntent(credential.getAssociatedApp()) != null;
}
/**
* Launches a CCT that starts a password change script for a {@link CompromisedCredential}.
* @param credential A {@link CompromisedCredential} to be changed with a script.
*/
@Override
public void launchCctWithScript(CompromisedCredential credential) {
Intent intent = buildIntent(credential.getOrigin().getSpec());
populateAutofillAssistantExtras(intent, credential.getUsername());
IntentUtils.safeStartActivity(mFragmentView.getActivity(), intent);
}
@Override
public void launchEditPage(CompromisedCredential credential) {
SettingsLauncher launcher = new SettingsLauncherImpl();
Bundle fragmentArgs = new Bundle();
fragmentArgs.putParcelable(
PasswordCheckEditFragmentView.EXTRA_COMPROMISED_CREDENTIAL, credential);
launcher.launchSettingsActivity(
mFragmentView.getContext(), PasswordCheckEditFragmentView.class, fragmentArgs);
}
private Intent getPackageLaunchIntent(String packageName) {
return Objects.requireNonNull(mFragmentView.getActivity())
.getPackageManager()
.getLaunchIntentForPackage(packageName);
}
/**
* Builds an intent to launch a CCT.
* @param initialUrl Initial URL to launch a CCT.
* @return {@link Intent} for CCT.
*/
private Intent buildIntent(String initialUrl) {
final Activity activity = mFragmentView.getActivity();
CustomTabsIntent customTabIntent =
new CustomTabsIntent.Builder().setShowTitle(true).build();
customTabIntent.intent.setData(Uri.parse(initialUrl));
Intent intent = LaunchIntentDispatcher.createCustomTabActivityIntent(
activity, customTabIntent.intent);
intent.setPackage(activity.getPackageName());
intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName());
IntentHandler.addTrustedIntentExtras(intent);
return intent;
}
/**
* Populates intent extras for an Autofill Assistant script.
* @param intent An {@link Intent} to be populated.
* @param username A username for a password change script. One of extras to put.
*/
private void populateAutofillAssistantExtras(Intent intent, String username) {
intent.putExtra(AUTOFILL_ASSISTANT_ENABLED_KEY, /* value= */ true);
intent.putExtra(AUTOFILL_ASSISTANT_PACKAGE + PASSWORD_CHANGE_USERNAME_PARAMETER, username);
intent.putExtra(AUTOFILL_ASSISTANT_PACKAGE + INTENT_PARAMETER, INTENT);
// TODO(crbug.com/1086114): Also add the following parameters when server side changes is
// ready: CALLER, SOURCE. That would be useful for metrics.
}
} }
...@@ -22,7 +22,7 @@ import android.util.Pair; ...@@ -22,7 +22,7 @@ import android.util.Pair;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import org.chromium.chrome.browser.password_check.PasswordCheckComponentUi.ChangePasswordDelegate; import org.chromium.chrome.browser.password_check.helper.PasswordCheckChangePasswordHelper;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper; import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper.ReauthReason; import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper.ReauthReason;
import org.chromium.ui.modelutil.ListModel; import org.chromium.ui.modelutil.ListModel;
...@@ -35,12 +35,12 @@ import org.chromium.ui.modelutil.PropertyModel; ...@@ -35,12 +35,12 @@ import org.chromium.ui.modelutil.PropertyModel;
*/ */
class PasswordCheckMediator class PasswordCheckMediator
implements PasswordCheckCoordinator.CredentialEventHandler, PasswordCheck.Observer { implements PasswordCheckCoordinator.CredentialEventHandler, PasswordCheck.Observer {
private final PasswordCheckComponentUi.ChangePasswordDelegate mChangePasswordDelegate;
private final PasswordCheckReauthenticationHelper mReauthenticationHelper; private final PasswordCheckReauthenticationHelper mReauthenticationHelper;
private final PasswordCheckChangePasswordHelper mChangePasswordDelegate;
private PropertyModel mModel; private PropertyModel mModel;
private PasswordCheckComponentUi.Delegate mDelegate; private PasswordCheckComponentUi.Delegate mDelegate;
PasswordCheckMediator(ChangePasswordDelegate changePasswordDelegate, PasswordCheckMediator(PasswordCheckChangePasswordHelper changePasswordDelegate,
PasswordCheckReauthenticationHelper reauthenticationHelper) { PasswordCheckReauthenticationHelper reauthenticationHelper) {
mChangePasswordDelegate = changePasswordDelegate; mChangePasswordDelegate = changePasswordDelegate;
mReauthenticationHelper = reauthenticationHelper; mReauthenticationHelper = reauthenticationHelper;
......
// 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.password_check.helper;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Browser;
import androidx.browser.customtabs.CustomTabsIntent;
import org.chromium.base.IntentUtils;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.LaunchIntentDispatcher;
import org.chromium.chrome.browser.password_check.CompromisedCredential;
import org.chromium.chrome.browser.password_check.PasswordCheckEditFragmentView;
import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
import java.util.Objects;
/**
* Helper to launch apps, settings screens, or Chrome Custom tabs that enable the user to change a
* compromised password.
*/
public class PasswordCheckChangePasswordHelper {
private static final String AUTOFILL_ASSISTANT_PACKAGE =
"org.chromium.chrome.browser.autofill_assistant.";
private static final String AUTOFILL_ASSISTANT_ENABLED_KEY =
AUTOFILL_ASSISTANT_PACKAGE + "ENABLED";
private static final String PASSWORD_CHANGE_USERNAME_PARAMETER = "PASSWORD_CHANGE_USERNAME";
private static final String INTENT_PARAMETER = "INTENT";
private static final String INTENT = "PASSWORD_CHANGE";
private final Context mContext;
public PasswordCheckChangePasswordHelper(Context context) {
mContext = context;
}
/**
* Launches an app (if available) or a CCT with the site the given credential was used on.
* @param credential A {@link CompromisedCredential}.
*/
public void launchAppOrCctWithChangePasswordUrl(CompromisedCredential credential) {
// TODO(crbug.com/1092444): Always launch the URL if possible and let Android handle the
// match to open it.
IntentUtils.safeStartActivity(mContext,
credential.getAssociatedApp().isEmpty()
? buildIntent(credential.getPasswordChangeUrl())
: getPackageLaunchIntent(credential.getAssociatedApp()));
}
/**
* @param credential A {@link CompromisedCredential}.
* @return True iff there is a valid URL to navigate to or an app that can be opened.
*/
public boolean canManuallyChangeCredential(CompromisedCredential credential) {
return !credential.getPasswordChangeUrl().isEmpty()
|| getPackageLaunchIntent(credential.getAssociatedApp()) != null;
}
/**
* Launches a CCT with the site the given credential was used on and invokes the script that
* fixes the compromised credential automatically.
* @param credential A {@link CompromisedCredential}.
*/
public void launchCctWithScript(CompromisedCredential credential) {
Intent intent = buildIntent(credential.getOrigin().getSpec());
populateAutofillAssistantExtras(intent, credential.getUsername());
IntentUtils.safeStartActivity(mContext, intent);
}
/**
* Launches a settings fragment to edit the given credential.
* @param credential A {@link CompromisedCredential} to change.
*/
public void launchEditPage(CompromisedCredential credential) {
SettingsLauncher launcher = new SettingsLauncherImpl();
Bundle fragmentArgs = new Bundle();
fragmentArgs.putParcelable(
PasswordCheckEditFragmentView.EXTRA_COMPROMISED_CREDENTIAL, credential);
launcher.launchSettingsActivity(
mContext, PasswordCheckEditFragmentView.class, fragmentArgs);
}
private Intent getPackageLaunchIntent(String packageName) {
return Objects.requireNonNull(mContext).getPackageManager().getLaunchIntentForPackage(
packageName);
}
/**
* Builds an intent to launch a CCT.
*
* @param initialUrl Initial URL to launch a CCT.
* @return {@link Intent} for CCT.
*/
private Intent buildIntent(String initialUrl) {
CustomTabsIntent customTabIntent =
new CustomTabsIntent.Builder().setShowTitle(true).build();
customTabIntent.intent.setData(Uri.parse(initialUrl));
Intent intent = LaunchIntentDispatcher.createCustomTabActivityIntent(
mContext, customTabIntent.intent);
intent.setPackage(mContext.getPackageName());
intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
IntentHandler.addTrustedIntentExtras(intent);
return intent;
}
/**
* Populates intent extras for an Autofill Assistant script.
*
* @param intent An {@link Intent} to be populated.
* @param username A username for a password change script. One of extras to put.
*/
private void populateAutofillAssistantExtras(Intent intent, String username) {
intent.putExtra(AUTOFILL_ASSISTANT_ENABLED_KEY, true);
intent.putExtra(AUTOFILL_ASSISTANT_PACKAGE + PASSWORD_CHANGE_USERNAME_PARAMETER, username);
intent.putExtra(AUTOFILL_ASSISTANT_PACKAGE + INTENT_PARAMETER, INTENT);
// TODO(crbug.com/1086114): Also add the following parameters when server side changes is
// ready: CALLER, SOURCE. That would be useful for metrics.
}
}
\ No newline at end of file
...@@ -9,7 +9,7 @@ import android.view.MenuItem; ...@@ -9,7 +9,7 @@ import android.view.MenuItem;
/** /**
* This component is responsible for handling the UI logic for the password check. * This component is responsible for handling the UI logic for the password check.
*/ */
interface PasswordCheckComponentUi { public interface PasswordCheckComponentUi {
/** /**
* A delegate that handles native tasks for the UI component. * A delegate that handles native tasks for the UI component.
*/ */
...@@ -21,37 +21,6 @@ interface PasswordCheckComponentUi { ...@@ -21,37 +21,6 @@ interface PasswordCheckComponentUi {
void removeCredential(CompromisedCredential credential); void removeCredential(CompromisedCredential credential);
} }
/**
* Implementers of this delegate are expected to launch apps or Chrome Custom tabs that enable
* the user to change a compromised password.
*/
interface ChangePasswordDelegate {
/**
* @param credential A {@link CompromisedCredential}.
* @return True iff there is a valid URL to navigate to or an app that can be opened.
*/
boolean canManuallyChangeCredential(CompromisedCredential credential);
/**
* Launches an app (if available) or a CCT with the site the given credential was used on.
* @param credential A {@link CompromisedCredential}.
*/
void launchAppOrCctWithChangePasswordUrl(CompromisedCredential credential);
/**
* Launches a CCT with the site the given credential was used on and invokes the script that
* fixes the compromised credential automatically.
* @param credential A {@link CompromisedCredential}.
*/
void launchCctWithScript(CompromisedCredential credential);
/**
* Starts a new site (e.g. a fragment) that allows to change the password saved in Chrome.
* @param credential A {@link CompromisedCredential} to edit in Chrome.
*/
void launchEditPage(CompromisedCredential credential);
}
/** /**
* Handle the request of the user to show the help page for the Check Passwords view. * Handle the request of the user to show the help page for the Check Passwords view.
* @param item A {@link MenuItem}. * @param item A {@link MenuItem}.
......
...@@ -52,6 +52,7 @@ import org.chromium.base.Callback; ...@@ -52,6 +52,7 @@ import org.chromium.base.Callback;
import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.password_check.PasswordCheckProperties.ItemType; import org.chromium.chrome.browser.password_check.PasswordCheckProperties.ItemType;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckChangePasswordHelper;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper; import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper;
import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper.ReauthReason; import org.chromium.chrome.browser.password_check.helper.PasswordCheckReauthenticationHelper.ReauthReason;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
...@@ -83,7 +84,7 @@ public class PasswordCheckControllerTest { ...@@ -83,7 +84,7 @@ public class PasswordCheckControllerTest {
@Mock @Mock
private PasswordCheckComponentUi.Delegate mDelegate; private PasswordCheckComponentUi.Delegate mDelegate;
@Mock @Mock
private PasswordCheckComponentUi.ChangePasswordDelegate mChangePasswordDelegate; private PasswordCheckChangePasswordHelper mChangePasswordDelegate;
@Mock @Mock
private PasswordCheck mPasswordCheck; private PasswordCheck mPasswordCheck;
@Mock @Mock
......
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