// Copyright 2012 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_controller.h"

#include "base/files/file_path.h"
#include "base/ios/weak_nsobject.h"
#include "base/location.h"
#include "base/logging.h"
#import "base/mac/bind_objc_block.h"
#include "base/mac/objc_property_releaser.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
#import "ios/chrome/browser/ui/open_in_controller_testing.h"
#include "ios/chrome/browser/ui/ui_util.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ios/web/public/web_thread.h"
#import "ios/web/web_state/ui/crw_web_controller.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/l10n/l10n_util_mac.h"
#import "ui/gfx/ios/NSString+CrStringDrawing.h"
#include "url/gurl.h"

namespace {
// The path in the temp directory containing documents that are to be opened in
// other applications.
static NSString* const kDocumentsTempPath = @"OpenIn";

static const int kHTTPResponseCodeSucceeded = 200;

// Duration of the show/hide animation for the |openInToolbar_|.
const NSTimeInterval kOpenInToolbarAnimationDuration = 0.2;

// Duration to show or hide the |overlayedView_|.
const NSTimeInterval kOverlayViewAnimationDuration = 0.3;

// Time interval after which the |openInToolbar_| is automatically hidden.
const NSTimeInterval kOpenInToolbarDisplayDuration = 2.0;

// Text size used for the label indicating a download in progress.
const CGFloat kLabelTextSize = 22.0;

// Alpha value for the background view of |overlayedView_|.
const CGFloat kOverlayedViewBackgroundAlpha = 0.6;

// Width of the label displayed on the |overlayedView_| as a percentage of the
// |overlayedView_|'s width.
const CGFloat kOverlayedViewLabelWidthPercentage = 0.7;

// Bottom margin for the label displayed on the |overlayedView_|.
const CGFloat kOverlayedViewLabelBottomMargin = 60;

}  // anonymous namespace

@interface OpenInController () {
  // AlertCoordinator for showing an alert if no applications were found to open
  // the current document.
  base::scoped_nsobject<AlertCoordinator> _alertCoordinator;
}

// URLFetcher delegate method called when |fetcher_| completes a request.
- (void)urlFetchDidComplete:(const net::URLFetcher*)source;
// Ensures the destination directory is created and any contained obsolete files
// are deleted. Returns YES if the directory is created successfully.
+ (BOOL)createDestinationDirectoryAndRemoveObsoleteFiles;
// Starts downloading the file at path |kDocumentsTempPath| with the name
// |suggestedFilename_|.
- (void)startDownload;
// Shows the overlayed toolbar |openInToolbar_|.
- (void)showOpenInToolbar;
// Hides the overlayed toolbar |openInToolbar_|.
- (void)hideOpenInToolbar;
// Called when there is a tap on the |webController_|'s view to display the
// overlayed toolbar |openInToolbar_| if necessary and (re)schedule the
// |openInTimer_|.
- (void)handleTapFrom:(UIGestureRecognizer*)gestureRecognizer;
// Downloads the file at |documentURL_| and presents the OpenIn menu for opening
// it in other applications.
- (void)exportFileWithOpenInMenuAnchoredAt:(id)sender;
// Called when there is a tap on the |overlayedView_| to cancel the file
// download.
- (void)handleTapOnOverlayedView:(UIGestureRecognizer*)gestureRecognizer;
// Removes |overlayedView_| from the top view of the application.
- (void)removeOverlayedView;
// Shows an alert with the given error message.
- (void)showErrorWithMessage:(NSString*)message;
// Presents the OpenIn menu for the file at |fileURL|.
- (void)presentOpenInMenuForFileAtURL:(NSURL*)fileURL;
// Removes the file at path |path|.
- (void)removeDocumentAtPath:(NSString*)path;
// Removes all the stored files at path |path|.
+ (void)removeAllStoredDocumentsAtPath:(NSString*)path;
// Shows an overlayed spinner on the top view to indicate that a file download
// is in progress.
- (void)showDownloadOverlayView;
// Returns a toolbar with an "Open in..." button to be overlayed on a document
// on tap.
- (UIToolbar*)openInToolbar;
@end

