[ios] Wraps the QR scanner in a basic coordinator.

The new QRScannerCoordinator class provides a single entry point for the
activity services feature, including all of the necessary public API.
Dependencies on other components are encapsulated within new protocols that are
declared in the requirements/ subdirectory.

Bug: 
Change-Id: I532c78a3be95589e4651c210f80a4ae7bf4625e3
Reviewed-on: https://chromium-review.googlesource.com/577814
Reviewed-by: Mark Cogan <[email protected]>
Commit-Queue: Rohit Rao (ping after 24h) <[email protected]>
Cr-Commit-Position: refs/heads/master@{#494794}
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn
index a2cbfa1..a585df6e 100644
--- a/ios/chrome/browser/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/BUILD.gn
@@ -269,7 +269,6 @@
     "//ios/chrome/browser/ui/overscroll_actions",
     "//ios/chrome/browser/ui/payments",
     "//ios/chrome/browser/ui/print",
-    "//ios/chrome/browser/ui/qr_scanner",
     "//ios/chrome/browser/ui/reading_list",
     "//ios/chrome/browser/ui/stack_view",
     "//ios/chrome/browser/ui/static_content",
@@ -399,7 +398,8 @@
     "//ios/chrome/browser/ui/overscroll_actions",
     "//ios/chrome/browser/ui/payments",
     "//ios/chrome/browser/ui/print",
-    "//ios/chrome/browser/ui/qr_scanner",
+    "//ios/chrome/browser/ui/qr_scanner:coordinator",
+    "//ios/chrome/browser/ui/qr_scanner/requirements",
     "//ios/chrome/browser/ui/reading_list",
     "//ios/chrome/browser/ui/stack_view",
     "//ios/chrome/browser/ui/static_content",
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 5f25134..dc388e0 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -135,7 +135,8 @@
 #import "ios/chrome/browser/ui/page_not_available_controller.h"
 #import "ios/chrome/browser/ui/payments/payment_request_manager.h"
 #import "ios/chrome/browser/ui/print/print_controller.h"
-#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h"
+#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h"
+#import "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h"
 #import "ios/chrome/browser/ui/reading_list/offline_page_native_content.h"
 #import "ios/chrome/browser/ui/reading_list/reading_list_coordinator.h"
 #import "ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.h"
@@ -356,6 +357,7 @@
                                     OverscrollActionsControllerDelegate,
                                     PassKitDialogProvider,
                                     PreloadControllerDelegate,
+                                    QRScannerPresenting,
                                     SKStoreProductViewControllerDelegate,
                                     SnapshotOverlayProvider,
                                     StoreKitLauncher,
@@ -425,9 +427,6 @@
   // Used to display the Voice Search UI.  Nil if not visible.
   scoped_refptr<VoiceSearchController> _voiceSearchController;
 
-  // Used to display the QR Scanner UI. Nil if not visible.
-  QRScannerViewController* _qrScannerViewController;
-
   // Used to display the Reading List.
   ReadingListCoordinator* _readingListCoordinator;
 
@@ -525,6 +524,9 @@
   // Coordinator for displaying alerts.
   AlertCoordinator* _alertCoordinator;
 
+  // Coordinator for the QR scanner.
+  QRScannerLegacyCoordinator* _qrScannerCoordinator;
+
   // Coordinator for Tab History Popup.
   TabHistoryCoordinator* _tabHistoryCoordinator;
 }
@@ -1357,7 +1359,6 @@
     self.typingShield = nil;
     if (_voiceSearchController)
       _voiceSearchController->SetDelegate(nil);
-    _qrScannerViewController = nil;
     _readingListCoordinator = nil;
     _toolbarController = nil;
     _toolbarModelDelegate = nil;
@@ -1740,6 +1741,7 @@
 
   // Disconnect child coordinators.
   [_activityServiceCoordinator disconnect];
+  [_qrScannerCoordinator disconnect];
   [_tabHistoryCoordinator disconnect];
 
   // The file remover needs the browser state, so needs to be destroyed now.
@@ -1847,6 +1849,12 @@
   _activityServiceCoordinator.presentationProvider = self;
   _activityServiceCoordinator.snackbarProvider = self;
 
