Commit 07b947f3 authored by Viktor Semeniuk's avatar Viktor Semeniuk Committed by Commit Bot

[iOS][Password Check] Entry point from Breach Dialog

This change adds new entry point from Password Breach dialog to
Passwords screen. Password Check will automatically start when page is
opened.

Mock: https://docs.google.com/presentation/d/1B_Cr6KlWXtjfG7pA1xk5r9vDNtszICNfN3KqH-T30Q0/edit#slide=id.g853bc68e3a_3_598

Bug: 1075494, 1113170
Change-Id: I5693b53c05078961df83f519d3a0175240f8db97
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2320170
Commit-Queue: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: default avatarJavier Ernesto Flores Robles <javierrobles@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Reviewed-by: default avatarIoana Pandele <ioanap@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795432}
parent dbe5766a
...@@ -134,6 +134,14 @@ class IOSChromePasswordCheckManager ...@@ -134,6 +134,14 @@ class IOSChromePasswordCheckManager
password_manager::BulkLeakCheckServiceAdapter password_manager::BulkLeakCheckServiceAdapter
bulk_leak_check_service_adapter_; bulk_leak_check_service_adapter_;
// Boolean that remembers whether the delegate is initialized. This is done
// when the delegate obtains the list of saved passwords for the first time.
bool is_initialized_ = false;
// Boolean that indicate whether Password Check should be started right after
// delegate is initialized.
bool start_check_on_init_ = false;
// A scoped observer for |saved_passwords_presenter_|. // A scoped observer for |saved_passwords_presenter_|.
ScopedObserver<password_manager::SavedPasswordsPresenter, ScopedObserver<password_manager::SavedPasswordsPresenter,
password_manager::SavedPasswordsPresenter::Observer> password_manager::SavedPasswordsPresenter::Observer>
......
...@@ -114,11 +114,15 @@ IOSChromePasswordCheckManager::IOSChromePasswordCheckManager( ...@@ -114,11 +114,15 @@ IOSChromePasswordCheckManager::IOSChromePasswordCheckManager(
IOSChromePasswordCheckManager::~IOSChromePasswordCheckManager() = default; IOSChromePasswordCheckManager::~IOSChromePasswordCheckManager() = default;
void IOSChromePasswordCheckManager::StartPasswordCheck() { void IOSChromePasswordCheckManager::StartPasswordCheck() {
IOSChromePasswordCheckManagerHolder data( if (is_initialized_) {
scoped_refptr<IOSChromePasswordCheckManager>(this)); IOSChromePasswordCheckManagerHolder data(
bulk_leak_check_service_adapter_.StartBulkLeakCheck(kPasswordCheckDataKey, scoped_refptr<IOSChromePasswordCheckManager>(this));
&data); bulk_leak_check_service_adapter_.StartBulkLeakCheck(kPasswordCheckDataKey,
is_check_running_ = true; &data);
is_check_running_ = true;
} else {
start_check_on_init_ = true;
}
} }
void IOSChromePasswordCheckManager::StopPasswordCheck() { void IOSChromePasswordCheckManager::StopPasswordCheck() {
...@@ -183,6 +187,9 @@ void IOSChromePasswordCheckManager::OnSavedPasswordsChanged( ...@@ -183,6 +187,9 @@ void IOSChromePasswordCheckManager::OnSavedPasswordsChanged(
SavedPasswordsView) { SavedPasswordsView) {
// Observing saved passwords to update possible kNoPasswords state. // Observing saved passwords to update possible kNoPasswords state.
NotifyPasswordCheckStatusChanged(); NotifyPasswordCheckStatusChanged();
if (!std::exchange(is_initialized_, true) && start_check_on_init_) {
StartPasswordCheck();
}
} }
void IOSChromePasswordCheckManager::OnCompromisedCredentialsChanged( void IOSChromePasswordCheckManager::OnCompromisedCredentialsChanged(
......
...@@ -41,6 +41,11 @@ enum class KeyRetrievalTriggerForUMA; ...@@ -41,6 +41,11 @@ enum class KeyRetrievalTriggerForUMA;
- (void)showSavedPasswordsSettingsFromViewController: - (void)showSavedPasswordsSettingsFromViewController:
(UIViewController*)baseViewController; (UIViewController*)baseViewController;
// Shows the list of saved passwords in the settings. Automatically starts
// password check.
- (void)showSavedPasswordsSettingsAndStartPasswordCheckFromViewController:
(UIViewController*)baseViewController;
// Shows the list of profiles (addresess) in the settings. // Shows the list of profiles (addresess) in the settings.
- (void)showProfileSettingsFromViewController: - (void)showProfileSettingsFromViewController:
(UIViewController*)baseViewController; (UIViewController*)baseViewController;
......
...@@ -1100,7 +1100,28 @@ const char kMultiWindowOpenInNewWindowHistogram[] = ...@@ -1100,7 +1100,28 @@ const char kMultiWindowOpenInNewWindowHistogram[] =
Browser* browser = self.mainInterface.browser; Browser* browser = self.mainInterface.browser;
self.settingsNavigationController = self.settingsNavigationController =
[SettingsNavigationController savePasswordsControllerForBrowser:browser [SettingsNavigationController savePasswordsControllerForBrowser:browser
delegate:self]; delegate:self
startPasswordCheckAutomatically:NO];
[baseViewController presentViewController:self.settingsNavigationController
animated:YES
completion:nil];
}
- (void)showSavedPasswordsSettingsAndStartPasswordCheckFromViewController:
(UIViewController*)baseViewController {
DCHECK(!self.signinCoordinator);
[self dismissModalDialogs];
if (self.settingsNavigationController) {
[self.settingsNavigationController
showSavedPasswordsSettingsAndStartPasswordCheckFromViewController:
baseViewController];
return;
}
Browser* browser = self.mainInterface.browser;
self.settingsNavigationController =
[SettingsNavigationController savePasswordsControllerForBrowser:browser
delegate:self
startPasswordCheckAutomatically:YES];
[baseViewController presentViewController:self.settingsNavigationController [baseViewController presentViewController:self.settingsNavigationController
animated:YES animated:YES
completion:nil]; completion:nil];
......
...@@ -20,6 +20,7 @@ source_set("passwords") { ...@@ -20,6 +20,7 @@ source_set("passwords") {
"resources", "resources",
"//base", "//base",
"//components/password_manager/core/browser", "//components/password_manager/core/browser",
"//components/password_manager/core/common",
"//components/strings:components_strings_grit", "//components/strings:components_strings_grit",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser/main:public", "//ios/chrome/browser/main:public",
......
...@@ -103,4 +103,11 @@ using password_manager::CredentialLeakType; ...@@ -103,4 +103,11 @@ using password_manager::CredentialLeakType;
.permittedArrowDirections = UIPopoverArrowDirectionUp; .permittedArrowDirections = UIPopoverArrowDirectionUp;
} }
- (void)startPasswordCheck {
id<ApplicationCommands> handler = HandlerForProtocol(
self.browser->GetCommandDispatcher(), ApplicationCommands);
[handler showSavedPasswordsSettingsAndStartPasswordCheckFromViewController:
self.baseViewController];
}
@end @end
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "components/password_manager/core/browser/leak_detection_dialog_utils.h" #include "components/password_manager/core/browser/leak_detection_dialog_utils.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/common/password_manager_features.h"
#import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#import "ios/chrome/browser/ui/passwords/password_breach_consumer.h" #import "ios/chrome/browser/ui/passwords/password_breach_consumer.h"
#import "ios/chrome/browser/ui/passwords/password_breach_presenter.h" #import "ios/chrome/browser/ui/passwords/password_breach_presenter.h"
#include "ios/chrome/browser/ui/ui_feature_flags.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -82,12 +84,19 @@ using password_manager::metrics_util::LogLeakDialogTypeAndDismissalReason; ...@@ -82,12 +84,19 @@ using password_manager::metrics_util::LogLeakDialogTypeAndDismissalReason;
} }
- (void)confirmationAlertPrimaryAction { - (void)confirmationAlertPrimaryAction {
// Opening a new tab already stops the presentation in the presenter.
// No need to send |stop|.
self.dismissReason = LeakDialogDismissalReason::kClickedCheckPasswords; self.dismissReason = LeakDialogDismissalReason::kClickedCheckPasswords;
OpenNewTabCommand* newTabCommand = if (base::FeatureList::IsEnabled(
[OpenNewTabCommand commandWithURLFromChrome:GetPasswordCheckupURL()]; password_manager::features::kPasswordCheck)) {
[self.handler openURLInNewTab:newTabCommand]; // Opening Password page will stop the presentation in the presenter.
// No need to send |stop|.
[self.presenter startPasswordCheck];
} else {
// Opening a new tab already stops the presentation in the presenter.
// No need to send |stop|.
OpenNewTabCommand* newTabCommand =
[OpenNewTabCommand commandWithURLFromChrome:GetPasswordCheckupURL()];
[self.handler openURLInNewTab:newTabCommand];
}
} }
- (void)confirmationAlertLearnMoreAction { - (void)confirmationAlertLearnMoreAction {
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
// Informs the presenter that the feature should dismiss. // Informs the presenter that the feature should dismiss.
- (void)stop; - (void)stop;
// Informs the presenter that the Password page should be open.
- (void)startPasswordCheck;
@end @end
#endif // IOS_CHROME_BROWSER_UI_PASSWORDS_PASSWORD_BREACH_PRESENTER_H_ #endif // IOS_CHROME_BROWSER_UI_PASSWORDS_PASSWORD_BREACH_PRESENTER_H_
...@@ -22,6 +22,9 @@ class Browser; ...@@ -22,6 +22,9 @@ class Browser;
- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; - (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
// Starts password check.
- (void)startPasswordCheck;
@end @end
@interface PasswordsTableViewController (Testing) < @interface PasswordsTableViewController (Testing) <
......
...@@ -309,6 +309,12 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf( ...@@ -309,6 +309,12 @@ std::vector<std::unique_ptr<autofill::PasswordForm>> CopyOf(
return self; return self;
} }
- (void)startPasswordCheck {
if (_passwordCheck->GetPasswordCheckState() != PasswordCheckState::kRunning) {
_passwordCheck->StartPasswordCheck();
}
}
#pragma mark - UIViewController #pragma mark - UIViewController
- (void)viewDidLoad { - (void)viewDidLoad {
......
...@@ -77,11 +77,13 @@ extern NSString* const kSettingsDoneButtonId; ...@@ -77,11 +77,13 @@ extern NSString* const kSettingsDoneButtonId;
// Creates a new SavePasswordsCollectionViewController and the chrome around it. // Creates a new SavePasswordsCollectionViewController and the chrome around it.
// |browser| is the browser where settings are being displayed and should not be // |browser| is the browser where settings are being displayed and should not be
// nil. |delegate| may be nil. // nil. |delegate| may be nil. |startCheck| indicates whether startPasswordCheck
// should be called right after creating view controller.
+ (instancetype) + (instancetype)
savePasswordsControllerForBrowser:(Browser*)browser savePasswordsControllerForBrowser:(Browser*)browser
delegate:(id<SettingsNavigationControllerDelegate>) delegate:(id<SettingsNavigationControllerDelegate>)
delegate; delegate
startPasswordCheckAutomatically:(BOOL)startCheck;
// Creates and displays a new UIViewController for user to report an issue. // Creates and displays a new UIViewController for user to report an issue.
// |browser| is the browser where settings are being displayed and should not be // |browser| is the browser where settings are being displayed and should not be
......
...@@ -140,11 +140,15 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId"; ...@@ -140,11 +140,15 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId";
+ (instancetype) + (instancetype)
savePasswordsControllerForBrowser:(Browser*)browser savePasswordsControllerForBrowser:(Browser*)browser
delegate:(id<SettingsNavigationControllerDelegate>) delegate:(id<SettingsNavigationControllerDelegate>)
delegate { delegate
startPasswordCheckAutomatically:(BOOL)startCheck {
DCHECK(browser); DCHECK(browser);
PasswordsTableViewController* controller = PasswordsTableViewController* controller =
[[PasswordsTableViewController alloc] initWithBrowser:browser]; [[PasswordsTableViewController alloc] initWithBrowser:browser];
controller.dispatcher = [delegate handlerForSettings]; controller.dispatcher = [delegate handlerForSettings];
if (startCheck) {
[controller startPasswordCheck];
}
SettingsNavigationController* nc = [[SettingsNavigationController alloc] SettingsNavigationController* nc = [[SettingsNavigationController alloc]
initWithRootViewController:controller initWithRootViewController:controller
...@@ -526,6 +530,15 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId"; ...@@ -526,6 +530,15 @@ NSString* const kSettingsDoneButtonId = @"kSettingsDoneButtonId";
[self pushViewController:controller animated:YES]; [self pushViewController:controller animated:YES];
} }
- (void)showSavedPasswordsSettingsAndStartPasswordCheckFromViewController:
(UIViewController*)baseViewController {
PasswordsTableViewController* controller =
[[PasswordsTableViewController alloc] initWithBrowser:self.browser];
controller.dispatcher = [self.settingsNavigationDelegate handlerForSettings];
[controller startPasswordCheck];
[self pushViewController:controller animated:YES];
}
// TODO(crbug.com/779791) : Do not pass |baseViewController| through dispatcher. // TODO(crbug.com/779791) : Do not pass |baseViewController| through dispatcher.
- (void)showProfileSettingsFromViewController: - (void)showProfileSettingsFromViewController:
(UIViewController*)baseViewController { (UIViewController*)baseViewController {
......
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