Commit a8f9fc3e authored by Sebastien Lalancette's avatar Sebastien Lalancette Committed by Commit Bot

[iOS] Add Scoping to QR Code Generator Coordinator

By adding a scopedHandler to handle both the "Show QR Code" and
"Dismiss QR Code" commands, we'll be able to reuse the ActivityServices
component to share URLs outside from the BrowserCoordinator.

Bug: 1102890
Change-Id: I830b3ed7a1a44cc1e4242c666bc3427d05aaf471
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2284101
Commit-Queue: Sebastien Lalancette <seblalancette@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790840}
parent 7336de4b
...@@ -57,7 +57,7 @@ NSString* const kGenerateQrCodeActivityType = ...@@ -57,7 +57,7 @@ NSString* const kGenerateQrCodeActivityType =
} }
- (BOOL)canPerformWithActivityItems:(NSArray*)activityItems { - (BOOL)canPerformWithActivityItems:(NSArray*)activityItems {
return base::FeatureList::IsEnabled(kQRCodeGeneration); return base::FeatureList::IsEnabled(kQRCodeGeneration) && self.handler;
} }
+ (UIActivityCategory)activityCategory { + (UIActivityCategory)activityCategory {
......
...@@ -56,6 +56,17 @@ TEST_F(GenerateQrCodeActivityTest, FlagOff_ActivityDisabled) { ...@@ -56,6 +56,17 @@ TEST_F(GenerateQrCodeActivityTest, FlagOff_ActivityDisabled) {
EXPECT_FALSE([activity canPerformWithActivityItems:@[]]); EXPECT_FALSE([activity canPerformWithActivityItems:@[]]);
} }
// Tests that the activity cannot be performed when its handler is nil.
TEST_F(GenerateQrCodeActivityTest, NilHandler_ActivityDisabled) {
scoped_features_.InitAndEnableFeature(kQRCodeGeneration);
GenerateQrCodeActivity* activity =
[[GenerateQrCodeActivity alloc] initWithURL:GURL("https://example.com")
title:@"Some title"
handler:nil];
EXPECT_FALSE([activity canPerformWithActivityItems:@[]]);
}
// Tests that the right handler method is invoked upon execution. // Tests that the right handler method is invoked upon execution.
TEST_F(GenerateQrCodeActivityTest, Execution) { TEST_F(GenerateQrCodeActivityTest, Execution) {
__block GURL fakeURL("https://example.com"); __block GURL fakeURL("https://example.com");
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
@protocol ActivityServicePositioner; @protocol ActivityServicePositioner;
@protocol ActivityServicePresentation; @protocol ActivityServicePresentation;
class Browser; class Browser;
@protocol QRGenerationCommands;
// ActivityServiceCoordinator provides a public interface for the share // ActivityServiceCoordinator provides a public interface for the share
// menu feature. // menu feature.
...@@ -39,6 +40,9 @@ class Browser; ...@@ -39,6 +40,9 @@ class Browser;
@property(nonatomic, readwrite, weak) id<ActivityServicePresentation> @property(nonatomic, readwrite, weak) id<ActivityServicePresentation>
presentationProvider; presentationProvider;
// Handler for activities that need to be executed within a certain scope.
@property(nonatomic, weak) id<QRGenerationCommands> scopedHandler;
@end @end
#endif // IOS_CHROME_BROWSER_UI_ACTIVITY_SERVICES_ACTIVITY_SERVICE_COORDINATOR_H_ #endif // IOS_CHROME_BROWSER_UI_ACTIVITY_SERVICES_ACTIVITY_SERVICE_COORDINATOR_H_
...@@ -38,9 +38,7 @@ const char kSharePageLatencyHistogram[] = "IOS.SharePageLatency"; ...@@ -38,9 +38,7 @@ const char kSharePageLatencyHistogram[] = "IOS.SharePageLatency";
@interface ActivityServiceCoordinator () @interface ActivityServiceCoordinator ()
@property(nonatomic, weak) @property(nonatomic, weak) id<BrowserCommands, FindInPageCommands> handler;
id<BrowserCommands, FindInPageCommands, QRGenerationCommands>
handler;
// The time when the Share Page operation started. // The time when the Share Page operation started.
@property(nonatomic, assign) base::TimeTicks sharePageStartTime; @property(nonatomic, assign) base::TimeTicks sharePageStartTime;
...@@ -69,8 +67,7 @@ const char kSharePageLatencyHistogram[] = "IOS.SharePageLatency"; ...@@ -69,8 +67,7 @@ const char kSharePageLatencyHistogram[] = "IOS.SharePageLatency";
#pragma mark - Public methods #pragma mark - Public methods
- (void)start { - (void)start {
self.handler = static_cast< self.handler = static_cast<id<BrowserCommands, FindInPageCommands>>(
id<BrowserCommands, FindInPageCommands, QRGenerationCommands>>(
self.browser->GetCommandDispatcher()); self.browser->GetCommandDispatcher());
ChromeBrowserState* browserState = self.browser->GetBrowserState(); ChromeBrowserState* browserState = self.browser->GetBrowserState();
...@@ -78,6 +75,7 @@ const char kSharePageLatencyHistogram[] = "IOS.SharePageLatency"; ...@@ -78,6 +75,7 @@ const char kSharePageLatencyHistogram[] = "IOS.SharePageLatency";
ios::BookmarkModelFactory::GetForBrowserState(browserState); ios::BookmarkModelFactory::GetForBrowserState(browserState);
self.mediator = self.mediator =
[[ActivityServiceMediator alloc] initWithHandler:self.handler [[ActivityServiceMediator alloc] initWithHandler:self.handler
qrGenerationHandler:self.scopedHandler
prefService:browserState->GetPrefs() prefService:browserState->GetPrefs()
bookmarkModel:bookmarkModel]; bookmarkModel:bookmarkModel];
......
...@@ -28,13 +28,13 @@ class PrefService; ...@@ -28,13 +28,13 @@ class PrefService;
@interface ActivityServiceMediator : NSObject @interface ActivityServiceMediator : NSObject
// Initializes a mediator instance with a |handler| used to execute action, a // Initializes a mediator instance with a |handler| used to execute action, a
// |prefService| to read settings and policies, and a |bookmarkModel| to // |qrGenerationHandler| to execute QR generation actions, a |prefService| to
// retrieve bookmark states. // read settings and policies, and a |bookmarkModel| to retrieve bookmark
- (instancetype) // states.
initWithHandler: - (instancetype)initWithHandler:(id<BrowserCommands, FindInPageCommands>)handler
(id<BrowserCommands, FindInPageCommands, QRGenerationCommands>)handler qrGenerationHandler:(id<QRGenerationCommands>)qrGenerationHandler
prefService:(PrefService*)prefService prefService:(PrefService*)prefService
bookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel bookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
......
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
@interface ActivityServiceMediator () @interface ActivityServiceMediator ()
@property(nonatomic, weak) @property(nonatomic, weak) id<BrowserCommands, FindInPageCommands> handler;
id<BrowserCommands, FindInPageCommands, QRGenerationCommands>
handler; @property(nonatomic, weak) id<QRGenerationCommands> qrGenerationHandler;
@property(nonatomic, assign) PrefService* prefService; @property(nonatomic, assign) PrefService* prefService;
...@@ -53,13 +53,13 @@ ...@@ -53,13 +53,13 @@
#pragma mark - Public #pragma mark - Public
- (instancetype) - (instancetype)initWithHandler:(id<BrowserCommands, FindInPageCommands>)handler
initWithHandler: qrGenerationHandler:(id<QRGenerationCommands>)qrGenerationHandler
(id<BrowserCommands, FindInPageCommands, QRGenerationCommands>)handler prefService:(PrefService*)prefService
prefService:(PrefService*)prefService bookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel {
bookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel {
if (self = [super init]) { if (self = [super init]) {
_handler = handler; _handler = handler;
_qrGenerationHandler = qrGenerationHandler;
_prefService = prefService; _prefService = prefService;
_bookmarkModel = bookmarkModel; _bookmarkModel = bookmarkModel;
} }
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
GenerateQrCodeActivity* generateQrCodeActivity = GenerateQrCodeActivity* generateQrCodeActivity =
[[GenerateQrCodeActivity alloc] initWithURL:data.shareURL [[GenerateQrCodeActivity alloc] initWithURL:data.shareURL
title:data.title title:data.title
handler:self.handler]; handler:self.qrGenerationHandler];
[applicationActivities addObject:generateQrCodeActivity]; [applicationActivities addObject:generateQrCodeActivity];
FindInPageActivity* findInPageActivity = FindInPageActivity* findInPageActivity =
......
...@@ -35,8 +35,7 @@ ...@@ -35,8 +35,7 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
@protocol @protocol HandlerProtocols <BrowserCommands, FindInPageCommands>
HandlerProtocols <BrowserCommands, FindInPageCommands, QRGenerationCommands>
@end @end
class ActivityServiceMediatorTest : public PlatformTest { class ActivityServiceMediatorTest : public PlatformTest {
...@@ -47,13 +46,16 @@ class ActivityServiceMediatorTest : public PlatformTest { ...@@ -47,13 +46,16 @@ class ActivityServiceMediatorTest : public PlatformTest {
pref_service_ = std::make_unique<TestingPrefServiceSimple>(); pref_service_ = std::make_unique<TestingPrefServiceSimple>();
mocked_handler_ = OCMStrictProtocolMock(@protocol(HandlerProtocols)); mocked_handler_ = OCMStrictProtocolMock(@protocol(HandlerProtocols));
mocked_qr_generation_handler_ =
OCMStrictProtocolMock(@protocol(QRGenerationCommands));
mocked_thumbnail_generator_ = mocked_thumbnail_generator_ =
OCMStrictClassMock([ChromeActivityItemThumbnailGenerator class]); OCMStrictClassMock([ChromeActivityItemThumbnailGenerator class]);
mediator_ = mediator_ = [[ActivityServiceMediator alloc]
[[ActivityServiceMediator alloc] initWithHandler:mocked_handler_ initWithHandler:mocked_handler_
prefService:pref_service_.get() qrGenerationHandler:mocked_qr_generation_handler_
bookmarkModel:nil]; prefService:pref_service_.get()
bookmarkModel:nil];
} }
void VerifyTypes(NSArray* activities, NSArray* expected_types) { void VerifyTypes(NSArray* activities, NSArray* expected_types) {
...@@ -64,6 +66,7 @@ class ActivityServiceMediatorTest : public PlatformTest { ...@@ -64,6 +66,7 @@ class ActivityServiceMediatorTest : public PlatformTest {
} }
id mocked_handler_; id mocked_handler_;
id mocked_qr_generation_handler_;
id mocked_thumbnail_generator_; id mocked_thumbnail_generator_;
std::unique_ptr<TestingPrefServiceSimple> pref_service_; std::unique_ptr<TestingPrefServiceSimple> pref_service_;
base::HistogramTester histograms_tester_; base::HistogramTester histograms_tester_;
......
...@@ -233,8 +233,6 @@ ...@@ -233,8 +233,6 @@
forProtocol:@protocol(BrowserCoordinatorCommands)]; forProtocol:@protocol(BrowserCoordinatorCommands)];
[self.dispatcher startDispatchingToTarget:self [self.dispatcher startDispatchingToTarget:self
forProtocol:@protocol(PageInfoCommands)]; forProtocol:@protocol(PageInfoCommands)];
[self.dispatcher startDispatchingToTarget:self
forProtocol:@protocol(QRGenerationCommands)];
[self installDelegatesForAllWebStates]; [self installDelegatesForAllWebStates];
[self installDelegatesForBrowser]; [self installDelegatesForBrowser];
[self addWebStateListObserver]; [self addWebStateListObserver];
...@@ -526,9 +524,12 @@ ...@@ -526,9 +524,12 @@
initWithBaseViewController:self.viewController initWithBaseViewController:self.viewController
browser:self.browser browser:self.browser
scenario:ActivityScenario::TabShareButton]; scenario:ActivityScenario::TabShareButton];
self.activityServiceCoordinator.positionProvider = self.activityServiceCoordinator.positionProvider =
[self.viewController activityServicePositioner]; [self.viewController activityServicePositioner];
self.activityServiceCoordinator.presentationProvider = self; self.activityServiceCoordinator.presentationProvider = self;
self.activityServiceCoordinator.scopedHandler = self;
[self.activityServiceCoordinator start]; [self.activityServiceCoordinator start];
} }
...@@ -750,7 +751,8 @@ ...@@ -750,7 +751,8 @@
initWithBaseViewController:self.viewController initWithBaseViewController:self.viewController
browser:self.browser browser:self.browser
title:command.title title:command.title
URL:command.URL]; URL:command.URL
handler:self];
[self.qrGeneratorCoordinator start]; [self.qrGeneratorCoordinator start];
} }
......
...@@ -8,16 +8,20 @@ ...@@ -8,16 +8,20 @@
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
#include "url/gurl.h" #include "url/gurl.h"
@protocol QRGenerationCommands;
// QRGeneratorCoordinator presents the public interface for the QR code // QRGeneratorCoordinator presents the public interface for the QR code
// generation feature. // generation feature.
@interface QRGeneratorCoordinator : ChromeCoordinator @interface QRGeneratorCoordinator : ChromeCoordinator
// Initializes an instance with a base |viewController|, the current |browser|, // Initializes an instance with a base |viewController|, the current |browser|,
// the |title| and |URL| of a webpage to generate a QR code for. // the |title| and |URL| of a webpage to generate a QR code for, and a |handler|
// to handle commands execution.
- (instancetype)initWithBaseViewController:(UIViewController*)viewController - (instancetype)initWithBaseViewController:(UIViewController*)viewController
browser:(Browser*)browser browser:(Browser*)browser
title:(NSString*)title title:(NSString*)title
URL:(const GURL&)URL URL:(const GURL&)URL
handler:(id<QRGenerationCommands>)handler
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
// Unavailable, use -initWithBaseViewController:browser:title:URL:. // Unavailable, use -initWithBaseViewController:browser:title:URL:.
......
...@@ -58,11 +58,13 @@ ...@@ -58,11 +58,13 @@
- (instancetype)initWithBaseViewController:(UIViewController*)viewController - (instancetype)initWithBaseViewController:(UIViewController*)viewController
browser:(Browser*)browser browser:(Browser*)browser
title:(NSString*)title title:(NSString*)title
URL:(const GURL&)URL { URL:(const GURL&)URL
handler:(id<QRGenerationCommands>)handler {
if (self = [super initWithBaseViewController:viewController if (self = [super initWithBaseViewController:viewController
browser:browser]) { browser:browser]) {
_title = title; _title = title;
_URL = URL; _URL = URL;
_handler = handler;
} }
return self; return self;
} }
...@@ -70,9 +72,6 @@ ...@@ -70,9 +72,6 @@
#pragma mark - Chrome Coordinator #pragma mark - Chrome Coordinator
- (void)start { - (void)start {
self.handler = HandlerForProtocol(self.browser->GetCommandDispatcher(),
QRGenerationCommands);
self.viewController = [[QRGeneratorViewController alloc] init]; self.viewController = [[QRGeneratorViewController alloc] init];
[self.viewController setModalPresentationStyle:UIModalPresentationFormSheet]; [self.viewController setModalPresentationStyle:UIModalPresentationFormSheet];
......
...@@ -35,17 +35,15 @@ class QRGeneratorCoordinatorTest : public PlatformTest { ...@@ -35,17 +35,15 @@ class QRGeneratorCoordinatorTest : public PlatformTest {
mock_qr_generation_commands_handler_ = mock_qr_generation_commands_handler_ =
OCMStrictProtocolMock(@protocol(QRGenerationCommands)); OCMStrictProtocolMock(@protocol(QRGenerationCommands));
[browser_->GetCommandDispatcher()
startDispatchingToTarget:mock_qr_generation_commands_handler_
forProtocol:@protocol(QRGenerationCommands)];
test_title_ = @"Does not matter"; test_title_ = @"Does not matter";
coordinator_ = [[QRGeneratorCoordinator alloc] coordinator_ = [[QRGeneratorCoordinator alloc]
initWithBaseViewController:base_view_controller_ initWithBaseViewController:base_view_controller_
browser:browser_.get() browser:browser_.get()
title:test_title_ title:test_title_
URL:test_url_]; URL:test_url_
handler:(id<QRGenerationCommands>)
mock_qr_generation_commands_handler_];
} }
NSString* test_title_; NSString* test_title_;
......
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