// Bridge to deliver method calls from C++ to the |OpenInController| class.
class OpenInControllerBridge
    : public net::URLFetcherDelegate,
      public base::RefCountedThreadSafe<OpenInControllerBridge> {
 public:
  explicit OpenInControllerBridge(OpenInController* owner) : owner_(owner) {}

  void OnURLFetchComplete(const net::URLFetcher* source) override {
    DCHECK(owner_);
    [owner_ urlFetchDidComplete:source];
  }

  BOOL CreateDestinationDirectoryAndRemoveObsoleteFiles(void) {
    return [OpenInController createDestinationDirectoryAndRemoveObsoleteFiles];
  }

  void OnDestinationDirectoryCreated(BOOL success) {
    DCHECK_CURRENTLY_ON(web::WebThread::UI);
    if (!success)
      [owner_ hideOpenInToolbar];
    else
      [owner_ startDownload];
  }

  void OnOwnerDisabled() {
    // When the owner is disabled:
    // - if there is a task in flight posted via |PostTaskAndReplyWithResult|
    // then dereferencing |bridge_| will not release it as |bridge_| is also
    // referenced by the task posting; setting |owner_| to nil makes sure that
    // no methods are called on it, and it works since |owner_| is only used on
    // the main thread.
    // - if there is a task in flight posted by the URLFetcher then
    // |OpenInController| destroys the fetcher and cancels the callback. This is
    // why |OnURLFetchComplete| will neved be called after |owner_| is disabled.
    owner_ = nil;
  }

 protected:
  friend base::RefCountedThreadSafe<OpenInControllerBridge>;
  ~OpenInControllerBridge() override {}

 private:
  OpenInController* owner_;  // weak
};

@implementation OpenInController {
  // Bridge from C++ to Obj-C class.
  scoped_refptr<OpenInControllerBridge> bridge_;

  // URL of the document.
  GURL documentURL_;

  // Controller for opening documents in other applications.
  base::scoped_nsobject<UIDocumentInteractionController> documentController_;

  // Toolbar overlay to be displayed on tap.
  base::scoped_nsobject<OpenInToolbar> openInToolbar_;

  // Timer used to automatically hide the |openInToolbar_| after a period.
  base::scoped_nsobject<NSTimer> openInTimer_;

  // Gesture recognizer to catch taps on the document.
  base::scoped_nsobject<UITapGestureRecognizer> tapRecognizer_;

  // Suggested filename for the document.
  base::scoped_nsobject<NSString> suggestedFilename_;

  // Fetcher used to redownload the document and save it in the sandbox.
  std::unique_ptr<net::URLFetcher> fetcher_;

  // CRWWebController used to check if the tap is not on a link and the
  // |openInToolbar_| should be displayed.
  base::scoped_nsobject<CRWWebController> webController_;

  // URLRequestContextGetter needed for the URLFetcher.
  scoped_refptr<net::URLRequestContextGetter> requestContext_;

  // Spinner view displayed while the file is downloading.
  base::scoped_nsobject<UIView> overlayedView_;

  // The location where the "Open in..." menu is anchored.
  CGRect anchorLocation_;

  // YES if the file download was canceled.
  BOOL downloadCanceled_;

  // YES if the OpenIn menu is displayed.
  BOOL isOpenInMenuDisplayed_;

  // Task runner on which file operations should happen.
  scoped_refptr<base::SequencedTaskRunner> sequencedTaskRunner_;

  base::mac::ObjCPropertyReleaser propertyReleaser_OpenInController_;
}

- (id)initWithRequestContext:(net::URLRequestContextGetter*)requestContext
               webController:(CRWWebController*)webController {
  self = [super init];
  if (self) {
    requestContext_ = requestContext;
    webController_.reset([webController retain]);
    tapRecognizer_.reset([[UITapGestureRecognizer alloc]
        initWithTarget:self
                action:@selector(handleTapFrom:)]);
    [tapRecognizer_ setDelegate:self];
    base::SequencedWorkerPool* pool = web::WebThread::GetBlockingPool();
    sequencedTaskRunner_ =
        pool->GetSequencedTaskRunner(pool->GetSequenceToken());
    isOpenInMenuDisplayed_ = NO;
    propertyReleaser_OpenInController_.Init(self, [OpenInController class]);
  }
  return self;
}

