OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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 "content/renderer/introducer_dispatcher.h" |
| 6 |
| 7 #include "base/id_map.h" |
| 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "content/common/introducer_messages.h" |
| 10 #include "content/common/webmessageportchannel_impl.h" |
| 11 #include "content/renderer/render_view_observer.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMStringList.h" |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntroducer.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntroducerAcceptCa
llback.h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntroducerCallback
.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntroducerConnectC
allback.h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebIntroducerInstallC
allback.h" |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" |
| 24 |
| 25 class ConnectCallback : public WebKit::WebIntroducerCallback { |
| 26 public: |
| 27 ConnectCallback(WebKit::WebMessagePortChannel* service, |
| 28 const WebKit::WebElement& anchor, |
| 29 WebKit::WebIntroducerConnectCallback* callback) : |
| 30 service_(service), |
| 31 anchor_(anchor), |
| 32 callback_(callback), |
| 33 navigated_(false) {} |
| 34 virtual ~ConnectCallback() {} |
| 35 |
| 36 void handleEvent(const WebKit::WebDOMStringList& agreed) { |
| 37 if (0 == agreed.length()) { |
| 38 service_->destroy(); |
| 39 service_ = NULL; |
| 40 } |
| 41 callback_->handleEvent(service_, agreed, navigated_); |
| 42 } |
| 43 |
| 44 void navigate(const GURL& src) { |
| 45 WebKit::WebFrame* frame = WebKit::WebFrame::fromFrameOwnerElement(anchor_); |
| 46 if (frame) { |
| 47 frame->loadRequest(WebKit::WebURLRequest(src)); |
| 48 navigated_ = true; |
| 49 } |
| 50 } |
| 51 |
| 52 private: |
| 53 WebKit::WebMessagePortChannel* service_; |
| 54 WebKit::WebElement anchor_; |
| 55 scoped_ptr<WebKit::WebIntroducerConnectCallback> callback_; |
| 56 bool navigated_; |
| 57 |
| 58 DISALLOW_COPY_AND_ASSIGN(ConnectCallback); |
| 59 }; |
| 60 |
| 61 class AcceptCallback : public WebKit::WebIntroducerCallback { |
| 62 public: |
| 63 AcceptCallback(WebKit::WebMessagePortChannel* customer, |
| 64 WebKit::WebIntroducerAcceptCallback* callback) : |
| 65 customer_(customer), |
| 66 callback_(callback) {} |
| 67 virtual ~AcceptCallback() {} |
| 68 |
| 69 void handleEvent(const WebKit::WebString& origin, |
| 70 const WebKit::WebDOMStringList& wanted) { |
| 71 if (0 == wanted.length()) { |
| 72 customer_->destroy(); |
| 73 customer_ = NULL; |
| 74 } else { |
| 75 callback_->handleEvent(customer_, origin, wanted); |
| 76 } |
| 77 } |
| 78 |
| 79 private: |
| 80 WebKit::WebMessagePortChannel* customer_; |
| 81 scoped_ptr<WebKit::WebIntroducerAcceptCallback> callback_; |
| 82 |
| 83 DISALLOW_COPY_AND_ASSIGN(AcceptCallback); |
| 84 }; |
| 85 |
| 86 class IntroducerDispatcher : public RenderViewObserver, |
| 87 public WebKit::WebIntroducer { |
| 88 public: |
| 89 explicit IntroducerDispatcher(RenderView* render_view) |
| 90 : RenderViewObserver(render_view) {} |
| 91 virtual ~IntroducerDispatcher() {} |
| 92 |
| 93 virtual void install(const WebKit::WebSecurityOrigin& origin, |
| 94 const WebKit::WebURL& icon, |
| 95 const WebKit::WebString& name, |
| 96 const WebKit::WebURL& home, |
| 97 WebKit::WebIntroducerInstallCallback* callback) { |
| 98 Send(new IntroducerHostMsg_Install(routing_id(), pending_.Add(callback), |
| 99 origin.toString().utf8(), |
| 100 icon, name, home)); |
| 101 } |
| 102 void OnInstallReturn(int request_id, bool done) { |
| 103 WebKit::WebIntroducerCallback* cb = pending_.Lookup(request_id); |
| 104 if (cb) { |
| 105 static_cast<WebKit::WebIntroducerInstallCallback*>(cb)->handleEvent(done); |
| 106 } |
| 107 pending_.Remove(request_id); |
| 108 } |
| 109 virtual void uninstall(const WebKit::WebSecurityOrigin& origin) { |
| 110 Send(new IntroducerHostMsg_Uninstall(routing_id(), pending_.Add(NULL), |
| 111 origin.toString().utf8())); |
| 112 } |
| 113 virtual void offer(const WebKit::WebSecurityOrigin& origin, |
| 114 const WebKit::WebString& id, |
| 115 const WebKit::WebString& label, |
| 116 const WebKit::WebDOMStringList& supports, |
| 117 const WebKit::WebURL& window, |
| 118 const WebKit::WebURL& frame) { |
| 119 IntroducerHostMsg_Offer_Params args; |
| 120 args.id = id.utf8(); |
| 121 args.label = label; |
| 122 args.supports.reserve(supports.length()); |
| 123 for (unsigned i = 0, end = supports.length(); i != end; ++i) { |
| 124 args.supports.push_back(supports.item(i).utf8()); |
| 125 } |
| 126 args.window = window; |
| 127 args.frame = frame; |
| 128 Send(new IntroducerHostMsg_Offer(routing_id(), pending_.Add(NULL), |
| 129 origin.toString().utf8(), args)); |
| 130 } |
| 131 virtual void rescind(const WebKit::WebSecurityOrigin& origin, |
| 132 const WebKit::WebString& id) { |
| 133 Send(new IntroducerHostMsg_Rescind(routing_id(), pending_.Add(NULL), |
| 134 origin.toString().utf8(), id.utf8())); |
| 135 } |
| 136 virtual void connect(const WebKit::WebSecurityOrigin& origin, |
| 137 const WebKit::WebElement& anchor, |
| 138 const WebKit::WebDOMStringList& wanted, |
| 139 WebKit::WebIntroducerConnectCallback* callback) { |
| 140 std::vector<std::string> wanted_arg; |
| 141 wanted_arg.reserve(wanted.length()); |
| 142 for (unsigned i = 0, end = wanted.length(); i != end; ++i) { |
| 143 wanted_arg.push_back(wanted.item(i).utf8()); |
| 144 } |
| 145 WebMessagePortChannelImpl* service = new WebMessagePortChannelImpl(); |
| 146 WebKit::WebFrame* frame = WebKit::WebFrame::fromFrameOwnerElement(anchor); |
| 147 Send(new IntroducerHostMsg_Connect(routing_id(), |
| 148 pending_.Add(new ConnectCallback(service, anchor, callback)), |
| 149 origin.toString().utf8(), |
| 150 frame ? frame->identifier() : 0, |
| 151 wanted_arg, |
| 152 service->message_port_id())); |
| 153 } |
| 154 void OnConnectNavigation(int request_id, const GURL& src) { |
| 155 WebKit::WebIntroducerCallback* cb = pending_.Lookup(request_id); |
| 156 if (cb) { |
| 157 static_cast<ConnectCallback*>(cb)->navigate(src); |
| 158 } |
| 159 } |
| 160 void OnConnectReturn(int request_id, const std::vector<std::string>& agreed) { |
| 161 WebKit::WebIntroducerCallback* cb = pending_.Lookup(request_id); |
| 162 if (cb) { |
| 163 WebKit::WebDOMStringList web_agreed; |
| 164 for (std::vector<std::string>::const_iterator i = agreed.begin(), |
| 165 end = agreed.end(); |
| 166 i != end; ++i) { |
| 167 web_agreed.append(WebKit::WebString::fromUTF8(*i)); |
| 168 } |
| 169 static_cast<ConnectCallback*>(cb)->handleEvent(web_agreed); |
| 170 } |
| 171 pending_.Remove(request_id); |
| 172 } |
| 173 virtual void accept(const WebKit::WebSecurityOrigin& origin, |
| 174 const WebKit::WebString& registrant, |
| 175 WebKit::WebIntroducerAcceptCallback* callback) { |
| 176 WebMessagePortChannelImpl* customer = new WebMessagePortChannelImpl(); |
| 177 WebKit::WebFrame* frame = WebKit::WebFrame::frameForCurrentContext(); |
| 178 Send(new IntroducerHostMsg_Accept(routing_id(), |
| 179 pending_.Add(new AcceptCallback(customer, callback)), |
| 180 frame->parent() ? frame->identifier() : 0, |
| 181 registrant.utf8(), |
| 182 customer->message_port_id())); |
| 183 } |
| 184 void OnAcceptReturn(int request_id, |
| 185 const std::string& origin, |
| 186 const std::vector<std::string>& wanted) { |
| 187 WebKit::WebIntroducerCallback* cb = pending_.Lookup(request_id); |
| 188 if (cb) { |
| 189 WebKit::WebDOMStringList web_wanted; |
| 190 for (std::vector<std::string>::const_iterator i = wanted.begin(), |
| 191 end = wanted.end(); |
| 192 i != end; ++i) { |
| 193 web_wanted.append(WebKit::WebString::fromUTF8(*i)); |
| 194 } |
| 195 static_cast<AcceptCallback*>(cb)->handleEvent( |
| 196 WebKit::WebString::fromUTF8(origin), web_wanted); |
| 197 } |
| 198 pending_.Remove(request_id); |
| 199 } |
| 200 |
| 201 virtual bool OnMessageReceived(const IPC::Message& message) { |
| 202 bool handled = true; |
| 203 IPC_BEGIN_MESSAGE_MAP(IntroducerDispatcher, message) |
| 204 IPC_MESSAGE_HANDLER(IntroducerMsg_AcceptReturn, OnAcceptReturn); |
| 205 IPC_MESSAGE_HANDLER(IntroducerMsg_ConnectNavigation, OnConnectNavigation); |
| 206 IPC_MESSAGE_HANDLER(IntroducerMsg_ConnectReturn, OnConnectReturn); |
| 207 IPC_MESSAGE_HANDLER(IntroducerMsg_InstallReturn, OnInstallReturn); |
| 208 IPC_MESSAGE_UNHANDLED(handled = false) |
| 209 IPC_END_MESSAGE_MAP() |
| 210 return handled; |
| 211 } |
| 212 |
| 213 private: |
| 214 IDMap<WebKit::WebIntroducerCallback,IDMapOwnPointer> pending_; |
| 215 |
| 216 DISALLOW_COPY_AND_ASSIGN(IntroducerDispatcher); |
| 217 }; |
| 218 |
| 219 WebKit::WebIntroducer* makeIntroducerDispatcher(RenderView* render_view) { |
| 220 return new IntroducerDispatcher(render_view); |
| 221 } |
OLD | NEW |