[iOSKAUpgrade] Pre-select relevant data type in ExpandedManualFillVC
This CL selects the relevant segment from the
ExpandedManualFillViewController's segmented control depending on the
type of the form the user is trying to fill. There's currently no
selected segment when the expanded manual fill view appears. This CL
changes that.
Note: Switching data types by tapping/swiping the different segments
will be handled in a separate CL.
Mocks: go/ios-keyboard-accessory-upgrade-mocks
Fixed: 325607752
Change-Id: I095996677eb82684911d33e988c5a56aaa40fe40
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5278570
Commit-Queue: Noémie St-Onge <noemies@google.com>
Reviewed-by: Tommy Martino <tmartino@chromium.org>
Reviewed-by: Alexis Hétu <sugoi@chromium.org>
Reviewed-by: David Jean <djean@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1261980}
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn b/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn
index 8e22cdd1..fe51195 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/BUILD.gn
@@ -57,6 +57,7 @@
"//ios/chrome/browser/ui/autofill/branding",
"//ios/chrome/browser/ui/autofill/branding:branding_ui",
"//ios/chrome/browser/ui/autofill/manual_fill",
+ "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_constants",
"//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui",
"//ios/chrome/browser/ui/bubble",
"//ios/chrome/browser/ui/toolbar/public",
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
index 46f1e2f..5ad04a4 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.mm
@@ -322,11 +322,12 @@
}
// Starts the expanded manual fill coordinator and displays its view controller.
-- (void)startManualFill {
+- (void)startManualFillForDataType:(manual_fill::ManualFillDataType)dataType {
ExpandedManualFillCoordinator* expandedManualFillCoordinator =
[[ExpandedManualFillCoordinator alloc]
initWithBaseViewController:self.baseViewController
- browser:self.browser];
+ browser:self.browser
+ forDataType:dataType];
[expandedManualFillCoordinator start];
self.formInputViewController = expandedManualFillCoordinator.viewController;
@@ -403,11 +404,13 @@
- (void)formInputAccessoryViewController:
(FormInputAccessoryViewController*)formInputAccessoryViewController
- didPressManualFillButton:(UIButton*)manualFillButton {
+ didPressManualFillButton:(UIButton*)manualFillButton
+ forDataType:
+ (manual_fill::ManualFillDataType)dataType {
CHECK(IsKeyboardAccessoryUpgradeEnabled());
[self stopChildren];
- [self startManualFill];
+ [self startManualFillForDataType:dataType];
[self updateKeyboardAccessoryForManualFilling];
}
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
index eedf8b0..fc3be3b 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller.mm
@@ -19,6 +19,7 @@
#import "ios/chrome/browser/ui/autofill/form_input_accessory/form_suggestion_view.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller_delegate.h"
+#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h"
#import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h"
#import "ios/chrome/common/ui/elements/form_input_accessory_view.h"
#import "ios/chrome/common/ui/util/constraints_ui_util.h"
@@ -26,6 +27,9 @@
#import "ui/base/device_form_factor.h"
#import "ui/base/l10n/l10n_util.h"
+using autofill::FillingProduct;
+using manual_fill::ManualFillDataType;
+
@interface FormInputAccessoryViewController () <
FormSuggestionViewDelegate,
ManualFillAccessoryViewControllerDelegate>
@@ -185,9 +189,12 @@
- (void)manualFillButtonPressed:(UIButton*)button {
DCHECK(IsKeyboardAccessoryUpgradeEnabled());
+ ManualFillDataType dataType =
+ [self manualFillDataTypeFromFillingProduct:_mainFillingProduct];
[_formInputAccessoryViewControllerDelegate
formInputAccessoryViewController:self
- didPressManualFillButton:button];
+ didPressManualFillButton:button
+ forDataType:dataType];
[self showManualFillView:YES];
}
@@ -354,31 +361,33 @@
self.lastAnnouncedFieldId != _currentFieldId) {
std::u16string mainFillingProductString;
switch (_mainFillingProduct) {
- case autofill::FillingProduct::kAddress:
- case autofill::FillingProduct::kPlusAddresses:
+ case FillingProduct::kAddress:
+ case FillingProduct::kPlusAddresses:
mainFillingProductString = l10n_util::GetPluralStringFUTF16(
IDS_IOS_AUTOFILL_ADDRESS_SUGGESTIONS_AVAILABLE_ACCESSIBILITY_ANNOUNCEMENT,
suggestionCount);
break;
- case autofill::FillingProduct::kPassword:
+ case FillingProduct::kPassword:
mainFillingProductString = l10n_util::GetPluralStringFUTF16(
IDS_IOS_AUTOFILL_PASSWORD_SUGGESTIONS_AVAILABLE_ACCESSIBILITY_ANNOUNCEMENT,
suggestionCount);
break;
- case autofill::FillingProduct::kCreditCard:
- case autofill::FillingProduct::kIban:
+ case FillingProduct::kCreditCard:
+ case FillingProduct::kIban:
mainFillingProductString = l10n_util::GetPluralStringFUTF16(
IDS_IOS_AUTOFILL_PAYMENT_METHOD_SUGGESTIONS_AVAILABLE_ACCESSIBILITY_ANNOUNCEMENT,
suggestionCount);
break;
- case autofill::FillingProduct::kAutocomplete:
+ case FillingProduct::kAutocomplete:
mainFillingProductString = l10n_util::GetPluralStringFUTF16(
IDS_IOS_AUTOFILL_AUTOCOMPLETE_SUGGESTIONS_AVAILABLE_ACCESSIBILITY_ANNOUNCEMENT,
suggestionCount);
break;
- case autofill::FillingProduct::kMerchantPromoCode:
- case autofill::FillingProduct::kCompose:
- case autofill::FillingProduct::kNone:
+ case FillingProduct::kMerchantPromoCode:
+ case FillingProduct::kCompose:
+ // These cases are currently not available on iOS.
+ NOTREACHED_NORETURN();
+ case FillingProduct::kNone:
return;
}
@@ -426,6 +435,29 @@
}
}
+// Returns a ManualFillDataType based on the provided FillingProduct.
+- (ManualFillDataType)manualFillDataTypeFromFillingProduct:
+ (FillingProduct)fillingProduct {
+ switch (fillingProduct) {
+ case FillingProduct::kAddress:
+ case FillingProduct::kPlusAddresses:
+ return ManualFillDataType::kAddress;
+ case FillingProduct::kCreditCard:
+ case FillingProduct::kIban:
+ return ManualFillDataType::kPaymentMethod;
+ case FillingProduct::kPassword:
+ case FillingProduct::kAutocomplete:
+ case FillingProduct::kNone:
+ // `kPassword` acts as the default value when the FillingProduct
+ // doesn't point towards a specific data type.
+ return ManualFillDataType::kPassword;
+ case FillingProduct::kCompose:
+ case FillingProduct::kMerchantPromoCode:
+ // These cases are currently not available on iOS.
+ NOTREACHED_NORETURN();
+ }
+}
+
#pragma mark - ManualFillAccessoryViewControllerDelegate
- (void)manualFillAccessoryViewController:(ManualFillAccessoryViewController*)
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller_delegate.h b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller_delegate.h
index 0966b884..e782146e 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller_delegate.h
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_view_controller_delegate.h
@@ -9,6 +9,10 @@
@class FormInputAccessoryViewController;
+namespace manual_fill {
+enum class ManualFillDataType;
+}
+
// Protocol to handle user interactions in a FormInputAccessoryViewController.
@protocol FormInputAccessoryViewControllerDelegate
@@ -35,7 +39,9 @@
// Invoked after the user taps the `manual fill` button.
- (void)formInputAccessoryViewController:
(FormInputAccessoryViewController*)formInputAccessoryViewController
- didPressManualFillButton:(UIButton*)manualFillButton;
+ didPressManualFillButton:(UIButton*)manualFillButton
+ forDataType:
+ (manual_fill::ManualFillDataType)dataType;
// Invoked after the user taps the form input accessory view.
- (void)formInputAccessoryViewController:
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
index ff8fc36..819603a 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -35,6 +35,7 @@
"manual_fill_password_mediator.mm",
]
deps = [
+ ":manual_fill_constants",
":requesters",
"//base",
"//components/autofill/core/browser",
@@ -89,6 +90,7 @@
"card_view_controller.mm",
"chip_button.h",
"chip_button.mm",
+ "expanded_manual_fill_view_controller+Testing.h",
"expanded_manual_fill_view_controller.h",
"expanded_manual_fill_view_controller.mm",
"fallback_view_controller.h",
@@ -163,6 +165,7 @@
testonly = true
sources = [
"chip_button_unittest.mm",
+ "expanded_manual_fill_view_controller_unittest.mm",
"fallback_view_controller_unittest.mm",
"form_observer_helper_unittest.mm",
"full_card_requester_unittest.mm",
@@ -177,6 +180,7 @@
]
deps = [
":manual_fill",
+ ":manual_fill_constants",
":manual_fill_ui",
":requesters",
"//base",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h
index 3fb0923..6d51961 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h
+++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h
@@ -7,9 +7,24 @@
#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h"
+namespace manual_fill {
+enum class ManualFillDataType;
+}
+
// The coordinator responsible for presenting the expanded manual fill view.
@interface ExpandedManualFillCoordinator : ChromeCoordinator
+// Designated initializer. `dataType` represents the type of manual filling
+// options to show in the expanded manual fill view.
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+ browser:(Browser*)browser
+ forDataType:
+ (manual_fill::ManualFillDataType)dataType
+ NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+ browser:(Browser*)browser NS_UNAVAILABLE;
+
// Returns the coordinator's view controller.
- (UIViewController*)viewController;
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm
index c31707d..03bb7bd 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.mm
@@ -5,6 +5,9 @@
#import "ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_coordinator.h"
#import "ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h"
+
+using manual_fill::ManualFillDataType;
@interface ExpandedManualFillCoordinator ()
@@ -14,11 +17,27 @@
@end
-@implementation ExpandedManualFillCoordinator
+@implementation ExpandedManualFillCoordinator {
+ // Initial data type to present in the expanded manual fill view.
+ ManualFillDataType _initialDataType;
+}
+
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+ browser:(Browser*)browser
+ forDataType:(ManualFillDataType)dataType {
+ self = [super initWithBaseViewController:viewController browser:browser];
+ if (self) {
+ _initialDataType = dataType;
+ }
+ return self;
+}
- (void)start {
self.expandedManualFillViewController =
- [[ExpandedManualFillViewController alloc] init];
+ [[ExpandedManualFillViewController alloc]
+ initForDataType:_initialDataType];
+
+ // TODO(b/40942168): Show manual filling options.
}
- (void)stop {
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller+Testing.h b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller+Testing.h
new file mode 100644
index 0000000..8b4731d
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller+Testing.h
@@ -0,0 +1,19 @@
+// Copyright 2024 The Chromium Authors
+// 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_AUTOFILL_MANUAL_FILL_EXPANDED_MANUAL_FILL_VIEW_CONTROLLER_TESTING_H_
+#define IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_EXPANDED_MANUAL_FILL_VIEW_CONTROLLER_TESTING_H_
+
+#import "ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.h"
+
+// Testing category exposing a private property of
+// ExpandedManualFillViewController for tests.
+@interface ExpandedManualFillViewController (Testing)
+
+// Control allowing switching between the different data types.
+@property(nonatomic, strong, readonly) UISegmentedControl* segmentedControl;
+
+@end
+
+#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_EXPANDED_MANUAL_FILL_VIEW_CONTROLLER_TESTING_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.h b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.h
index d289c42..3878de9 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.h
+++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.h
@@ -7,10 +7,27 @@
#import <UIKit/UIKit.h>
+namespace manual_fill {
+enum class ManualFillDataType;
+}
+
// View that presents manual filling options for a specific autofill data type
// (i.e., password, payment or address) and allows switching between the
// different types.
@interface ExpandedManualFillViewController : UIViewController
+
+// Designated initializer. `dataType` represents the type of manual filling
+// options to show.
+- (instancetype)initForDataType:(manual_fill::ManualFillDataType)dataType
+ NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithNibName:(NSString*)nibNameOrNil
+ bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
+
+- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
+
+- (instancetype)init NS_UNAVAILABLE;
+
@end
#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_EXPANDED_MANUAL_FILL_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.mm
index b06f65a..768dbf59 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller.mm
@@ -13,6 +13,8 @@
#import "ios/chrome/grit/ios_strings.h"
#import "ui/base/l10n/l10n_util.h"
+using manual_fill::ManualFillDataType;
+
namespace {
// Size of the Chrome logo.
@@ -44,8 +46,28 @@
// the wide layout only.
constexpr CGFloat kSegmentedControlTrailingSpacingWideLayout = 15;
+// Helper method to get the right segment index depending on the `data_type`.
+int GetSegmentIndexForDataType(ManualFillDataType data_type) {
+ switch (data_type) {
+ case ManualFillDataType::kPassword:
+ return 0;
+ case ManualFillDataType::kPaymentMethod:
+ return 1;
+ case ManualFillDataType::kAddress:
+ return 2;
+ }
+}
+
} // namespace
+@interface ExpandedManualFillViewController ()
+
+// Control allowing switching between the different data types. Not an ivar so
+// that it can be used in tests.
+@property(nonatomic, strong) UISegmentedControl* segmentedControl;
+
+@end
+
@implementation ExpandedManualFillViewController {
// Header view presented at the top of this view controller's view. Contains
// the Chrome logo, close button and segmented control. The
@@ -69,8 +91,17 @@
// Button to close the view.
ExtendedTouchTargetButton* _closeButton;
- // Control allowing switching between the different data types.
- UISegmentedControl* _segmentedControl;
+ // Initial data type to present in the view. Reflects the type of the form the
+ // user wants to fill.
+ ManualFillDataType _initialDataType;
+}
+
+- (instancetype)initForDataType:(ManualFillDataType)dataType {
+ self = [super initWithNibName:nil bundle:nil];
+ if (self) {
+ _initialDataType = dataType;
+ }
+ return self;
}
#pragma mark - UIViewController
@@ -86,7 +117,8 @@
_headerTopView = [self createHeaderTopView];
_chromeLogo = [self createChromeLogo];
_closeButton = [self createCloseButton];
- _segmentedControl = [self createSegmentedControl];
+ _segmentedControl =
+ [self createSegmentedControlAndSelectDataType:_initialDataType];
_headerViewHeightConstraint = [_headerView.heightAnchor
constraintEqualToConstant:kHeaderViewHeightWideLayout];
@@ -204,8 +236,10 @@
return closeButton;
}
-// Creates and configures the segmented control.
-- (UISegmentedControl*)createSegmentedControl {
+// Creates and configures the segmented control. `dataType` indicates which
+// segment to select.
+- (UISegmentedControl*)createSegmentedControlAndSelectDataType:
+ (ManualFillDataType)dataType {
UIImageSymbolConfiguration* symbolConfiguration = [UIImageSymbolConfiguration
configurationWithPointSize:kDataTypeIconSize
weight:UIImageSymbolWeightRegular
@@ -229,8 +263,7 @@
UISegmentedControl* segmentedControl = [[UISegmentedControl alloc]
initWithItems:@[ passwordIcon, cardIcon, addressIcon ]];
segmentedControl.translatesAutoresizingMaskIntoConstraints = NO;
- // TODO(b/40942168): Pre-select relevant data type with
- // `segmentedControl.selectedSegmentIndex =`.
+ segmentedControl.selectedSegmentIndex = GetSegmentIndexForDataType(dataType);
[segmentedControl addTarget:self
action:@selector(onSegmentSelected:)
forControlEvents:UIControlEventValueChanged];
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller_unittest.mm b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller_unittest.mm
new file mode 100644
index 0000000..b329699
--- /dev/null
+++ b/ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller_unittest.mm
@@ -0,0 +1,56 @@
+// Copyright 2024 The Chromium Authors
+// 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/autofill/manual_fill/expanded_manual_fill_view_controller.h"
+#import "ios/chrome/browser/ui/autofill/manual_fill/expanded_manual_fill_view_controller+Testing.h"
+
+#import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h"
+#import "testing/platform_test.h"
+
+using manual_fill::ManualFillDataType;
+
+// Test fixture for testing the ExpandedManualFillViewController class.
+class ExpandedManualFillViewControllerTest : public PlatformTest {
+ protected:
+ void SetUp() override {
+ PlatformTest::SetUp();
+
+ InitViewControllerForDataType(ManualFillDataType::kPassword);
+ }
+
+ // Instanciate the view controller for the given `data_type` and load its view
+ // if needed.
+ void InitViewControllerForDataType(ManualFillDataType data_type) {
+ view_controller_ =
+ [[ExpandedManualFillViewController alloc] initForDataType:data_type];
+ [view_controller_ loadViewIfNeeded];
+ }
+
+ // Resets the view controller.
+ void ResetViewController() { view_controller_ = nil; }
+
+ ExpandedManualFillViewController* view_controller() {
+ return view_controller_;
+ }
+
+ private:
+ ExpandedManualFillViewController* view_controller_;
+};
+
+// Tests that the right segmented control segment is selected depending on the
+// data type the view controller is instanciated for.
+TEST_F(ExpandedManualFillViewControllerTest,
+ TestSegmentedControlPreSelectedData) {
+ EXPECT_EQ(view_controller().segmentedControl.selectedSegmentIndex, 0);
+
+ ResetViewController();
+
+ InitViewControllerForDataType(ManualFillDataType::kPaymentMethod);
+ EXPECT_EQ(view_controller().segmentedControl.selectedSegmentIndex, 1);
+
+ ResetViewController();
+
+ InitViewControllerForDataType(ManualFillDataType::kAddress);
+ EXPECT_EQ(view_controller().segmentedControl.selectedSegmentIndex, 2);
+}
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h
index 08c05c4..0308967b 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_constants.h
@@ -24,6 +24,13 @@
// view.
extern NSString* const kExpandedManualFillChromeLogoID;
+// Possible data types when manually filling a form.
+enum class ManualFillDataType {
+ kPassword = 0,
+ kPaymentMethod,
+ kAddress,
+};
+
} // namespace manual_fill
#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_MANUAL_FILL_CONSTANTS_H_