chromium/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_default_browser_promo_coordinator.mm

// Copyright 2023 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/content_suggestions/set_up_list/set_up_list_default_browser_promo_coordinator.h"

#import "base/ios/block_types.h"
#import "base/metrics/histogram_functions.h"
#import "base/metrics/user_metrics.h"
#import "base/metrics/user_metrics_action.h"
#import "components/feature_engagement/public/tracker.h"
#import "components/segmentation_platform/public/segmentation_platform_service.h"
#import "ios/chrome/browser/default_browser/model/utils.h"
#import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
#import "ios/chrome/browser/first_run/ui_bundled/default_browser/default_browser_screen_view_controller.h"
#import "ios/chrome/browser/ntp/model/set_up_list_item_type.h"
#import "ios/chrome/browser/ntp/model/set_up_list_prefs.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/browser/browser.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_default_browser_promo_coordinator_delegate.h"
#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_default_browser_promo_mediator.h"

using base::RecordAction;
using base::UmaHistogramEnumeration;
using base::UserMetricsAction;

@implementation SetUpListDefaultBrowserPromoCoordinator {
  // The view controller that displays the default browser promo.
  DefaultBrowserScreenViewController* _viewController;

  // Application is used to open the OS settings for this app.
  UIApplication* _application;

  // Whether or not the Set Up List Item should be marked complete.
  BOOL _markItemComplete;

  raw_ptr<segmentation_platform::DeviceSwitcherResultDispatcher>
      _deviceSwitcherResultDispatcher;
  raw_ptr<segmentation_platform::SegmentationPlatformService>
      _segmentationService;
  SetUpListDefaultBrowserPromoMediator* _mediator;

  // TODO: (crbug.com/357867254) Transparent view to block user interaction
  // while waiting for classification results. This ivar is a temporary
  // solution.
  UIView* _transparentView;
}

- (instancetype)initWithBaseViewController:(UIViewController*)viewController
                                   browser:(Browser*)browser
                               application:(UIApplication*)application
                       segmentationService:
                           (segmentation_platform::SegmentationPlatformService*)
                               segmentationService
            deviceSwitcherResultDispatcher:
                (segmentation_platform::DeviceSwitcherResultDispatcher*)
                    dispatcher {
  self = [super initWithBaseViewController:viewController browser:browser];
  if (self) {
    _application = application;
    _segmentationService = segmentationService;
    _deviceSwitcherResultDispatcher = dispatcher;
  }
  return self;
}

#pragma mark - ChromeCoordinator

- (void)start {
  RecordAction(UserMetricsAction("IOS.DefaultBrowserPromo.SetUpList.Appear"));
  [self recordDefaultBrowserPromoShown];

  if (IsSegmentedDefaultBrowserPromoEnabled()) {
    CHECK(_segmentationService);
    CHECK(_deviceSwitcherResultDispatcher);
    _mediator = [[SetUpListDefaultBrowserPromoMediator alloc]
           initWithSegmentationService:_segmentationService
        deviceSwitcherResultDispatcher:_deviceSwitcherResultDispatcher];

    // Present a transparent view to block UI interaction until promo presents.
    _transparentView =
        [[UIView alloc] initWithFrame:self.baseViewController.view.bounds];
    _transparentView.backgroundColor = [UIColor clearColor];
    [self.baseViewController.view addSubview:_transparentView];

    __weak __typeof(self) weakSelf = self;
    [_mediator retrieveUserSegmentWithCompletion:^{
      [weakSelf showPromo];
    }];
  } else {
    [self showPromo];
  }
}

- (void)stop {
  _viewController.presentationController.delegate = nil;

  ProceduralBlock completion = nil;
  if (_markItemComplete) {
    PrefService* localState = GetApplicationContext()->GetLocalState();
    completion = ^{
      set_up_list_prefs::MarkItemComplete(localState,
                                          SetUpListItemType::kDefaultBrowser);
    };
  }
  [_viewController dismissViewControllerAnimated:YES completion:completion];
  _viewController.delegate = nil;
  _application = nil;
  _transparentView = nil;
  _segmentationService = nullptr;
  _deviceSwitcherResultDispatcher = nullptr;
  _mediator.consumer = nil;
  [_mediator disconnect];
  _mediator = nil;
  _viewController = nil;
  self.delegate = nil;
}

#pragma mark - PromoStyleViewControllerDelegate

- (void)didTapPrimaryActionButton {
  RecordDefaultBrowserPromoLastAction(
      IOSDefaultBrowserPromoAction::kActionButton);
  RecordAction(UserMetricsAction("IOS.DefaultBrowserPromo.SetUpList.Accepted"));
  [self logDefaultBrowserFullscreenPromoHistogramForAction:
            IOSDefaultBrowserPromoAction::kActionButton];
  [_application openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]
                options:{}
      completionHandler:nil];
  _markItemComplete = YES;
  [self.delegate setUpListDefaultBrowserPromoDidFinish:YES];
}

- (void)didTapSecondaryActionButton {
  RecordDefaultBrowserPromoLastAction(IOSDefaultBrowserPromoAction::kCancel);
  RecordAction(UserMetricsAction("IOS.DefaultBrowserPromo.SetUpList.Dismiss"));
  [self logDefaultBrowserFullscreenPromoHistogramForAction:
            IOSDefaultBrowserPromoAction::kCancel];
  _markItemComplete = YES;
  [self.delegate setUpListDefaultBrowserPromoDidFinish:NO];
}

#pragma mark - UIAdaptivePresentationControllerDelegate

- (void)presentationControllerDidDismiss:
    (UIPresentationController*)presentationController {
  RecordDefaultBrowserPromoLastAction(IOSDefaultBrowserPromoAction::kDismiss);
  RecordAction(UserMetricsAction("IOS.DefaultBrowserPromo.SetUpList.Dismiss"));
  [self logDefaultBrowserFullscreenPromoHistogramForAction:
            IOSDefaultBrowserPromoAction::kCancel];
  [self.delegate setUpListDefaultBrowserPromoDidFinish:NO];
}

#pragma mark - Metrics Helpers

- (void)logDefaultBrowserFullscreenPromoHistogramForAction:
    (IOSDefaultBrowserPromoAction)action {
  UmaHistogramEnumeration("IOS.DefaultBrowserPromo.SetUpList.Action", action);
}

#pragma mark - Private

// Records that a default browser promo has been shown.
- (void)recordDefaultBrowserPromoShown {
  ChromeBrowserState* browserState = self.browser->GetBrowserState();
  LogToFETDefaultBrowserPromoShown(
      feature_engagement::TrackerFactory::GetForBrowserState(browserState));
}

// Presents the default browser promo.
- (void)showPromo {
  [_transparentView removeFromSuperview];
  _transparentView = nil;
  _viewController = [[DefaultBrowserScreenViewController alloc] init];
  _viewController.delegate = self;
  if (IsSegmentedDefaultBrowserPromoEnabled()) {
    _mediator.consumer = _viewController;
  }
  [self.baseViewController presentViewController:_viewController
                                        animated:YES
                                      completion:nil];
  _viewController.presentationController.delegate = self;
}

@end