Commit fcdb3ef9 authored by Jérôme Lebel's avatar Jérôme Lebel Committed by Commit Bot

[iOS] Adding unified user consent dialog

This patch is to implement unified user consent dialog. This dialog is
not used yet. This dialog will be used by ChromeSigninViewController in
the workflow of sign-in.


This dialog has 2 goals:
  - Asks to the user to choose an account
  - Shows the user consent to the user

Some assets are not ready and are shown in red. The strings are not
final neither.

Implementation:
with identity:
https://drive.google.com/open?id=1ebwI5_pmWCuz09x-zJQYCuJIKxKoLVH5
https://drive.google.com/open?id=1WUdN_NtzF74tn28HaRwpqbUZ3L2vtJS8
https://drive.google.com/open?id=1zSBHzGsk-vwuhL4fJQw0vsDZ7sDzCwnk
https://drive.google.com/open?id=1rWf_KT6hnKHUvtEoAYA3wr7koyepXEXF
without identity:
https://drive.google.com/open?id=1HQjRFu_cODRzKY2ZKpyJ7hTjJMXPjEui

Mock:
https://docs.google.com/presentation/d/1cZfr5FGWGSy0PNaQ8uzik0alLAH-5glh1vsb030vha8/edit?ts=5aba5455#slide=id.g353bc22139_3_19

Related to previous patch:
crrev.com/c/995417
Related to next patch:
crrev.com/c/1010346