- (void)enableWithDocumentURL:(const GURL&)documentURL
            suggestedFilename:(NSString*)suggestedFilename {
  documentURL_ = GURL(documentURL);
  suggestedFilename_.reset([suggestedFilename retain]);
  [webController_ addGestureRecognizerToWebView:tapRecognizer_];
  [self openInToolbar].alpha = 0.0f;
  [webController_ addToolbarViewToWebView:[self openInToolbar]];
}

- (void)disable {
  [self openInToolbar].alpha = 0.0f;
  [openInTimer_ invalidate];
  if (bridge_.get())
    bridge_->OnOwnerDisabled();
  bridge_ = nil;
  [webController_ removeGestureRecognizerFromWebView:tapRecognizer_];
  [webController_ removeToolbarViewFromWebView:[self openInToolbar]];
  [documentController_ dismissMenuAnimated:NO];
  [documentController_ setDelegate:nil];
  documentURL_ = GURL();
  suggestedFilename_.reset();
  fetcher_.reset();
}

- (void)detachFromWebController {
  [self disable];
  // Animation blocks may be keeping this object alive; don't extend the
  // lifetime of CRWWebController.
  webController_.reset();
}

- (void)dealloc {
  [self disable];
  [super dealloc];
}

- (void)handleTapFrom:(UIGestureRecognizer*)gestureRecognizer {
  if ([gestureRecognizer state] == UIGestureRecognizerStateEnded) {
    [self showOpenInToolbar];
  }
}

- (void)showOpenInToolbar {
  if ([openInTimer_ isValid]) {
    [openInTimer_ setFireDate:([NSDate dateWithTimeIntervalSinceNow:
                                           kOpenInToolbarDisplayDuration])];
  } else {
    openInTimer_.reset(
        [[NSTimer scheduledTimerWithTimeInterval:kOpenInToolbarDisplayDuration
                                          target:self
                                        selector:@selector(hideOpenInToolbar)
                                        userInfo:nil
                                         repeats:NO] retain]);
    UIView* openInToolbar = [self openInToolbar];
    [UIView animateWithDuration:kOpenInToolbarAnimationDuration
                     animations:^{
                       [openInToolbar setAlpha:1.0];
                     }];
  }
}

- (void)hideOpenInToolbar {
  if (!openInToolbar_)
    return;
  UIView* openInToolbar = [self openInToolbar];
  [UIView animateWithDuration:kOpenInToolbarAnimationDuration
                   animations:^{
                     [openInToolbar setAlpha:0.0];
                   }];
}

- (void)exportFileWithOpenInMenuAnchoredAt:(UIView*)view {
  DCHECK([view isKindOfClass:[UIView class]]);
  DCHECK_CURRENTLY_ON(web::WebThread::UI);
  if (!webController_)
    return;

  anchorLocation_ = [[self openInToolbar] convertRect:view.frame
                                               toView:[webController_ view]];
  [openInTimer_ invalidate];
  if (!bridge_.get())
    bridge_ = new OpenInControllerBridge(self);

  // This needs to be done in two steps, on two separate threads. The
  // first task needs to be done on the worker pool and returns a BOOL which is
  // then used in the second function, |OnDestinationDirectoryCreated|, which
  // runs on the UI thread.
  base::Callback<BOOL(void)> task = base::Bind(
      &OpenInControllerBridge::CreateDestinationDirectoryAndRemoveObsoleteFiles,
      bridge_);
  base::Callback<void(BOOL)> reply = base::Bind(
      &OpenInControllerBridge::OnDestinationDirectoryCreated, bridge_);
  base::PostTaskAndReplyWithResult(sequencedTaskRunner_.get(), FROM_HERE, task,
                                   reply);
}

