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.
5 #include "wrt_widget_host.h"
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 "ipc_message_start_ewk.h"
14 #include "net/url_request/url_request.h"
18 // TODO(z.kostrzewa) I would prefer not make it a singleton, check out
19 // if it can't be a member of ContentMainDelegateEfl (but keep the static
21 base::LazyInstance<scoped_ptr<WrtWidgetHost> > g_wrt_widget_host =
22 LAZY_INSTANCE_INITIALIZER;
24 bool SendToAllRenderers(IPC::Message* message) {
26 content::RenderProcessHost::iterator it =
27 content::RenderProcessHost::AllHostsIterator();
28 while (!it.IsAtEnd()) {
29 if (it.GetCurrentValue()->Send(message))
36 bool SendToRenderer(int renderer_id, IPC::Message* message) {
37 return content::RenderProcessHost::FromID(renderer_id)->Send(message);
41 class WrtWidgetHostMessageFilter : public content::BrowserMessageFilter {
43 explicit WrtWidgetHostMessageFilter(WrtWidgetHost* wrt_widget_host);
46 bool OnMessageReceived(const IPC::Message& message) override;
48 WrtWidgetHost* wrt_widget_host_;
51 WrtWidgetHostMessageFilter::WrtWidgetHostMessageFilter(
52 WrtWidgetHost* wrt_widget_host)
53 : content::BrowserMessageFilter(EwkMsgStart),
54 wrt_widget_host_(wrt_widget_host) {
57 bool WrtWidgetHostMessageFilter::OnMessageReceived(const IPC::Message& message) {
59 IPC_BEGIN_MESSAGE_MAP(WrtWidgetHostMessageFilter, message)
60 IPC_MESSAGE_FORWARD(WrtMsg_ParseUrlResponse, wrt_widget_host_, WrtWidgetHost::OnUrlRetrieved)
61 IPC_MESSAGE_UNHANDLED(handled = false)
66 WrtWidgetHost* WrtWidgetHost::Get() {
67 // TODO(z.kostrzewa) LazyInstance is thread-safe but creating
68 // WrtWidgetHost is not - make it thread-safe.
69 if (!g_wrt_widget_host.Get().get())
70 g_wrt_widget_host.Get().reset(new WrtWidgetHost);
71 return g_wrt_widget_host.Get().get();
74 WrtWidgetHost::WrtWidgetHost()
75 : message_filter_(new WrtWidgetHostMessageFilter(this)),
80 void WrtWidgetHost::GetUrlForRequest(
81 net::URLRequest* request,
82 base::Callback<void(const GURL&)> callback) {
83 // TODO(z.kostrzewa) Check on which thread(s) callbacks_ is touched
84 // and provide synchronization if required (either via a lock or
85 // by assuring that it is referenced only on one thread)
86 int callback_id = callback_id_generator_.GetNext();
87 callbacks_[callback_id] = callback;
89 int renderer_id, frame_id;
90 if (content::ResourceRequestInfo::GetRenderFrameForRequest(request, &renderer_id,
92 if (SendToRenderer(renderer_id, new WrtMsg_ParseUrl(callback_id, request->url())))
95 callbacks_.erase(callback_id);
99 void WrtWidgetHost::SetWidgetInfo(int widget_id,
101 const std::string& theme,
102 const std::string& encoded_bundle) {
103 // TODO shouldn't it be confirmed by WRT that this is really a launch
104 // of the widget identified by widget_id?
105 if (SendToAllRenderers(
106 new WrtMsg_SetWidgetInfo(widget_id, scale, theme, encoded_bundle))) {
107 // TODO(z.kostrzewa) This should be determined (somehow) on application
108 // startup. Can it be done via Application Framework/Package Manager?
110 widget_id_ = widget_id;
114 void WrtWidgetHost::SendWrtMessage(
115 const Ewk_Wrt_Message_Data& message) {
116 SendToAllRenderers(new WrtMsg_SendWrtMessage(message));
119 bool WrtWidgetHost::InWrt() const {
123 int WrtWidgetHost::WidgetId() const {
127 void WrtWidgetHost::OnUrlRetrieved(int callback_id, const GURL& url) {
128 callbacks_type::iterator it = callbacks_.find(callback_id);
129 if (callbacks_.end() == it)
132 callbacks_type::mapped_type callback = it->second;
133 callbacks_.erase(callback_id);