0

[iOS] Dismiss the parent access bottom sheet with gesture & keyboard

This CL allows dismissing the bottom sheet by:
- accessibility gesture
- pressing escape key (e.g. with physical keyboard)

Change-Id: I1e620f1a68ee7babeb97cda44d765aab72176108
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6429648
Commit-Queue: Duong Dac <ddac@chromium.org>
Reviewed-by: Louis Romero <lpromero@google.com>
Cr-Commit-Position: refs/heads/main@{#1442640}
This commit is contained in:
Duong Dac
2025-04-04 02:47:35 -07:00
committed by Chromium LUCI CQ
parent 1f79413865
commit deaf006c44
5 changed files with 49 additions and 8 deletions

@@ -157,7 +157,8 @@
#pragma mark - ParentAccessBottomSheetViewControllerPresentationDelegate #pragma mark - ParentAccessBottomSheetViewControllerPresentationDelegate
- (void)closeButtonTapped:(ParentAccessBottomSheetViewController*)controller { - (void)closeBottomSheetRequested:
(ParentAccessBottomSheetViewController*)controller {
[self hideParentAccessBottomSheetWithResult:supervised_user:: [self hideParentAccessBottomSheetWithResult:supervised_user::
LocalApprovalResult::kCanceled LocalApprovalResult::kCanceled
errorType:std::nullopt]; errorType:std::nullopt];

@@ -798,10 +798,22 @@ static const char* kInterstitialDetails = "Details";
waitForUIElementToDisappearWithMatcher: waitForUIElementToDisappearWithMatcher:
grey_accessibilityID(kParentAccessViewAccessibilityIdentifier)]; grey_accessibilityID(kParentAccessViewAccessibilityIdentifier)];
// Reopen the local web approval bottom sheet.
[ChromeEarlGrey tapWebStateElementWithID:@"local-approvals-button"];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:
grey_accessibilityID(kParentAccessViewAccessibilityIdentifier)];
// Close the bottom sheet by keyboard.
[ChromeEarlGrey simulatePhysicalKeyboardEvent:@"escape" flags:0];
[ChromeEarlGrey
waitForUIElementToDisappearWithMatcher:
grey_accessibilityID(kParentAccessViewAccessibilityIdentifier)];
// Verify that metrics are recorded on bottom sheet dismissal. // Verify that metrics are recorded on bottom sheet dismissal.
GREYAssertNil( GREYAssertNil(
[MetricsAppInterface [MetricsAppInterface
expectUniqueSampleWithCount:1 expectUniqueSampleWithCount:2
forBucket:static_cast<int>( forBucket:static_cast<int>(
supervised_user::LocalApprovalResult:: supervised_user::LocalApprovalResult::
kCanceled) kCanceled)
@@ -809,7 +821,7 @@ static const char* kInterstitialDetails = "Details";
@"Unexpected value for local web approval result histogram."); @"Unexpected value for local web approval result histogram.");
GREYAssertNil( GREYAssertNil(
[MetricsAppInterface [MetricsAppInterface
expectTotalCount:1 expectTotalCount:2
forHistogram:@"FamilyLinkUser.LocalWebApprovalResult"], forHistogram:@"FamilyLinkUser.LocalWebApprovalResult"],
@"Unexpected total count for local web approval result histogram."); @"Unexpected total count for local web approval result histogram.");
GREYAssertNil( GREYAssertNil(

@@ -12,6 +12,7 @@ source_set("ui") {
deps = [ deps = [
":constants", ":constants",
"//components/strings:components_strings_grit", "//components/strings:components_strings_grit",
"//ios/chrome/browser/keyboard/ui_bundled",
"//ios/chrome/browser/shared/ui/bottom_sheet:bottom_sheet_view_controller", "//ios/chrome/browser/shared/ui/bottom_sheet:bottom_sheet_view_controller",
"//ios/chrome/browser/shared/ui/symbols", "//ios/chrome/browser/shared/ui/symbols",
"//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/shared/ui/util",

@@ -6,6 +6,7 @@
#import "base/functional/callback.h" #import "base/functional/callback.h"
#import "components/strings/grit/components_strings.h" #import "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/keyboard/ui_bundled/UIKeyCommand+Chrome.h"
#import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
#import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/supervised_user/ui/constants.h" #import "ios/chrome/browser/supervised_user/ui/constants.h"
@@ -114,6 +115,30 @@ UIImage* CloseButtonImage(BOOL highlighted) {
} }
} }
#pragma mark - UIAccessibilityAction
// Dismiss the bottom sheet via the escape accessibility gesture.
- (BOOL)accessibilityPerformEscape {
[self closeBottomSheetRequested];
return YES;
}
#pragma mark - UIResponder
// To always be able to register key commands via -keyCommands, the VC must be
// able to become first responder.
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (NSArray<UIKeyCommand*>*)keyCommands {
return @[ UIKeyCommand.cr_close ];
}
- (void)keyCommand_close {
[self closeBottomSheetRequested];
}
#pragma mark - Private #pragma mark - Private
// Returns a custom detent between the medium and large detents. // Returns a custom detent between the medium and large detents.
@@ -145,10 +170,10 @@ UIImage* CloseButtonImage(BOOL highlighted) {
kCustomBottomSheetDetentIdentifier; kCustomBottomSheetDetentIdentifier;
} }
- (void)closeButtonTapped { - (void)closeBottomSheetRequested {
// Hide the WebView to prevent a white flash in dark mode. // Hide the WebView to prevent a white flash in dark mode.
[self setWebViewHidden:YES]; [self setWebViewHidden:YES];
[self.presentationDelegate closeButtonTapped:self]; [self.presentationDelegate closeBottomSheetRequested:self];
} }
// Creates, initializes, and adds `_closeButton` to the bottom sheet. // Creates, initializes, and adds `_closeButton` to the bottom sheet.
@@ -164,7 +189,7 @@ UIImage* CloseButtonImage(BOOL highlighted) {
_closeButton = [UIButton _closeButton = [UIButton
buttonWithConfiguration:closeButtonConfiguration buttonWithConfiguration:closeButtonConfiguration
primaryAction:[UIAction actionWithHandler:^(UIAction* action) { primaryAction:[UIAction actionWithHandler:^(UIAction* action) {
[weakSelf closeButtonTapped]; [weakSelf closeBottomSheetRequested];
}]]; }]];
_closeButton.translatesAutoresizingMaskIntoConstraints = NO; _closeButton.translatesAutoresizingMaskIntoConstraints = NO;

@@ -10,8 +10,10 @@
// Delegate for presentation events related to the Parent Access bottom sheet. // Delegate for presentation events related to the Parent Access bottom sheet.
@protocol ParentAccessBottomSheetViewControllerPresentationDelegate <NSObject> @protocol ParentAccessBottomSheetViewControllerPresentationDelegate <NSObject>
// Called when the user taps on the Close (X) button. // Called when the bottom sheet receives a dismiss signal (e.g., (x) button,
- (void)closeButtonTapped:(ParentAccessBottomSheetViewController*)controller; // accessibility gesture, or escape key)
- (void)closeBottomSheetRequested:
(ParentAccessBottomSheetViewController*)controller;
@end @end