- (void)startDownload {
  NSString* tempDirPath = [NSTemporaryDirectory()
      stringByAppendingPathComponent:kDocumentsTempPath];
  NSString* filePath =
      [tempDirPath stringByAppendingPathComponent:suggestedFilename_.get()];

  // In iPad the toolbar has to be displayed to anchor the "Open in" menu.
  if (!IsIPadIdiom())
    [self hideOpenInToolbar];

  // Show an overlayed view to indicate a download is in progress. On tap this
  // view can be dismissed and the download canceled.
  [self showDownloadOverlayView];
  downloadCanceled_ = NO;

  // Ensure |bridge_| is set in case this function is called from a unittest.
  if (!bridge_.get())
    bridge_ = new OpenInControllerBridge(self);

  // Download the document and save it at |filePath|.
  fetcher_ = net::URLFetcher::Create(0, documentURL_, net::URLFetcher::GET,
                                     bridge_.get());
  fetcher_->SetRequestContext(requestContext_.get());
  fetcher_->SetLoadFlags(net::LOAD_SKIP_CACHE_VALIDATION);
  fetcher_->SaveResponseToFileAtPath(
      base::FilePath(base::SysNSStringToUTF8(filePath)), sequencedTaskRunner_);
  fetcher_->Start();
}

- (void)handleTapOnOverlayedView:(UIGestureRecognizer*)gestureRecognizer {
  if ([gestureRecognizer state] != UIGestureRecognizerStateEnded)
    return;

  [self removeOverlayedView];
  if (IsIPadIdiom())
    [self hideOpenInToolbar];
  downloadCanceled_ = YES;
}

- (void)removeOverlayedView {
  if (!overlayedView_)
    return;

  UIView* overlayedView = overlayedView_.get();
  [UIView animateWithDuration:kOverlayViewAnimationDuration
      animations:^{
        [overlayedView setAlpha:0.0];
      }
      completion:^(BOOL finished) {
        [overlayedView removeFromSuperview];
      }];
  overlayedView_.reset();
}

- (void)showErrorWithMessage:(NSString*)message {
  UIViewController* topViewController =
      [[[UIApplication sharedApplication] keyWindow] rootViewController];

  _alertCoordinator.reset([[AlertCoordinator alloc]
      initWithBaseViewController:topViewController
                           title:nil
                         message:message]);

  [_alertCoordinator addItemWithTitle:l10n_util::GetNSString(IDS_OK)
                               action:nil
                                style:UIAlertActionStyleDefault];

  [_alertCoordinator start];
}

- (void)presentOpenInMenuForFileAtURL:(NSURL*)fileURL {
  if (!webController_)
    return;

  if (requestContext_.get()) {
    // |requestContext_| is nil only if this is called from a unit test, in
    // which case the |documentController_| was set already.
    documentController_.reset([[UIDocumentInteractionController
        interactionControllerWithURL:fileURL] retain]);
  }

  // TODO(cgrigoruta): The UTI is hardcoded for now, change this when we add
  // support for other file types as well.
  [documentController_ setUTI:@"com.adobe.pdf"];
  [documentController_ setDelegate:self];
  BOOL success =
      [documentController_ presentOpenInMenuFromRect:anchorLocation_
                                              inView:[webController_ view]
                                            animated:YES];
  if (requestContext_.get()) {
    [self removeOverlayedView];
    if (!success) {
      if (IsIPadIdiom())
        [self hideOpenInToolbar];
      NSString* errorMessage =
          l10n_util::GetNSStringWithFixup(IDS_IOS_OPEN_IN_NO_APPS_REGISTERED);
      [self showErrorWithMessage:errorMessage];
    } else {
      isOpenInMenuDisplayed_ = YES;
    }
  }
}

