blob: c44b25cf612665d1ee8724f739c53d7a98e50556 [file] [log] [blame]
// Copyright 2019 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/open_in/open_in_mediator.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/open_in/open_in_tab_helper.h"
#import "ios/chrome/browser/ui/open_in/open_in_controller.h"
#include "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
#import "ios/web/public/browser_state.h"
#import "ios/web/public/web_state.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface OpenInMediator () <WebStateListObserving> {
std::unique_ptr<WebStateListObserverBridge> _webStateListObserver;
// A map associating webStates with their OpenInControllers.
std::map<web::WebState*, OpenInController*> _openInControllersForWebStates;
}
// The Browser that accesses the WebStateList.
@property(nonatomic, assign) Browser* browser;
// The WebStateList that this mediator listens for newly added Webstates.
@property(nonatomic, assign) WebStateList* webStateList;
// The base view controller from which to present UI.
@property(nonatomic, weak) UIViewController* baseViewController;
@end
@implementation OpenInMediator
- (instancetype)initWithBaseViewController:(UIViewController*)baseViewController
browser:(Browser*)browser {
self = [super init];
if (self) {
_baseViewController = baseViewController;
_browser = browser;
_webStateList = browser->GetWebStateList();
// Set the delegates for all existing webstates in the |_webStateList|.
for (int i = 0; i < _webStateList->count(); i++) {
web::WebState* webState = _webStateList->GetWebStateAt(i);
OpenInTabHelper::FromWebState(webState)->SetDelegate(self);
}
_webStateListObserver = std::make_unique<WebStateListObserverBridge>(self);
_webStateList->AddObserver(_webStateListObserver.get());
}
return self;
}
- (void)dealloc {
[self disconnect];
}
- (void)disableAll {
for (const auto& element : _openInControllersForWebStates)
[element.second disable];
_openInControllersForWebStates.clear();
}
- (void)disconnect {
if (_webStateList) {
_webStateList->RemoveObserver(_webStateListObserver.get());
_webStateListObserver.reset();
_webStateList = nullptr;
}
[self disableAll];
}
#pragma mark - WebStateListObserver
- (void)webStateList:(WebStateList*)webStateList
didInsertWebState:(web::WebState*)webState
atIndex:(int)index
activating:(BOOL)activating {
DCHECK_EQ(_webStateList, webStateList);
OpenInTabHelper::FromWebState(webState)->SetDelegate(self);
}
#pragma mark - OpenInTabHelperDelegate
// Creates OpenInController and set its base view to the |webState| view. Then
// enables the OpenIn view for the |webState|.
- (void)enableOpenInForWebState:(web::WebState*)webState
withDocumentURL:(const GURL&)documentURL
suggestedFileName:(NSString*)suggestedFileName {
if (!_openInControllersForWebStates[webState]) {
OpenInController* openInController = [[OpenInController alloc]
initWithBaseViewController:_baseViewController
URLLoaderFactory:webState->GetBrowserState()
->GetSharedURLLoaderFactory()
webState:webState];
openInController.browser = _browser;
_openInControllersForWebStates[webState] = openInController;
}
OpenInController* controller = _openInControllersForWebStates[webState];
controller.baseView = webState->GetView();
[controller enableWithDocumentURL:documentURL
suggestedFilename:suggestedFileName];
}
// Disables the openIn view for the |webState|.
- (void)disableOpenInForWebState:(web::WebState*)webState {
if (_openInControllersForWebStates[webState])
[_openInControllersForWebStates[webState] disable];
}
// Detaches the webState from its' OpenInController.
- (void)destroyOpenInForWebState:(web::WebState*)webState {
if (!_openInControllersForWebStates[webState])
return;
[_openInControllersForWebStates[webState] detachFromWebState];
_openInControllersForWebStates.erase(webState);
}
@end