+  _qrScannerCoordinator =
+      [[QRScannerLegacyCoordinator alloc] initWithBaseViewController:self];
+  _qrScannerCoordinator.dispatcher = _dispatcher;
+  _qrScannerCoordinator.loadProvider = _toolbarController;
+  _qrScannerCoordinator.presentationProvider = self;
+
   _tabHistoryCoordinator =
       [[TabHistoryCoordinator alloc] initWithBaseViewController:self];
   _tabHistoryCoordinator.dispatcher = _dispatcher;
@@ -4248,15 +4256,6 @@
   [self addToReadingListURL:[command URL] title:[command title]];
 }
 
-- (void)showQRScanner {
-  _qrScannerViewController =
-      [[QRScannerViewController alloc] initWithDelegate:_toolbarController];
-  [self presentViewController:[_qrScannerViewController
-                                  getViewControllerToPresent]
-                     animated:YES
-                   completion:nil];
-}
-
 - (void)showReadingList {
   _readingListCoordinator = [[ReadingListCoordinator alloc]
       initWithBaseViewController:self
@@ -5134,6 +5133,18 @@
   [self.dialogPresenter tryToPresent];
 }
 
+#pragma mark - QRScanner Requirements
+
+- (void)presentQRScannerViewController:(UIViewController*)controller {
+  [self presentViewController:controller animated:YES completion:nil];
+}
+
+- (void)dismissQRScannerViewController:(UIViewController*)controller
+                            completion:(void (^)(void))completion {
+  DCHECK_EQ(controller, self.presentedViewController);
+  [self dismissViewControllerAnimated:YES completion:completion];
+}
+
 #pragma mark - TabHistoryPresenter
 
 - (void)prepareForTabHistoryPresentation {
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn
index 3f20de2..d165a0b 100644
--- a/ios/chrome/browser/ui/commands/BUILD.gn
+++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -20,6 +20,7 @@
     "open_new_tab_command.mm",
     "open_url_command.h",
     "open_url_command.mm",
+    "qr_scanner_commands.h",
     "reading_list_add_command.h",
     "reading_list_add_command.mm",
     "show_mail_composer_command.h",
diff --git a/ios/chrome/browser/ui/commands/browser_commands.h b/ios/chrome/browser/ui/commands/browser_commands.h
index 990c7758..05f87669 100644
--- a/ios/chrome/browser/ui/commands/browser_commands.h
+++ b/ios/chrome/browser/ui/commands/browser_commands.h
@@ -9,14 +9,17 @@
 
 #import "ios/chrome/browser/ui/commands/activity_service_commands.h"
 #import "ios/chrome/browser/ui/commands/history_popup_commands.h"
+#import "ios/chrome/browser/ui/commands/qr_scanner_commands.h"
 
 @class OpenNewTabCommand;
 @class ReadingListAddCommand;
 
 // Protocol for commands that will generally be handled by the "current tab",
 // which in practice is the BrowserViewController instance displaying the tab.
-@protocol
-    BrowserCommands<NSObject, ActivityServiceCommands, TabHistoryPopupCommands>
+@protocol BrowserCommands<NSObject,
+                          ActivityServiceCommands,
+                          QRScannerCommands,
+                          TabHistoryPopupCommands>
 
 // Closes the current tab.
 - (void)closeCurrentTab;
@@ -48,9 +51,6 @@
 // Adds a page to the reading list using data in |command|.
 - (void)addToReadingList:(ReadingListAddCommand*)command;
 
-// Shows the QR scanner UI.
-- (void)showQRScanner;
-
 // Shows the Reading List UI.
 - (void)showReadingList;
 
diff --git a/ios/chrome/browser/ui/commands/qr_scanner_commands.h b/ios/chrome/browser/ui/commands/qr_scanner_commands.h
new file mode 100644
index 0000000..012c2d6
--- /dev/null
+++ b/ios/chrome/browser/ui/commands/qr_scanner_commands.h
@@ -0,0 +1,16 @@
+// Copyright 2017 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_COMMANDS_QR_SCANNER_COMMANDS_H_
+#define IOS_CHROME_BROWSER_UI_COMMANDS_QR_SCANNER_COMMANDS_H_
+
+// QRScannerCommands contains commands related to scanning QR codes.
+@protocol QRScannerCommands<NSObject>
+
+// Shows the QR scanner UI.
+- (void)showQRScanner;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_COMMANDS_QR_SCANNER_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/qr_scanner/BUILD.gn b/ios/chrome/browser/ui/qr_scanner/BUILD.gn
index 7e74d40..dcd4435 100644
--- a/ios/chrome/browser/ui/qr_scanner/BUILD.gn
+++ b/ios/chrome/browser/ui/qr_scanner/BUILD.gn
@@ -27,6 +27,7 @@
     "//ios/chrome/browser",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/icons",
+    "//ios/chrome/browser/ui/qr_scanner/requirements",
     "//ios/chrome/common:ios_app_bundle_id_prefix_header",
     "//ios/third_party/material_components_ios",
     "//ui/base",
@@ -37,6 +38,23 @@
   ]
 }
 
