Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / printing / background_printing_manager.cc
1 // Copyright (c) 2012 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/printing/background_printing_manager.h"
6
7 #include "base/stl_util.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/printing/print_job.h"
10 #include "chrome/browser/printing/print_preview_dialog_controller.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/notification_details.h"
13 #include "content/public/browser/notification_source.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_delegate.h"
17 #include "content/public/browser/web_contents_observer.h"
18
19 using content::BrowserThread;
20 using content::WebContents;
21
22 namespace printing {
23
24 class BackgroundPrintingManager::Observer
25     : public content::WebContentsObserver {
26  public:
27   Observer(BackgroundPrintingManager* manager, WebContents* web_contents);
28
29  private:
30   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
31   virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
32
33   BackgroundPrintingManager* manager_;
34 };
35
36 BackgroundPrintingManager::Observer::Observer(
37     BackgroundPrintingManager* manager, WebContents* web_contents)
38     : content::WebContentsObserver(web_contents),
39       manager_(manager) {
40 }
41
42 void BackgroundPrintingManager::Observer::RenderProcessGone(
43     base::TerminationStatus status) {
44   manager_->DeletePreviewContents(web_contents());
45 }
46 void BackgroundPrintingManager::Observer::WebContentsDestroyed(
47     WebContents* web_contents) {
48   manager_->DeletePreviewContents(web_contents);
49 }
50
51 BackgroundPrintingManager::BackgroundPrintingManager() {
52   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
53 }
54
55 BackgroundPrintingManager::~BackgroundPrintingManager() {
56   DCHECK(CalledOnValidThread());
57   // The might be some WebContentses still in |printing_contents_map_| at this
58   // point (e.g. when the last remaining tab closes and there is still a print
59   // preview WebContents trying to print). In such a case it will fail to print,
60   // but we should at least clean up the observers.
61   // TODO(thestig): Handle this case better.
62   STLDeleteValues(&printing_contents_map_);
63 }
64
65 void BackgroundPrintingManager::OwnPrintPreviewDialog(
66     WebContents* preview_dialog) {
67   DCHECK(CalledOnValidThread());
68   DCHECK(PrintPreviewDialogController::IsPrintPreviewDialog(preview_dialog));
69   CHECK(!HasPrintPreviewDialog(preview_dialog));
70
71   printing_contents_map_[preview_dialog] = new Observer(this, preview_dialog);
72
73   // Watch for print jobs finishing. Everything else is watched for by the
74   // Observer. TODO(avi, cait): finish the job of removing this last
75   // notification.
76   registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED,
77                  content::Source<WebContents>(preview_dialog));
78
79   // Activate the initiator.
80   PrintPreviewDialogController* dialog_controller =
81       PrintPreviewDialogController::GetInstance();
82   if (!dialog_controller)
83     return;
84   WebContents* initiator = dialog_controller->GetInitiator(preview_dialog);
85   if (!initiator)
86     return;
87   initiator->GetDelegate()->ActivateContents(initiator);
88 }
89
90 void BackgroundPrintingManager::Observe(
91     int type,
92     const content::NotificationSource& source,
93     const content::NotificationDetails& details) {
94   DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_RELEASED, type);
95   DeletePreviewContents(content::Source<WebContents>(source).ptr());
96 }
97
98 void BackgroundPrintingManager::DeletePreviewContents(
99     WebContents* preview_contents) {
100   WebContentsObserverMap::iterator i =
101       printing_contents_map_.find(preview_contents);
102   if (i == printing_contents_map_.end()) {
103     // Everyone is racing to be the first to delete the |preview_contents|. If
104     // this case is hit, someone else won the race, so there is no need to
105     // continue. <http://crbug.com/100806>
106     return;
107   }
108
109   // Stop all observation ...
110   registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_RELEASED,
111                     content::Source<WebContents>(preview_contents));
112   Observer* observer = i->second;
113   printing_contents_map_.erase(i);
114   delete observer;
115
116   // ... and mortally wound the contents. (Deletion immediately is not a good
117   // idea in case this was called from RenderViewGone.)
118   base::MessageLoop::current()->DeleteSoon(FROM_HERE, preview_contents);
119 }
120
121 std::set<content::WebContents*> BackgroundPrintingManager::CurrentContentSet() {
122   std::set<content::WebContents*> result;
123   for (WebContentsObserverMap::iterator i = printing_contents_map_.begin();
124        i != printing_contents_map_.end(); ++i) {
125     result.insert(i->first);
126   }
127   return result;
128 }
129
130 bool BackgroundPrintingManager::HasPrintPreviewDialog(
131     WebContents* preview_dialog) {
132   return ContainsKey(printing_contents_map_, preview_dialog);
133 }
134
135 }  // namespace printing