1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/views/frame/web_contents_close_handler.h"
6
7#include "chrome/browser/ui/views/frame/web_contents_close_handler_delegate.h"
8
9WebContentsCloseHandler::WebContentsCloseHandler(
10    WebContentsCloseHandlerDelegate* delegate)
11    : delegate_(delegate),
12      in_close_(false),
13      tab_changed_after_clone_(false) {
14}
15
16WebContentsCloseHandler::~WebContentsCloseHandler() {
17}
18
19void WebContentsCloseHandler::TabInserted() {
20  // Tests may end up reviving a TabStrip that is empty.
21  if (!in_close_)
22    return;
23  in_close_ = false;
24  delegate_->DestroyClonedLayer();
25}
26
27void WebContentsCloseHandler::ActiveTabChanged() {
28  if (in_close_)
29    tab_changed_after_clone_ = true;
30  else
31    delegate_->DestroyClonedLayer();
32}
33
34void WebContentsCloseHandler::WillCloseAllTabs() {
35  DCHECK(!in_close_);
36  in_close_ = true;
37  tab_changed_after_clone_ = false;
38  delegate_->CloneWebContentsLayer();
39  timer_.Stop();
40}
41
42void WebContentsCloseHandler::CloseAllTabsCanceled() {
43  DCHECK(in_close_);
44  in_close_ = false;
45  if (tab_changed_after_clone_) {
46    // If the tab changed, destroy immediately. That way we make sure we aren't
47    // showing the wrong thing.
48    delegate_->DestroyClonedLayer();
49  } else {
50    // The most common reason for a close to be canceled is a before unload
51    // handler. Often times the tab still ends up closing, but only after we get
52    // back a response from the renderer. Assume this is going to happen and
53    // keep around the cloned layer for a bit more time.
54    timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(500),
55                 this, &WebContentsCloseHandler::OnStillHaventClosed);
56  }
57}
58
59void WebContentsCloseHandler::OnStillHaventClosed() {
60  delegate_->DestroyClonedLayer();
61}
62