+source_set("coordinator") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "qr_scanner_legacy_coordinator.h",
+    "qr_scanner_legacy_coordinator.mm",
+  ]
+  deps = [
+    ":qr_scanner",
+    "//ios/chrome/browser",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/tabs",
+    "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/browser/ui/qr_scanner/requirements",
+    "//ios/shared/chrome/browser/ui/commands",
+  ]
+}
+
 source_set("eg_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h
new file mode 100644
index 0000000..93b44b2
--- /dev/null
+++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h
@@ -0,0 +1,32 @@
+// Copyright 2017 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_QR_SCANNER_QR_SCANNER_LEGACY_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_UI_QR_SCANNER_QR_SCANNER_LEGACY_COORDINATOR_H_
+
+#import "ios/chrome/browser/chrome_coordinator.h"
+
+@class CommandDispatcher;
+@protocol QRScannerPresenting;
+@protocol QRScannerResultLoading;
+
+// QRScannerLegacyCoordinator presents the public interface for the QR scanner
+// feature.
+@interface QRScannerLegacyCoordinator : ChromeCoordinator
+
+// Models.
+@property(nonatomic, readwrite, weak) CommandDispatcher* dispatcher;
+
+// Requirements.
+@property(nonatomic, readwrite, weak) id<QRScannerPresenting>
+    presentationProvider;
+@property(nonatomic, readwrite, weak) id<QRScannerResultLoading> loadProvider;
+
+// Removes references to any weak objects that this coordinator holds pointers
+// to.
+- (void)disconnect;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_QR_SCANNER_QR_SCANNER_LEGACY_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.mm
new file mode 100644
index 0000000..34858325
--- /dev/null
+++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.mm
@@ -0,0 +1,56 @@
+// Copyright 2017 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.
+
+#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_legacy_coordinator.h"
+
+#import "ios/chrome/browser/ui/commands/browser_commands.h"
+#import "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h"
+#import "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h"
+#import "ios/shared/chrome/browser/ui/commands/command_dispatcher.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface QRScannerLegacyCoordinator ()
+
+@property(nonatomic, readwrite, strong) QRScannerViewController* viewController;
+
+@end
+
+@implementation QRScannerLegacyCoordinator
+
+@synthesize dispatcher = _dispatcher;
+@synthesize loadProvider = _loadProvider;
+@synthesize presentationProvider = _presentationProvider;
+@synthesize viewController = _viewController;
+
+- (void)disconnect {
+  self.dispatcher = nil;
+}
+
+- (void)setDispatcher:(CommandDispatcher*)dispatcher {
+  if (dispatcher == self.dispatcher) {
+    return;
+  }
+
+  if (self.dispatcher) {
+    [self.dispatcher stopDispatchingToTarget:self];
+  }
+
+  [dispatcher startDispatchingToTarget:self
+                           forSelector:@selector(showQRScanner)];
+  _dispatcher = dispatcher;
+}
+
+- (void)showQRScanner {
+  self.viewController = [[QRScannerViewController alloc]
+      initWithPresentationProvider:self.presentationProvider
+                      loadProvider:self.loadProvider];
+  [self.presentationProvider
+      presentQRScannerViewController:[self.viewController
+                                             getViewControllerToPresent]];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
index 973b6ef..6fc2671 100644
--- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
+++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h
@@ -9,26 +9,14 @@
 
 #include "ios/chrome/browser/ui/qr_scanner/camera_controller.h"
 
-@protocol QRScannerViewControllerDelegate
-
-// Called when the scanner detects a valid code. Camera recording is stopped
-// when a result is scanned and the QRScannerViewController is dismissed. This
-// function is called when the dismissal completes. A valid code is any
-// non-empty string. If |load| is YES, the scanned code was of a type which can
-// only encode digits, and the delegate can load the result immediately, instead
-// of prompting the user to confirm the result.
-- (void)receiveQRScannerResult:(NSString*)qrScannerResult
-               loadImmediately:(BOOL)load;
-
-@end
+@protocol QRScannerPresenting;
+@protocol QRScannerResultLoading;
 
 @interface QRScannerViewController : UIViewController<CameraControllerDelegate>
 
-// The delegate which receives the scanned result after the view controller is
-// dismissed.
-@property(nonatomic, weak) id<QRScannerViewControllerDelegate> delegate;
-
-- (instancetype)initWithDelegate:(id<QRScannerViewControllerDelegate>)delegate
+- (instancetype)
+initWithPresentationProvider:(id<QRScannerPresenting>)presentationProvider
+                loadProvider:(id<QRScannerResultLoading>)loadProvider
     NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)initWithNibName:(NSString*)name
diff --git a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
index c39eec38..c9a8bd2f 100644
--- a/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
+++ b/ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.mm
@@ -12,6 +12,8 @@
 #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_alerts.h"
 #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_transitioning_delegate.h"
 #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_view.h"
+#include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h"
+#include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h"
 #include "ios/chrome/grit/ios_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -49,6 +51,10 @@
   QRScannerTransitioningDelegate* _transitioningDelegate;
 }
 
