OLD | NEW |
| (Empty) |
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 "content/browser/intents/intent_injector.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/command_line.h" | |
9 #include "base/file_path.h" | |
10 #include "base/logging.h" | |
11 #include "base/string16.h" | |
12 #include "base/stringprintf.h" | |
13 #include "content/browser/child_process_security_policy_impl.h" | |
14 #include "content/browser/intents/web_intents_dispatcher_impl.h" | |
15 #include "content/browser/renderer_host/render_process_host_impl.h" | |
16 #include "content/browser/renderer_host/render_view_host_impl.h" | |
17 #include "content/browser/web_contents/web_contents_impl.h" | |
18 #include "content/common/intents_messages.h" | |
19 #include "content/public/common/content_switches.h" | |
20 #include "webkit/fileapi/file_system_util.h" | |
21 #include "webkit/fileapi/isolated_context.h" | |
22 #include "webkit/glue/web_intent_data.h" | |
23 #include "webkit/glue/web_intent_reply_data.h" | |
24 | |
25 namespace content { | |
26 | |
27 IntentInjector::IntentInjector(WebContents* web_contents) | |
28 : WebContentsObserver(web_contents), | |
29 intents_dispatcher_(NULL), | |
30 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | |
31 DCHECK(web_contents); | |
32 } | |
33 | |
34 IntentInjector::~IntentInjector() { | |
35 } | |
36 | |
37 void IntentInjector::WebContentsDestroyed(WebContents* contents) { | |
38 if (intents_dispatcher_) { | |
39 intents_dispatcher_->SendReply(webkit_glue::WebIntentReply( | |
40 webkit_glue::WEB_INTENT_SERVICE_CONTENTS_CLOSED, string16())); | |
41 } | |
42 | |
43 delete this; | |
44 } | |
45 | |
46 void IntentInjector::SourceWebContentsDestroyed(WebContents* contents) { | |
47 intents_dispatcher_ = NULL; | |
48 } | |
49 | |
50 void IntentInjector::SetIntent( | |
51 WebIntentsDispatcher* intents_dispatcher, | |
52 const webkit_glue::WebIntentData& intent) { | |
53 intents_dispatcher_ = intents_dispatcher; | |
54 intents_dispatcher_->RegisterReplyNotification( | |
55 base::Bind(&IntentInjector::OnSendReturnMessage, | |
56 weak_factory_.GetWeakPtr())); | |
57 source_intent_.reset(new webkit_glue::WebIntentData(intent)); | |
58 initial_url_ = web_contents()->GetPendingSiteInstance()->GetSiteURL(); | |
59 } | |
60 | |
61 void IntentInjector::Abandon() { | |
62 intents_dispatcher_ = NULL; | |
63 delete this; | |
64 } | |
65 | |
66 void IntentInjector::OnSendReturnMessage( | |
67 webkit_glue::WebIntentReplyType reply_type) { | |
68 intents_dispatcher_ = NULL; | |
69 } | |
70 | |
71 void IntentInjector::RenderViewCreated(RenderViewHost* render_view_host) { | |
72 if (source_intent_.get() == NULL || !web_contents()->GetRenderViewHost()) | |
73 return; | |
74 | |
75 // Only deliver the intent to the renderer if it has the same origin | |
76 // as the initial delivery target. | |
77 if (initial_url_.GetOrigin() != | |
78 render_view_host->GetSiteInstance()->GetSiteURL().GetOrigin()) { | |
79 return; | |
80 } | |
81 | |
82 // If we're passing a browser-originated blob, either directly or as part of a | |
83 // payload, grant read permission on the blob file to the delivered context. | |
84 if (source_intent_->data_type == webkit_glue::WebIntentData::BLOB || | |
85 (source_intent_->data_type == webkit_glue::WebIntentData::MIME_TYPE && | |
86 !source_intent_->blob_file.empty())) { | |
87 const int child_id = render_view_host->GetProcess()->GetID(); | |
88 ChildProcessSecurityPolicy* policy = | |
89 ChildProcessSecurityPolicy::GetInstance(); | |
90 if (!policy->CanReadFile(child_id, source_intent_->blob_file)) | |
91 policy->GrantReadFile(child_id, source_intent_->blob_file); | |
92 } else if (source_intent_->data_type == | |
93 webkit_glue::WebIntentData::FILESYSTEM) { | |
94 const int child_id = render_view_host->GetProcess()->GetID(); | |
95 base::FilePath path; | |
96 const bool valid = | |
97 fileapi::IsolatedContext::GetInstance()->GetRegisteredPath( | |
98 source_intent_->filesystem_id, &path); | |
99 DCHECK(valid); | |
100 ChildProcessSecurityPolicy* policy = | |
101 ChildProcessSecurityPolicy::GetInstance(); | |
102 if (!policy->CanReadFile(child_id, path)) | |
103 policy->GrantReadFile(child_id, path); | |
104 policy->GrantReadFileSystem(child_id, source_intent_->filesystem_id); | |
105 } | |
106 | |
107 render_view_host->Send(new IntentsMsg_SetWebIntentData( | |
108 render_view_host->GetRoutingID(), *(source_intent_.get()))); | |
109 } | |
110 | |
111 bool IntentInjector::OnMessageReceived(const IPC::Message& message) { | |
112 bool handled = true; | |
113 IPC_BEGIN_MESSAGE_MAP(IntentInjector, message) | |
114 IPC_MESSAGE_HANDLER(IntentsHostMsg_WebIntentReply, OnReply); | |
115 IPC_MESSAGE_UNHANDLED(handled = false) | |
116 IPC_END_MESSAGE_MAP() | |
117 return handled; | |
118 } | |
119 | |
120 void IntentInjector::OnReply(const webkit_glue::WebIntentReply& reply) { | |
121 if (!intents_dispatcher_) | |
122 return; | |
123 | |
124 // Ensure SendReplyMessage is only called once. | |
125 WebIntentsDispatcher* intents_dispatcher = intents_dispatcher_; | |
126 intents_dispatcher_ = NULL; | |
127 intents_dispatcher->SendReply(reply); | |
128 } | |
129 | |
130 } // namespace content | |
OLD | NEW |