- (void)showDownloadOverlayView {
  UIViewController* topViewController =
      [[[UIApplication sharedApplication] keyWindow] rootViewController];
  UIView* topView = topViewController.view;
  overlayedView_.reset([[UIView alloc] initWithFrame:[topView bounds]]);
  [overlayedView_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
                                       UIViewAutoresizingFlexibleHeight)];
  base::scoped_nsobject<UIView> grayBackgroundView(
      [[UIView alloc] initWithFrame:[overlayedView_ frame]]);
  [grayBackgroundView setBackgroundColor:[UIColor darkGrayColor]];
  [grayBackgroundView setAlpha:kOverlayedViewBackgroundAlpha];
  [grayBackgroundView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
                                           UIViewAutoresizingFlexibleHeight)];
  [overlayedView_ addSubview:grayBackgroundView];

  base::scoped_nsobject<UIActivityIndicatorView> spinner([
      [UIActivityIndicatorView alloc]
      initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]);
  [spinner setFrame:[overlayedView_ frame]];
  [spinner setHidesWhenStopped:YES];
  [spinner setUserInteractionEnabled:NO];
  [spinner startAnimating];
  [spinner setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
                                UIViewAutoresizingFlexibleHeight)];
  [overlayedView_ addSubview:spinner];

  base::scoped_nsobject<UILabel> label([[UILabel alloc] init]);
  [label setTextColor:[UIColor whiteColor]];
  [label setFont:GetUIFont(FONT_HELVETICA, true, kLabelTextSize)];
  [label setNumberOfLines:0];
  [label setShadowColor:[UIColor blackColor]];
  [label setShadowOffset:CGSizeMake(0.0, 1.0)];
  [label setBackgroundColor:[UIColor clearColor]];
  [label setText:l10n_util::GetNSString(IDS_IOS_OPEN_IN_FILE_DOWNLOAD_CANCEL)];
  [label setLineBreakMode:NSLineBreakByWordWrapping];
  [label setTextAlignment:NSTextAlignmentCenter];
  CGFloat labelWidth =
      [overlayedView_ frame].size.width * kOverlayedViewLabelWidthPercentage;
  CGFloat originX = ([overlayedView_ frame].size.width - labelWidth) / 2;

  CGFloat labelHeight =
      [[label text] cr_boundingSizeWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX)
                                       font:[label font]]
          .height;
  CGFloat originY =
      [overlayedView_ center].y - labelHeight - kOverlayedViewLabelBottomMargin;
  [label setFrame:CGRectMake(originX, originY, labelWidth, labelHeight)];
  [overlayedView_ addSubview:label];

  base::scoped_nsobject<UITapGestureRecognizer> tapRecognizer(
      [[UITapGestureRecognizer alloc]
          initWithTarget:self
                  action:@selector(handleTapOnOverlayedView:)]);
  [tapRecognizer setDelegate:self];
  [overlayedView_ addGestureRecognizer:tapRecognizer];

  [overlayedView_ setAlpha:0.0];
  [topView addSubview:overlayedView_];
  UIView* overlayedView = overlayedView_.get();
  [UIView animateWithDuration:kOverlayViewAnimationDuration
                   animations:^{
                     [overlayedView setAlpha:1.0];
                   }];
}

- (UIView*)openInToolbar {
  if (!openInToolbar_) {
    openInToolbar_.reset([[OpenInToolbar alloc]
        initWithTarget:self
                action:@selector(exportFileWithOpenInMenuAnchoredAt:)]);
  }
  return openInToolbar_.get();
}

#pragma mark -
#pragma mark File management

- (void)removeDocumentAtPath:(NSString*)path {
  base::ThreadRestrictions::AssertIOAllowed();
  NSFileManager* fileManager = [NSFileManager defaultManager];
  NSError* error = nil;
  if (![fileManager removeItemAtPath:path error:&error]) {
    DLOG(ERROR) << "Failed to remove file: "
                << base::SysNSStringToUTF8([error description]);
  }
}

+ (void)removeAllStoredDocumentsAtPath:(NSString*)tempDirPath {
  base::ThreadRestrictions::AssertIOAllowed();
  NSFileManager* fileManager = [NSFileManager defaultManager];
  NSError* error = nil;
  NSArray* documentFiles =
      [fileManager contentsOfDirectoryAtPath:tempDirPath error:&error];
  if (!documentFiles) {
    DLOG(ERROR) << "Failed to get content of directory at path: "
                << base::SysNSStringToUTF8([error description]);
    return;
  }

  for (NSString* filename in documentFiles) {
    NSString* filePath = [tempDirPath stringByAppendingPathComponent:filename];
    if (![fileManager removeItemAtPath:filePath error:&error]) {
      DLOG(ERROR) << "Failed to remove file: "
                  << base::SysNSStringToUTF8([error description]);
    }
  }
}

