Remove tw_wrt.h
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / wrt / wrt_widget_host.cc
1 // Copyright (c) 2014,2015 Samsung Electronics. 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 "wrt_widget_host.h"
6
7 #include "base/lazy_instance.h"
8 #include "common/render_messages_ewk.h"
9 #include "content/public/browser/browser_message_filter.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/resource_request_info.h"
12 #include "ipc/ipc_message_macros.h"
13 #include "net/url_request/url_request.h"
14 #include "url/gurl.h"
15
16 namespace {
17 // TODO(z.kostrzewa) I would prefer not make it a singleton, check out
18 // if it can't be a member of ContentMainDelegateEfl (but keep the static
19 // getter, maybe?).
20 base::LazyInstance<scoped_ptr<WrtWidgetHost> > g_wrt_widget_host =
21     LAZY_INSTANCE_INITIALIZER;
22
23 bool SendToAllRenderers(IPC::Message* message) {
24   bool result = false;
25   content::RenderProcessHost::iterator it =
26       content::RenderProcessHost::AllHostsIterator();
27   while (!it.IsAtEnd()) {
28     if (it.GetCurrentValue()->Send(message))
29       result = true;
30     it.Advance();
31   }
32   return result;
33 }
34
35 bool SendToRenderer(int renderer_id, IPC::Message* message) {
36   return content::RenderProcessHost::FromID(renderer_id)->Send(message);
37 }
38 }
39
40 class WrtWidgetHostMessageFilter : public content::BrowserMessageFilter {
41  public:
42   explicit WrtWidgetHostMessageFilter(WrtWidgetHost* wrt_widget_host);
43
44  private:
45   bool OnMessageReceived(const IPC::Message& message) override;
46
47   WrtWidgetHost* wrt_widget_host_;
48 };
49
50 WrtWidgetHostMessageFilter::WrtWidgetHostMessageFilter(
51     WrtWidgetHost* wrt_widget_host)
52     : content::BrowserMessageFilter(EwkMsgStart),
53       wrt_widget_host_(wrt_widget_host) {
54 }
55
56 bool WrtWidgetHostMessageFilter::OnMessageReceived(const IPC::Message& message) {
57   bool handled = true;
58   IPC_BEGIN_MESSAGE_MAP(WrtWidgetHostMessageFilter, message)
59     IPC_MESSAGE_FORWARD(WrtMsg_ParseUrlResponse, wrt_widget_host_, WrtWidgetHost::OnUrlRetrieved)
60     IPC_MESSAGE_UNHANDLED(handled = false)
61   IPC_END_MESSAGE_MAP()
62   return handled;
63 }
64
65 WrtWidgetHost* WrtWidgetHost::Get() {
66   // TODO(z.kostrzewa) LazyInstance is thread-safe but creating
67   // WrtWidgetHost is not - make it thread-safe.
68   if (!g_wrt_widget_host.Get().get())
69     g_wrt_widget_host.Get().reset(new WrtWidgetHost);
70   return g_wrt_widget_host.Get().get();
71 }
72
73 WrtWidgetHost::WrtWidgetHost()
74     : message_filter_(new WrtWidgetHostMessageFilter(this)),
75       in_wrt_(false),
76       widget_id_(0) {
77 }
78
79 void WrtWidgetHost::GetUrlForRequest(
80     net::URLRequest* request,
81     base::Callback<void(const GURL&)> callback) {
82   // TODO(z.kostrzewa) Check on which thread(s) callbacks_ is touched
83   // and provide synchronization if required (either via a lock or
84   // by assuring that it is referenced only on one thread)
85   int callback_id = callback_id_generator_.GetNext();
86   callbacks_[callback_id] = callback;
87
88   int renderer_id, frame_id;
89   if (content::ResourceRequestInfo::GetRenderFrameForRequest(request, &renderer_id,
90                                                              &frame_id))
91     if (SendToRenderer(renderer_id, new WrtMsg_ParseUrl(callback_id, request->url())))
92       return;
93
94   callbacks_.erase(callback_id);
95   callback.Run(GURL());
96 }
97
98 void WrtWidgetHost::SetWidgetInfo(int widget_id,
99                                   double scale,
100                                   const std::string& theme,
101                                   const std::string& encoded_bundle) {
102   // TODO shouldn't it be confirmed by WRT that this is really a launch
103   // of the widget identified by widget_id?
104   if (SendToAllRenderers(
105           new WrtMsg_SetWidgetInfo(widget_id, scale, theme, encoded_bundle))) {
106     // TODO(z.kostrzewa) This should be determined (somehow) on application
107     // startup. Can it be done via Application Framework/Package Manager?
108     in_wrt_ = true;
109     widget_id_ = widget_id;
110   }
111 }
112
113 void WrtWidgetHost::SendWrtMessage(
114     const Ewk_Wrt_Message_Data& message) {
115   SendToAllRenderers(new WrtMsg_SendWrtMessage(message));
116 }
117
118 bool WrtWidgetHost::InWrt() const {
119   return in_wrt_;
120 }
121
122 int WrtWidgetHost::WidgetId() const {
123   return widget_id_;
124 }
125
126 void WrtWidgetHost::OnUrlRetrieved(int callback_id, const GURL& url) {
127   callbacks_type::iterator it = callbacks_.find(callback_id);
128   if (callbacks_.end() == it)
129     return;
130
131   callbacks_type::mapped_type callback = it->second;
132   callbacks_.erase(callback_id);
133   callback.Run(url);
134 }
135