+@property(nonatomic, readwrite, weak) id<QRScannerPresenting>
+    presentationProvider;
+@property(nonatomic, readwrite, weak) id<QRScannerResultLoading> loadProvider;
+
 // Dismisses the QRScannerViewController and runs |completion| on completion.
 // Logs metrics according to the |reason| for dismissal.
 - (void)dismissForReason:(DismissalReason)reason
@@ -72,15 +78,18 @@
 
 @implementation QRScannerViewController
 
-@synthesize delegate = _delegate;
+@synthesize loadProvider = _loadProvider;
+@synthesize presentationProvider = _presentationProvider;
 
 #pragma mark lifecycle
 
-- (instancetype)initWithDelegate:(id<QRScannerViewControllerDelegate>)delegate {
+- (instancetype)
+initWithPresentationProvider:(id<QRScannerPresenting>)presentationProvider
+                loadProvider:(id<QRScannerResultLoading>)loadProvider {
   self = [super initWithNibName:nil bundle:nil];
   if (self) {
-    DCHECK(delegate);
-    _delegate = delegate;
+    _loadProvider = loadProvider;
+    _presentationProvider = presentationProvider;
     _cameraController = [CameraController cameraControllerWithDelegate:self];
   }
   return self;
@@ -235,8 +244,9 @@
     case IMPOSSIBLY_UNLIKELY_AUTHORIZATION_CHANGE:
       break;
   }
-  [[self presentingViewController] dismissViewControllerAnimated:YES
-                                                      completion:completion];
+
+  [self.presentationProvider dismissQRScannerViewController:self
+                                                 completion:completion];
 }
 
 - (void)startReceivingNotifications {
@@ -279,8 +289,8 @@
     DCHECK(_result);
     [self dismissForReason:SCANNED_CODE
             withCompletion:^{
-              [[self delegate] receiveQRScannerResult:_result
-                                      loadImmediately:_loadResultImmediately];
+              [self.loadProvider receiveQRScannerResult:_result
+                                        loadImmediately:_loadResultImmediately];
             }];
   }
 }
@@ -346,8 +356,8 @@
     [_qrScannerView animateScanningResultWithCompletion:^void(void) {
       [self dismissForReason:SCANNED_CODE
               withCompletion:^{
-                [[self delegate] receiveQRScannerResult:result
-                                        loadImmediately:load];
+                [self.loadProvider receiveQRScannerResult:result
+                                          loadImmediately:load];
               }];
     }];
   }