+ (BOOL)createDestinationDirectoryAndRemoveObsoleteFiles {
  base::ThreadRestrictions::AssertIOAllowed();
  NSString* tempDirPath = [NSTemporaryDirectory()
      stringByAppendingPathComponent:kDocumentsTempPath];
  NSFileManager* fileManager = [NSFileManager defaultManager];
  BOOL isDirectory;
  NSError* error = nil;
  if (![fileManager fileExistsAtPath:tempDirPath isDirectory:&isDirectory]) {
    BOOL created = [fileManager createDirectoryAtPath:tempDirPath
                          withIntermediateDirectories:YES
                                           attributes:nil
                                                error:&error];
    DCHECK(created);
    if (!created) {
      DLOG(ERROR) << "Error creating destination dir: "
                  << base::SysNSStringToUTF8([error description]);
      return NO;
    }
  } else {
    DCHECK(isDirectory);
    if (!isDirectory) {
      DLOG(ERROR) << "Destination Directory already exists and is a file.";
      return NO;
    }
    // Remove all documents that might be still on temporary storage.
    [self removeAllStoredDocumentsAtPath:(NSString*)tempDirPath];
  }
  return YES;
}

#pragma mark -
#pragma mark URLFetcher delegate method

- (void)urlFetchDidComplete:(const net::URLFetcher*)fetcher {
  DCHECK(fetcher);
  if (requestContext_.get())
    DCHECK_CURRENTLY_ON(web::WebThread::UI);
  base::FilePath filePath;
  if (fetcher->GetResponseCode() == kHTTPResponseCodeSucceeded &&
      fetcher->GetResponseAsFilePath(true, &filePath)) {
    NSURL* fileURL =
        [NSURL fileURLWithPath:base::SysUTF8ToNSString(filePath.value())];
    if (downloadCanceled_) {
      sequencedTaskRunner_->PostTask(FROM_HERE, base::BindBlock(^{
                                       [self
                                           removeDocumentAtPath:[fileURL path]];
                                     }));
    } else {
      [self presentOpenInMenuForFileAtURL:fileURL];
    }
  } else if (!downloadCanceled_) {
    if (IsIPadIdiom())
      [self hideOpenInToolbar];
    [self removeOverlayedView];
    [self showErrorWithMessage:l10n_util::GetNSStringWithFixup(
                                   IDS_IOS_OPEN_IN_FILE_DOWNLOAD_FAILED)];
  }
}

#pragma mark -
#pragma mark UIDocumentInteractionControllerDelegate Methods

- (void)documentInteractionController:(UIDocumentInteractionController*)contr
           didEndSendingToApplication:(NSString*)application {
  sequencedTaskRunner_->PostTask(FROM_HERE, base::BindBlock(^{
                                   [self
                                       removeDocumentAtPath:[[contr URL] path]];
                                 }));
  if (IsIPadIdiom()) {
    // Call the |documentInteractionControllerDidDismissOpenInMenu:| method
    // as this is not called on the iPad after the document has been opened
    // in another application.
    [self documentInteractionControllerDidDismissOpenInMenu:contr];
  }
}

- (void)documentInteractionControllerDidDismissOpenInMenu:
    (UIDocumentInteractionController*)controller {
  if (!IsIPadIdiom()) {
    isOpenInMenuDisplayed_ = NO;
    // On the iPhone the |openInToolber_| is hidden already.
    return;
  }

  // On iPad this method is called whenever the device changes orientation,
  // even thought the OpenIn menu is not displayed. To distinguish the cases
  // when this method is called after the OpenIn menu is dismissed, we
  // check the BOOL |isOpenInMenuDisplayed|.
  if (isOpenInMenuDisplayed_) {
    openInTimer_.reset(
        [[NSTimer scheduledTimerWithTimeInterval:kOpenInToolbarDisplayDuration
                                          target:self
                                        selector:@selector(hideOpenInToolbar)
                                        userInfo:nil
                                         repeats:NO] retain]);
  }
  isOpenInMenuDisplayed_ = NO;
}

#pragma mark -
#pragma mark UIGestureRecognizerDelegate Methods

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer {
  if ([gestureRecognizer.view isEqual:overlayedView_])
    return YES;

  CGPoint location = [gestureRecognizer locationInView:[self openInToolbar]];
  return ![[self openInToolbar] pointInside:location withEvent:nil];
}

#pragma mark - TestingAditions

- (void)setDocumentInteractionController:
    (UIDocumentInteractionController*)controller {
  documentController_.reset([controller retain]);
}

- (NSString*)suggestedFilename {
  return suggestedFilename_.get();
}

@end
