Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / dom_distiller / content / dom_distiller_viewer_source.cc
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 "components/dom_distiller/content/dom_distiller_viewer_source.h"
6
7 #include <sstream>
8 #include <string>
9 #include <vector>
10
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "components/dom_distiller/core/task_tracker.h"
15 #include "components/dom_distiller/core/url_constants.h"
16 #include "components/dom_distiller/core/viewer.h"
17 #include "content/public/browser/render_frame_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "net/url_request/url_request.h"
20
21 namespace dom_distiller {
22
23 // Handles receiving data asynchronously for a specific entry, and passing
24 // it along to the data callback for the data source.
25 class DomDistillerViewerSource::RequestViewerHandle
26     : public ViewRequestDelegate {
27  public:
28   explicit RequestViewerHandle(
29       const content::URLDataSource::GotDataCallback& callback);
30   virtual ~RequestViewerHandle();
31
32   // ViewRequestDelegate implementation.
33   virtual void OnArticleReady(
34       const DistilledArticleProto* article_proto) OVERRIDE;
35
36   virtual void OnArticleUpdated(
37       ArticleDistillationUpdate article_update) OVERRIDE;
38
39   void TakeViewerHandle(scoped_ptr<ViewerHandle> viewer_handle);
40
41  private:
42   // The handle to the view request towards the DomDistillerService. It
43   // needs to be kept around to ensure the distillation request finishes.
44   scoped_ptr<ViewerHandle> viewer_handle_;
45
46   // This holds the callback to where the data retrieved is sent back.
47   content::URLDataSource::GotDataCallback callback_;
48 };
49
50 DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle(
51     const content::URLDataSource::GotDataCallback& callback)
52     : callback_(callback) {
53 }
54
55 DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() {
56 }
57
58 void DomDistillerViewerSource::RequestViewerHandle::OnArticleReady(
59     const DistilledArticleProto* article_proto) {
60   std::string unsafe_page_html = viewer::GetUnsafeHtml(article_proto);
61   callback_.Run(base::RefCountedString::TakeString(&unsafe_page_html));
62   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
63 }
64
65 void DomDistillerViewerSource::RequestViewerHandle::OnArticleUpdated(
66     ArticleDistillationUpdate article_update) {
67   // TODO(nyquist): Add support for displaying pages incrementally.
68 }
69
70 void DomDistillerViewerSource::RequestViewerHandle::TakeViewerHandle(
71     scoped_ptr<ViewerHandle> viewer_handle) {
72   viewer_handle_ = viewer_handle.Pass();
73 }
74
75 DomDistillerViewerSource::DomDistillerViewerSource(
76     DomDistillerServiceInterface* dom_distiller_service,
77     const std::string& scheme)
78     : scheme_(scheme), dom_distiller_service_(dom_distiller_service) {
79 }
80
81 DomDistillerViewerSource::~DomDistillerViewerSource() {
82 }
83
84 std::string DomDistillerViewerSource::GetSource() const {
85   return scheme_ + "://";
86 }
87
88 void DomDistillerViewerSource::StartDataRequest(
89     const std::string& path,
90     int render_process_id,
91     int render_frame_id,
92     const content::URLDataSource::GotDataCallback& callback) {
93   content::RenderFrameHost* render_frame_host =
94       content::RenderFrameHost::FromID(render_process_id, render_frame_id);
95   DCHECK(render_frame_host);
96   content::RenderViewHost* render_view_host =
97       render_frame_host->GetRenderViewHost();
98   DCHECK(render_view_host);
99   CHECK_EQ(0, render_view_host->GetEnabledBindings());
100
101   if (kCssPath == path) {
102     std::string css = viewer::GetCss();
103     callback.Run(base::RefCountedString::TakeString(&css));
104     return;
105   }
106
107   RequestViewerHandle* request_viewer_handle =
108       new RequestViewerHandle(callback);
109   scoped_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest(
110       dom_distiller_service_, path, request_viewer_handle);
111
112   if (viewer_handle) {
113     // The service returned a |ViewerHandle| and guarantees it will call
114     // the |RequestViewerHandle|, so passing ownership to it, to ensure the
115     // request is not cancelled. The |RequestViewerHandle| will delete itself
116     // after receiving the callback.
117     request_viewer_handle->TakeViewerHandle(viewer_handle.Pass());
118   } else {
119     // The service did not return a |ViewerHandle|, which means the
120     // |RequestViewerHandle| will never be called, so clean up now.
121     delete request_viewer_handle;
122
123     std::string error_page_html = viewer::GetErrorPageHtml();
124     callback.Run(base::RefCountedString::TakeString(&error_page_html));
125   }
126 };
127
128 std::string DomDistillerViewerSource::GetMimeType(
129     const std::string& path) const {
130   if (path == kCssPath)
131     return "text/css";
132   return "text/html";
133 }
134
135 bool DomDistillerViewerSource::ShouldServiceRequest(
136     const net::URLRequest* request) const {
137   return request->url().SchemeIs(scheme_.c_str());
138 }
139
140 // TODO(nyquist): Start tracking requests using this method.
141 void DomDistillerViewerSource::WillServiceRequest(
142     const net::URLRequest* request,
143     std::string* path) const {
144 }
145
146 std::string DomDistillerViewerSource::GetContentSecurityPolicyObjectSrc()
147     const {
148   return "object-src 'none'; style-src 'self';";
149 }
150
151 }  // namespace dom_distiller