| // Copyright 2019 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_OVERLAYS_OVERLAY_PRESENTATION_CONTEXT_IMPL_H_ |
| #define IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_PRESENTATION_CONTEXT_IMPL_H_ |
| |
| #import <UIKit/UIKit.h> |
| |
| #include "base/memory/weak_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/scoped_observation.h" |
| #include "ios/chrome/browser/overlays/public/overlay_modality.h" |
| #import "ios/chrome/browser/overlays/public/overlay_presentation_context.h" |
| #import "ios/chrome/browser/overlays/public/overlay_user_data.h" |
| #import "ios/chrome/browser/shared/model/browser/browser.h" |
| #import "ios/chrome/browser/shared/model/browser/browser_observer.h" |
| #import "ios/chrome/browser/ui/overlays/overlay_presentation_context_fullscreen_disabler.h" |
| #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h" |
| #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" |
| #import "ios/chrome/browser/ui/overlays/overlay_request_ui_state.h" |
| |
| @class OverlayRequestCoordinatorFactory; |
| @class OverlayPresentationContextCoordinator; |
| @protocol OverlayPresentationContextImplDelegate; |
| |
| // Implementation of OverlayPresentationContext. An instance of this class |
| // exists for every OverlayModality for each Browser. This delegate is scoped |
| // to the Browser because it needs to store state even when a Browser's UI is |
| // not on screen. When a Browser's UI is shown, the view controllers for each |
| // modality are set up. When the presentation context is supplied with a |
| // container or presentation context UIViewController, its presentation |
| // capabilities are updated and supported overlay UI can begin being shown in |
| // the context. |
| class OverlayPresentationContextImpl : public OverlayPresentationContext { |
| public: |
| // Returns the OverlayPresentationContextImpl for `browser` at `modality`. |
| static OverlayPresentationContextImpl* FromBrowser(Browser* browser, |
| OverlayModality modality); |
| |
| ~OverlayPresentationContextImpl() override; |
| |
| // Container that stores the UI delegate for each modality. Usage example: |
| // |
| // OverlayPresentationContextImpl::Container::FromUserData(browser)-> |
| // PresentationContextForModality(OverlayModality::kWebContentArea); |
| class Container : public OverlayUserData<Container> { |
| public: |
| ~Container() override; |
| |
| // Returns the OverlayPresentationContextImpl for `modality`. |
| OverlayPresentationContextImpl* PresentationContextForModality( |
| OverlayModality modality); |
| |
| private: |
| OVERLAY_USER_DATA_SETUP(Container); |
| explicit Container(Browser* browser); |
| |
| Browser* browser_ = nullptr; |
| std::map<OverlayModality, std::unique_ptr<OverlayPresentationContextImpl>> |
| ui_delegates_; |
| }; |
| |
| // The context's delegate. |
| void SetDelegate(id<OverlayPresentationContextImplDelegate> delegate); |
| |
| // The window in which overlay UI will be presented. |
| void SetWindow(UIWindow* window); |
| |
| // The UIViewController used for overlays displayed using child |
| // UIViewControllers. Setting to a new value updates the presentation |
| // capabilities to include kContained. |
| void SetContainerViewController(UIViewController* view_controller); |
| |
| // The UIViewController used for overlays displayed using presented |
| // UIViewControllers. Setting to a new value updates the presentation |
| // capabilities to include kPresented. |
| void SetPresentationContextViewController(UIViewController* view_controller); |
| |
| // OverlayPresentationContext: |
| void AddObserver(OverlayPresentationContextObserver* observer) override; |
| void RemoveObserver(OverlayPresentationContextObserver* observer) override; |
| UIPresentationCapabilities GetPresentationCapabilities() const override; |
| bool CanShowUIForRequest( |
| OverlayRequest* request, |
| UIPresentationCapabilities capabilities) const override; |
| bool CanShowUIForRequest(OverlayRequest* request) const override; |
| bool IsShowingOverlayUI() const override; |
| void PrepareToShowOverlayUI(OverlayRequest* request) override; |
| void ShowOverlayUI(OverlayRequest* request, |
| OverlayPresentationCallback presentation_callback, |
| OverlayDismissalCallback dismissal_callback) override; |
| void HideOverlayUI(OverlayRequest* request) override; |
| void CancelOverlayUI(OverlayRequest* request) override; |
| void SetUIDisabled(bool disabled) override; |
| |
| protected: |
| // Constructor called by the Container to instantiate a presentation context |
| // for `browser` at `modality`, using `factory` to create |
| // OverlayRequestCoordinators. |
| OverlayPresentationContextImpl(Browser* browser, |
| OverlayModality modality, |
| OverlayRequestCoordinatorFactory* factory); |
| |
| private: |
| // Setter for `request_`. Setting to a new value will attempt to |
| // present the UI for `request`. |
| void SetRequest(OverlayRequest* request); |
| |
| // Returns whether `request` uses a child UIViewController. If false, the |
| // request's UI is shown using presentation. |
| bool RequestUsesChildViewController(OverlayRequest* request) const; |
| |
| // Returns the base view controller to use for `request`'s coordinator, or |
| // nullptr if the base has not been provided. `container_view_controller_` is |
| // returned if `request` uses a child UIViewController, and |
| // `presentation_context_view_controller_` is returned if `request` uses |
| // UIViewController presentation. |
| UIViewController* GetBaseViewController(OverlayRequest* request) const; |
| |
| // Returns the UI state for `request`. |
| OverlayRequestUIState* GetRequestUIState(OverlayRequest* request) const; |
| |
| // Returns the presentation capabilities required to show `request`. |
| UIPresentationCapabilities GetRequiredPresentationCapabilities( |
| OverlayRequest* request) const; |
| |
| // Updates the presentation capabilities based on the provided |
| // UIViewControllers. |
| void UpdatePresentationCapabilities(); |
| |
| // Creates the current UIPresentationCapabilities based on the current state. |
| UIPresentationCapabilities ConstructPresentationCapabilities(); |
| |
| // Shows the UI for the presented request using the container coordinator. |
| void ShowUIForPresentedRequest(); |
| |
| // Called when the UI for `request_` has finished being presented. |
| void OverlayUIWasPresented(); |
| |
| // Dismisses the UI for the presented request for `reason`. |
| void DismissPresentedUI(OverlayDismissalReason reason); |
| |
| // Called when the UI for `request_` has finished being dismissed. |
| void OverlayUIWasDismissed(); |
| |
| // Called when the Browser is being destroyed. |
| void BrowserDestroyed(); |
| |
| // Helper object that detaches the UI delegate for Browser shudown. |
| class BrowserShutdownHelper : public BrowserObserver { |
| public: |
| BrowserShutdownHelper(Browser* browser, |
| OverlayPresenter* presenter, |
| OverlayPresentationContextImpl* presentation_context); |
| ~BrowserShutdownHelper() override; |
| |
| // BrowserObserver: |
| void BrowserDestroyed(Browser* browser) override; |
| |
| private: |
| // The presenter whose delegate needs to be reset. |
| OverlayPresenter* presenter_ = nullptr; |
| // OverlayPresentationContextImpl reference. |
| OverlayPresentationContextImpl* presentation_context_ = nullptr; |
| // Scoped observation. |
| base::ScopedObservation<Browser, BrowserObserver> browser_observation_{ |
| this}; |
| }; |
| |
| // Helper object that listens for UI dismissal events. |
| class OverlayRequestCoordinatorDelegateImpl |
| : public OverlayRequestCoordinatorDelegate { |
| public: |
| OverlayRequestCoordinatorDelegateImpl( |
| OverlayPresentationContextImpl* presentation_context); |
| ~OverlayRequestCoordinatorDelegateImpl() override; |
| |
| // OverlayUIDismissalDelegate: |
| void OverlayUIDidFinishPresentation(OverlayRequest* request) override; |
| void OverlayUIDidFinishDismissal(OverlayRequest* request) override; |
| |
| private: |
| OverlayPresentationContextImpl* presentation_context_ = nullptr; |
| }; |
| |
| // The presenter whose UI is being handled by this delegate. |
| OverlayPresenter* presenter_ = nullptr; |
| // The cleanup helper. |
| BrowserShutdownHelper shutdown_helper_; |
| // The delegate used to intercept presentation/dismissal events from |
| // OverlayRequestCoordinators. |
| OverlayRequestCoordinatorDelegateImpl coordinator_delegate_; |
| // The fullscreen disabler helper. |
| OverlayContainerFullscreenDisabler fullscreen_disabler_; |
| // The coordinator factory that provides the UI for the overlays at this |
| // modality. |
| OverlayRequestCoordinatorFactory* coordinator_factory_ = nil; |
| // The context's delegate. |
| __weak id<OverlayPresentationContextImplDelegate> delegate_ = nil; |
| // The window in which overlay UI will be presented. |
| __weak UIWindow* window_ = nil; |
| // The UIViewController used as the base for overlays UI displayed using child |
| // UIViewControllers. |
| __weak UIViewController* container_view_controller_ = nil; |
| // The UIViewController used as the base for overlays displayed using |
| // presented UIViewControllers. |
| __weak UIViewController* presentation_context_view_controller_ = nil; |
| // Whether the UI is temporarily disabled. |
| bool ui_disabled_ = false; |
| // The presentation capabilities of `coordinator_`'s view controller. |
| UIPresentationCapabilities presentation_capabilities_ = |
| UIPresentationCapabilities::kNone; |
| // The request that is currently presented by `presenter_`. When a new |
| // request is presented, the UI state for the request will be added to |
| // `states_`. |
| OverlayRequest* request_ = nullptr; |
| // Map storing the UI state for each OverlayRequest. |
| std::map<OverlayRequest*, std::unique_ptr<OverlayRequestUIState>> states_; |
| base::ObserverList<OverlayPresentationContextObserver, |
| /* check_empty= */ true> |
| observers_; |
| // Weak pointer factory. |
| base::WeakPtrFactory<OverlayPresentationContextImpl> weak_factory_; |
| }; |
| |
| #endif // IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_PRESENTATION_CONTEXT_IMPL_H_ |