Bug: 827072
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I706c6024ff59d1c7870a39afcc04443e88dcb6dc
Reviewed-on: https://chromium-review.googlesource.com/1009906
Commit-Queue: Jérôme Lebel <jlebel@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551340}
parent 02ba7243
...@@ -137,6 +137,15 @@ locale. The strings in this file are specific to iOS. ...@@ -137,6 +137,15 @@ locale. The strings in this file are specific to iOS.
<message name="IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE" desc="Title of the screen where users select an account to use. [Length: 20em] [iOS only]"> <message name="IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE" desc="Title of the screen where users select an account to use. [Length: 20em] [iOS only]">
Sign in to Chromium Sign in to Chromium
</message> </message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_BETTER_BROWSER" desc="Description on the sign-in consent dialog to explain the benefit to sign-in. [Length: unlimited] [iOS only]" translateable="false">
Improve Chromium and its security by sending system and usage data to Google
</message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SETTINGS" desc="Description on the sign-in consent dialog to explain the benefit to sign-in. [Length: unlimited] [iOS only]" translateable="false">
Google may use content on sites you visit, browser interactions and activity to personalize Chromium and Google services like Translate, Search and ads. You can customize this in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>
</message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_TITLE" desc="Title on the sign-in consent dialog to explain why sign-in can be useful for the user. [Length: 14em] [iOS only]" translateable="false">
Get Google smarts in Chromium
</message>
<message name="IDS_IOS_APP_RATING_PROMO_STRING" desc="Text displayed for the rate this app promo. [iOS only]"> <message name="IDS_IOS_APP_RATING_PROMO_STRING" desc="Text displayed for the rate this app promo. [iOS only]">
Enjoying Chromium? <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Rate this app<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph> Enjoying Chromium? <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Rate this app<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph>
</message> </message>
......
...@@ -137,6 +137,15 @@ locale. The strings in this file are specific to iOS. ...@@ -137,6 +137,15 @@ locale. The strings in this file are specific to iOS.
<message name="IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE" desc="Title of the screen where users select an account to use. [Length: 20em] [iOS only]"> <message name="IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE" desc="Title of the screen where users select an account to use. [Length: 20em] [iOS only]">
Sign in to Chrome Sign in to Chrome
</message> </message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_BETTER_BROWSER" desc="Description on the sign-in consent dialog to explain the benefit to sign-in. [Length: unlimited] [iOS only]" translateable="false">
Improve Chrome and its security by sending system and usage data to Google
</message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SETTINGS" desc="Description on the sign-in consent dialog to explain the benefit to sign-in. [Length: unlimited] [iOS only]" translateable="false">
Google may use content on sites you visit, browser interactions and activity to personalize Chrome and Google services like Translate, Search and ads. You can customize this in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>
</message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_TITLE" desc="Title on the sign-in consent dialog to explain why sign-in can be useful for the user. [Length: 14em] [iOS only]" translateable="false">
Get Google smarts in Chrome
</message>
<message name="IDS_IOS_APP_RATING_PROMO_STRING" desc="Text displayed for the rate this app promo. [iOS only]"> <message name="IDS_IOS_APP_RATING_PROMO_STRING" desc="Text displayed for the rate this app promo. [iOS only]">
Enjoying Chrome? <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Rate this app<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph> Enjoying Chrome? <ph name="BEGIN_LINK"><ex>BEGIN_LINK</ex>BEGIN_LINK</ph>Rate this app<ph name="END_LINK"><ex>END_LINK</ex>END_LINK</ph>
</message> </message>
......
...@@ -140,6 +140,12 @@ locale. The strings in this file are specific to iOS. ...@@ -140,6 +140,12 @@ locale. The strings in this file are specific to iOS.
<message name="IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON" desc="Title of the button to accept sign in and navigate away from the confirmation screen. [Length: 20m] [iOS only]"> <message name="IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON" desc="Title of the button to accept sign in and navigate away from the confirmation screen. [Length: 20m] [iOS only]">
Ok, Got it Ok, Got it
</message> </message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SYNC_DATA" desc="Description on the sign-in consent dialog to explain the benefit to sign-in. [Length: unlimited] [iOS only]" translateable="false">
Your passwords, history &amp; more on all devices
</message>
<message name="IDS_IOS_ACCOUNT_UNIFIED_CONSENT_PERSONALIZED" desc="Description on the sign-in consent dialog to explain the benefit to sign-in. [Length: unlimited] [iOS only]" translateable="false">
Personalized Google services like Google Pay
</message>
<message name="IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OPEN_SETTINGS" desc="Description of how to configure sync and Google services on the sign-in confirmation screen. [Length: unlimited]"> <message name="IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OPEN_SETTINGS" desc="Description of how to configure sync and Google services on the sign-in confirmation screen. [Length: unlimited]">
Manage Chrome Sync and personalization in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph> Manage Chrome Sync and personalization in <ph name="BEGIN_LINK">BEGIN_LINK</ph>Settings<ph name="END_LINK">END_LINK</ph>
</message> </message>
......
// Copyright 2018 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.
#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_COORDINATOR_H_
#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_COORDINATOR_H_
#import <UIKit/UIKit.h>
#include <vector>
@class ChromeIdentity;
@class UnifiedConsentCoordinator;
// Delegate protocol for UnifiedConsentCoordinator.
@protocol UnifiedConsentCoordinatorDelegate<NSObject>
// Called when the user taps on the settings link.
- (void)unifiedConsentCoordinatorDidTapSettingsLink:
(UnifiedConsentCoordinator*)controller;
@end
// UnityConsentCoordinator coordinates UnityConsentViewController, which is a
// sub view controller to ask for the user consent before the user can sign-in.
// All the string ids displayed by the view are available with
// |consentStringIds| and |openSettingsStringId|. Those can be used to record
// the consent agreed by the user.
@interface UnifiedConsentCoordinator : NSObject
@property(nonatomic, weak) id<UnifiedConsentCoordinatorDelegate> delegate;
// Identity selected by the user to sign-in.
@property(nonatomic, strong, readonly) ChromeIdentity* selectedIdentity;
// String id for text to open the settings (related to record the user consent).
@property(nonatomic, readonly) int openSettingsStringId;
// View controller used to display the view.
@property(nonatomic, strong, readonly) UIViewController* viewController;
// Starts this coordinator.
- (void)start;
// List of string ids used for the user consent. The string ids order matches
// the way they appear on the screen.
- (const std::vector<int>&)consentStringIds;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_COORDINATOR_H_
// Copyright 2018 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.
#include "ios/chrome/browser/ui/authentication/unified_consent_coordinator.h"
#include "base/logging.h"
#import "ios/chrome/browser/ui/authentication/unified_consent_mediator.h"
#import "ios/chrome/browser/ui/authentication/unified_consent_view_controller.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface UnifiedConsentCoordinator ()<UnifiedConsentViewControllerDelegate>
@property(nonatomic, strong) UnifiedConsentMediator* unifiedConsentMediator;
@property(nonatomic, strong, readwrite)
UnifiedConsentViewController* unifiedConsentViewController;
@end
@implementation UnifiedConsentCoordinator
@synthesize delegate = _delegate;
@synthesize unifiedConsentMediator = _unifiedConsentMediator;
@synthesize unifiedConsentViewController = _unifiedConsentViewController;
- (void)start {
self.unifiedConsentViewController =
[[UnifiedConsentViewController alloc] init];
self.unifiedConsentViewController.delegate = self;
self.unifiedConsentMediator = [[UnifiedConsentMediator alloc]
initWithUnifiedConsentViewController:self.unifiedConsentViewController];
[self.unifiedConsentMediator start];
}
- (ChromeIdentity*)selectedIdentity {
return self.unifiedConsentMediator.selectedIdentity;
}
- (UIViewController*)viewController {
return self.unifiedConsentViewController;
}
- (int)openSettingsStringId {
return self.unifiedConsentViewController.openSettingsStringId;
}
- (const std::vector<int>&)consentStringIds {
return [self.unifiedConsentViewController consentStringIds];
}
#pragma mark - UnifiedConsentViewControllerDelegate
- (void)unifiedConsentViewControllerDidTapSettingsLink:
(UnifiedConsentViewController*)controller {
DCHECK_EQ(self.unifiedConsentViewController, controller);
[self.delegate unifiedConsentCoordinatorDidTapSettingsLink:self];
}
- (void)unifiedConsentViewControllerDidTapIdentityPickerView:
(UnifiedConsentViewController*)controller {
DCHECK_EQ(self.unifiedConsentViewController, controller);
// TODO(crbug.com/827072): Needs implementation.
}
@end
// Copyright 2018 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.
#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_MEDIATOR_H_
#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_MEDIATOR_H_
#import <Foundation/Foundation.h>
@class ChromeIdentity;
@class UnifiedConsentViewController;
// A mediator object that monitor updates of the selecte chrome identity, and
// updates the UnifiedConsentViewController.
@interface UnifiedConsentMediator : NSObject
// Identity selected by the user to sign-in.
@property(nonatomic) ChromeIdentity* selectedIdentity;
- (instancetype)initWithUnifiedConsentViewController:
(UnifiedConsentViewController*)viewController NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
// Starts this mediator.
- (void)start;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_MEDIATOR_H_
// Copyright 2018 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.
#include "ios/chrome/browser/ui/authentication/unified_consent_mediator.h"
#include "base/logging.h"
#import "ios/chrome/browser/chrome_browser_provider_observer_bridge.h"
#import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
#include "ios/chrome/browser/ui/authentication/unified_consent_view_controller.h"
#import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface UnifiedConsentMediator ()<ChromeIdentityServiceObserver,
ChromeBrowserProviderObserver> {
std::unique_ptr<ChromeIdentityServiceObserverBridge> _identityServiceObserver;
std::unique_ptr<ChromeBrowserProviderObserverBridge> _browserProviderObserver;
}
@property(nonatomic, weak)
UnifiedConsentViewController* unifiedConsentViewController;
@property(nonatomic, strong) UIImage* selectedIdentityAvatar;
@end
@implementation UnifiedConsentMediator
@synthesize selectedIdentityAvatar = _selectedIdentityAvatar;
@synthesize selectedIdentity = _selectedIdentity;
@synthesize unifiedConsentViewController = _unifiedConsentViewController;
- (instancetype)initWithUnifiedConsentViewController:
(UnifiedConsentViewController*)viewController {
self = [super init];
if (self) {
_unifiedConsentViewController = viewController;
}
return self;
}
- (void)setSelectedIdentity:(ChromeIdentity*)selectedIdentity {
if (selectedIdentity == self.selectedIdentity)
return;
_selectedIdentity = selectedIdentity;
self.selectedIdentityAvatar = nil;
__weak UnifiedConsentMediator* weakSelf = self;
ios::GetChromeBrowserProvider()
->GetChromeIdentityService()
->GetAvatarForIdentity(self.selectedIdentity, ^(UIImage* identityAvatar) {
if (weakSelf.selectedIdentity != selectedIdentity) {
return;
}
[weakSelf identityAvatarUpdated:identityAvatar];
});
[self updateViewController];
}
- (void)start {
_identityServiceObserver =
std::make_unique<ChromeIdentityServiceObserverBridge>(self);
_browserProviderObserver =
std::make_unique<ChromeBrowserProviderObserverBridge>(self);
NSArray* identities = ios::GetChromeBrowserProvider()
->GetChromeIdentityService()
->GetAllIdentitiesSortedForDisplay();
// Make sure the view is loaded so the mediator can set it up.
[self.unifiedConsentViewController loadViewIfNeeded];
if (identities.count != 0) {
self.selectedIdentity = identities[0];
}
}
#pragma mark - Private
- (void)updateViewController {
if (self.selectedIdentity) {
[self.unifiedConsentViewController
updateIdentityPickerViewWithUserFullName:self.selectedIdentity
.userFullName
email:self.selectedIdentity
.userEmail];
[self.unifiedConsentViewController
updateIdentityPickerViewWithAvatar:self.selectedIdentityAvatar];
} else {
[self.unifiedConsentViewController hideIdentityPickerView];
}
}
- (void)identityAvatarUpdated:(UIImage*)identityAvatar {
if (_selectedIdentityAvatar == identityAvatar)
return;
_selectedIdentityAvatar = identityAvatar;
[self.unifiedConsentViewController
updateIdentityPickerViewWithAvatar:self.selectedIdentityAvatar];
}
#pragma mark - ChromeBrowserProviderObserver
- (void)chromeIdentityServiceDidChange:(ios::ChromeIdentityService*)identity {
DCHECK(!_identityServiceObserver.get());
_identityServiceObserver =
std::make_unique<ChromeIdentityServiceObserverBridge>(self);
}
- (void)chromeBrowserProviderWillBeDestroyed {
_browserProviderObserver.reset();
}
#pragma mark - ChromeIdentityServiceObserver
- (void)identityListChanged {
ChromeIdentity* newIdentity = nil;
NSArray* identities = ios::GetChromeBrowserProvider()
->GetChromeIdentityService()
->GetAllIdentitiesSortedForDisplay();
if (identities.count != 0) {
newIdentity = identities[0];
}
if (newIdentity != self.selectedIdentity) {
self.selectedIdentity = newIdentity;
}
}
- (void)profileUpdate:(ChromeIdentity*)identity {
if (identity == self.selectedIdentity) {
[self updateViewController];
}
}
- (void)chromeIdentityServiceWillBeDestroyed {
_identityServiceObserver.reset();
}
@end
// Copyright 2018 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.
#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
#include <vector>
@class ChromeIdentity;
@class UnifiedConsentViewController;
// Delegate protocol for UnityConsentViewController.
@protocol UnifiedConsentViewControllerDelegate<NSObject>
// Called when the user taps on the settings link.
- (void)unifiedConsentViewControllerDidTapSettingsLink:
(UnifiedConsentViewController*)controller;
// Called when the user taps on the IdentityPickerView.
- (void)unifiedConsentViewControllerDidTapIdentityPickerView:
(UnifiedConsentViewController*)controller;
@end
// UnityConsentViewController is a sub view controller to ask for the user
// consent before the user can sign-in.
// All the string ids displayed by the view are available with
// |consentStringIds| and |openSettingsStringId|. Those can be used to record
// the consent agreed by the user.
@interface UnifiedConsentViewController : UIViewController
@property(nonatomic, weak) id<UnifiedConsentViewControllerDelegate> delegate;
// String id for text to open the settings (related to record the user consent).
@property(nonatomic, readonly) int openSettingsStringId;
// -[UnifiedConsentViewController init] should be used.
- (instancetype)initWithNibName:(NSString*)nibNameOrNil
bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
// List of string ids used for the user consent. The string ids order matches
// the way they appear on the screen.
- (const std::vector<int>&)consentStringIds;
// Shows (if hidden) and updates the IdentityPickerView.
- (void)updateIdentityPickerViewWithUserFullName:(NSString*)fullName
email:(NSString*)email;
// Updates the IdentityPickerView avatar.
- (void)updateIdentityPickerViewWithAvatar:(UIImage*)avatar;
// Hides the IdentityPickerView.
- (void)hideIdentityPickerView;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
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