diff --git a/ios/chrome/browser/ui/qr_scanner/requirements/BUILD.gn b/ios/chrome/browser/ui/qr_scanner/requirements/BUILD.gn
new file mode 100644
index 0000000..370741b6
--- /dev/null
+++ b/ios/chrome/browser/ui/qr_scanner/requirements/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2017 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.
+
+source_set("requirements") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "qr_scanner_presenting.h",
+    "qr_scanner_result_loading.h",
+  ]
+}
diff --git a/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h
new file mode 100644
index 0000000..8e22110
--- /dev/null
+++ b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_presenting.h
@@ -0,0 +1,22 @@
+// Copyright 2017 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_QR_SCANNER_REQUIREMENTS_QR_SCANNER_PRESENTING_H_
+#define IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_PRESENTING_H_
+
+// QRScannerPresenting contains methods that control how the QR scanner UI is
+// presented and dismissed on screen.
+@protocol QRScannerPresenting
+
+// Asks the implementer to present the given |controller|.
+- (void)presentQRScannerViewController:(UIViewController*)controller;
+
+// Asks the implementer to dismiss the given |controller| and call the given
+// |completion| afterwards.
+- (void)dismissQRScannerViewController:(UIViewController*)controller
+                            completion:(void (^)(void))completion;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_PRESENTING_H_
diff --git a/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h
new file mode 100644
index 0000000..ef16745
--- /dev/null
+++ b/ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h
@@ -0,0 +1,23 @@
+// Copyright 2017 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_QR_SCANNER_REQUIREMENTS_QR_SCANNER_RESULT_LOADING_H_
+#define IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_RESULT_LOADING_H_
+
+// QRScannerResultLoading contains methods that allow the QR scanner to load
+// pages when valid QR codes are detected.
+@protocol QRScannerResultLoading
+
+// Called when the scanner detects a valid code. Camera recording is stopped
+// when a result is scanned and the QRScannerViewController is dismissed. This
+// function is called when the dismissal completes. A valid code is any
+// non-empty string. If |load| is YES, the scanned code was of a type which can
+// only encode digits, and the delegate can load the result immediately, instead
+// of prompting the user to confirm the result.
+- (void)receiveQRScannerResult:(NSString*)qrScannerResult
+               loadImmediately:(BOOL)load;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_QR_SCANNER_REQUIREMENTS_QR_SCANNER_RESULT_LOADING_H_
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn
index 3b385424..b5af691 100644
--- a/ios/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -68,7 +68,7 @@
     "//ios/chrome/browser/ui/history_popup/requirements",
     "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/popup_menu",
-    "//ios/chrome/browser/ui/qr_scanner",
+    "//ios/chrome/browser/ui/qr_scanner/requirements",
     "//ios/chrome/browser/ui/toolbar/keyboard_assist",
     "//ios/chrome/browser/ui/tools_menu",
     "//ios/chrome/browser/ui/tools_menu:configuration",
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
index 36d2a142..bc93d48 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
@@ -10,7 +10,7 @@
 #import "ios/chrome/browser/ui/history_popup/requirements/tab_history_positioner.h"
 #import "ios/chrome/browser/ui/history_popup/requirements/tab_history_ui_updater.h"
 #include "ios/chrome/browser/ui/omnibox/omnibox_popup_positioner.h"
-#include "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h"
+#include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h"
 #include "ios/web/public/navigation_item_list.h"
@@ -85,7 +85,7 @@
 // omnibox, etc.
 @interface WebToolbarController
     : ToolbarController<OmniboxFocuser,
-                        QRScannerViewControllerDelegate,
+                        QRScannerResultLoading,
                         TabHistoryPositioner,
                         TabHistoryUIUpdater,
                         VoiceSearchControllerDelegate>
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index fc165bc..000b3a3 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -1368,7 +1368,7 @@
 }
 
 #pragma mark -
-#pragma mark QRScannerViewControllerDelegate methods.
+#pragma mark QRScanner Requirements.
 
 - (void)receiveQRScannerResult:(NSString*)result loadImmediately:(BOOL)load {
   DCHECK(result);