Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: content/browser/manifest/manifest_manager_host.cc

Issue 1913043002: Convert ManifestManager IPCs to Mojo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/manifest/manifest_manager_host.h" 5 #include "content/browser/manifest/manifest_manager_host.h"
6 6
7 #include <stdint.h> 7 #include "base/id_map.h"
8 8 #include "content/common/manifest_type_converters.h"
9 #include "base/stl_util.h"
10 #include "content/common/manifest_manager_messages.h"
11 #include "content/public/browser/render_frame_host.h" 9 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/common/manifest.h" 10 #include "content/public/common/manifest.h"
14 #include "content/public/common/result_codes.h" 11 #include "content/public/common/service_registry.h"
15 12
16 namespace content { 13 namespace content {
17 14
18 namespace { 15 class ManifestManagerHost::FrameManifestManagerHost {
16 public:
17 FrameManifestManagerHost(ManifestManagerHost* parent,
18 RenderFrameHost* render_frame_host)
19 : parent_(parent), render_frame_host_(render_frame_host) {
20 render_frame_host->GetServiceRegistry()->ConnectToRemoteService(
21 mojo::GetProxy(&manifest_manager_));
22 manifest_manager_.set_connection_error_handler(base::Bind(
23 &ManifestManagerHost::FrameManifestManagerHost::OnConnectionError,
24 base::Unretained(this)));
25 }
19 26
20 void KillRenderer(RenderFrameHost* render_frame_host) { 27 ~FrameManifestManagerHost() {
21 base::ProcessHandle process_handle = 28 for (GetCallbackMap::const_iterator it(&get_callbacks_); !it.IsAtEnd();
22 render_frame_host->GetProcess()->GetHandle(); 29 it.Advance()) {
23 if (process_handle == base::kNullProcessHandle) 30 it.GetCurrentValue()->Run(Manifest());
24 return; 31 }
25 render_frame_host->GetProcess()->Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, 32 for (HasCallbackMap::const_iterator it(&has_callbacks_); !it.IsAtEnd();
26 false); 33 it.Advance()) {
27 } 34 it.GetCurrentValue()->Run(false);
35 }
36 }
28 37
29 } // anonymous namespace 38 // Calls the given callback with the manifest associated with the
39 // given RenderFrameHost. If the frame has no manifest or if getting it failed
40 // the callback will have an empty manifest.
41 void GetManifest(const GetManifestCallback& callback) {
42 int request_id = get_callbacks_.Add(new GetManifestCallback(callback));
43
44 manifest_manager_->RequestManifest(
45 base::Bind(&ManifestManagerHost::FrameManifestManagerHost::
46 OnRequestManifestResponse,
47 base::Unretained(this), request_id));
48 }
49
50 // Calls the given callback with a bool indicating whether or not the document
51 // associated with the given RenderFrameHost has a manifest.
52 void HasManifest(const HasManifestCallback& callback) {
53 int request_id = has_callbacks_.Add(new HasManifestCallback(callback));
54
55 manifest_manager_->HasManifest(base::Bind(
56 &ManifestManagerHost::FrameManifestManagerHost::OnHasManifestResponse,
57 base::Unretained(this), request_id));
58 }
59
60 private:
61 using GetCallbackMap = IDMap<GetManifestCallback, IDMapOwnPointer>;
62 using HasCallbackMap = IDMap<HasManifestCallback, IDMapOwnPointer>;
63
64 void OnConnectionError() { parent_->RenderFrameDeleted(render_frame_host_); }
65
66 void OnRequestManifestResponse(int request_id,
67 blink::mojom::ManifestPtr manifest) {
68 get_callbacks_.Lookup(request_id)->Run(manifest.To<Manifest>());
69 get_callbacks_.Remove(request_id);
70 DeleteIfIdle();
71 }
72
73 void OnHasManifestResponse(int request_id, bool has_manifest) {
74 has_callbacks_.Lookup(request_id)->Run(has_manifest);
75 has_callbacks_.Remove(request_id);
76 DeleteIfIdle();
77 }
78
79 void DeleteIfIdle() {
80 if (get_callbacks_.IsEmpty() && has_callbacks_.IsEmpty())
81 OnConnectionError();
mlamouri (slow - plz ping) 2016/04/27 13:38:08 OnConnectionError is for deleting? That sounds odd
Sam McNally 2016/04/28 08:25:27 Renamed it to not be specific to connection errors
82 }
83
84 ManifestManagerHost* parent_;
85 RenderFrameHost* render_frame_host_;
86 blink::mojom::ManifestManagerPtr manifest_manager_;
87 GetCallbackMap get_callbacks_;
88 HasCallbackMap has_callbacks_;
89
90 DISALLOW_COPY_AND_ASSIGN(FrameManifestManagerHost);
91 };
30 92
31 ManifestManagerHost::ManifestManagerHost(WebContents* web_contents) 93 ManifestManagerHost::ManifestManagerHost(WebContents* web_contents)
32 : WebContentsObserver(web_contents) { 94 : WebContentsObserver(web_contents) {}
33 }
34 95
35 ManifestManagerHost::~ManifestManagerHost() { 96 ManifestManagerHost::~ManifestManagerHost() = default;
36 STLDeleteValues(&pending_get_callbacks_);
37 STLDeleteValues(&pending_has_callbacks_);
38 }
39
40 ManifestManagerHost::GetCallbackMap*
41 ManifestManagerHost::GetCallbackMapForFrame(
42 RenderFrameHost* render_frame_host) {
43 FrameGetCallbackMap::iterator it =
44 pending_get_callbacks_.find(render_frame_host);
45 return it != pending_get_callbacks_.end() ? it->second : nullptr;
46 }
47
48 ManifestManagerHost::HasCallbackMap*
49 ManifestManagerHost::HasCallbackMapForFrame(
50 RenderFrameHost* render_frame_host) {
51 FrameHasCallbackMap::iterator it =
52 pending_has_callbacks_.find(render_frame_host);
53 return it != pending_has_callbacks_.end() ? it->second : nullptr;
54 }
55 97
56 void ManifestManagerHost::RenderFrameDeleted( 98 void ManifestManagerHost::RenderFrameDeleted(
57 RenderFrameHost* render_frame_host) { 99 RenderFrameHost* render_frame_host) {
58 { 100 hosts_.erase(render_frame_host);
59 GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
60 if (!callbacks)
61 return;
62
63 // Call the callbacks with a failure state before deleting them. Do this in
64 // a block so the iterator is destroyed before |callbacks|.
65 {
66 GetCallbackMap::const_iterator it(callbacks);
67 for (; !it.IsAtEnd(); it.Advance())
68 it.GetCurrentValue()->Run(Manifest());
69 }
70
71 delete callbacks;
72 pending_get_callbacks_.erase(render_frame_host);
73 }
74
75 {
76 HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host);
77 if (!callbacks)
78 return;
79
80 // Call the callbacks with a failure state before deleting them. Do this in
81 // a block so the iterator is destroyed before |callbacks|.
82 {
83 HasCallbackMap::const_iterator it(callbacks);
84 for (; !it.IsAtEnd(); it.Advance())
85 it.GetCurrentValue()->Run(false);
86 }
87
88 delete callbacks;
89 pending_has_callbacks_.erase(render_frame_host);
90 }
91 } 101 }
92 102
93 void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host, 103 void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host,
94 const GetManifestCallback& callback) { 104 const GetManifestCallback& callback) {
95 GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host); 105 GetOrCreateHostForFrame(render_frame_host).GetManifest(callback);
96 if (!callbacks) {
97 callbacks = new GetCallbackMap();
98 pending_get_callbacks_[render_frame_host] = callbacks;
99 }
100
101 int request_id = callbacks->Add(new GetManifestCallback(callback));
102
103 render_frame_host->Send(new ManifestManagerMsg_RequestManifest(
104 render_frame_host->GetRoutingID(), request_id));
105 } 106 }
106 107
107 void ManifestManagerHost::HasManifest(RenderFrameHost* render_frame_host, 108 void ManifestManagerHost::HasManifest(RenderFrameHost* render_frame_host,
108 const HasManifestCallback& callback) { 109 const HasManifestCallback& callback) {
109 HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host); 110 GetOrCreateHostForFrame(render_frame_host).HasManifest(callback);
110 if (!callbacks) {
111 callbacks = new HasCallbackMap();
112 pending_has_callbacks_[render_frame_host] = callbacks;
113 }
114
115 int request_id = callbacks->Add(new HasManifestCallback(callback));
116
117 render_frame_host->Send(new ManifestManagerMsg_HasManifest(
118 render_frame_host->GetRoutingID(), request_id));
119 } 111 }
120 112
121 bool ManifestManagerHost::OnMessageReceived( 113 ManifestManagerHost::FrameManifestManagerHost&
122 const IPC::Message& message, RenderFrameHost* render_frame_host) { 114 ManifestManagerHost::GetOrCreateHostForFrame(
123 bool handled = true; 115 RenderFrameHost* render_frame_host) {
124 116 std::unique_ptr<ManifestManagerHost::FrameManifestManagerHost>& host =
125 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(ManifestManagerHost, message, 117 hosts_[render_frame_host];
126 render_frame_host) 118 if (!host)
127 IPC_MESSAGE_HANDLER(ManifestManagerHostMsg_RequestManifestResponse, 119 host.reset(new FrameManifestManagerHost(this, render_frame_host));
128 OnRequestManifestResponse) 120 return *host;
129 IPC_MESSAGE_HANDLER(ManifestManagerHostMsg_HasManifestResponse,
130 OnHasManifestResponse)
131 IPC_MESSAGE_UNHANDLED(handled = false)
132 IPC_END_MESSAGE_MAP()
133
134 return handled;
135 } 121 }
136 122
137 void ManifestManagerHost::OnRequestManifestResponse( 123 } // namespace content
138 RenderFrameHost* render_frame_host,
139 int request_id,
140 const Manifest& insecure_manifest) {
141 GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
142 if (!callbacks) {
143 DVLOG(1) << "Unexpected RequestManifestResponse to from renderer. "
144 "Killing renderer.";
145 KillRenderer(render_frame_host);
146 return;
147 }
148
149 GetManifestCallback* callback = callbacks->Lookup(request_id);
150 if (!callback) {
151 DVLOG(1) << "Received a request_id (" << request_id << ") from renderer "
152 "with no associated callback. Killing renderer.";
153 KillRenderer(render_frame_host);
154 return;
155 }
156
157 // When receiving a Manifest, the browser process can't trust that it is
158 // coming from a known and secure source. It must be processed accordingly.
159 Manifest manifest = insecure_manifest;
160 manifest.name = base::NullableString16(
161 manifest.name.string().substr(0, Manifest::kMaxIPCStringLength),
162 manifest.name.is_null());
163 manifest.short_name = base::NullableString16(
164 manifest.short_name.string().substr(0, Manifest::kMaxIPCStringLength),
165 manifest.short_name.is_null());
166 if (!manifest.start_url.is_valid())
167 manifest.start_url = GURL();
168 for (auto& icon : manifest.icons) {
169 if (!icon.src.is_valid())
170 icon.src = GURL();
171 icon.type = base::NullableString16(
172 icon.type.string().substr(0, Manifest::kMaxIPCStringLength),
173 icon.type.is_null());
174 }
175 manifest.gcm_sender_id = base::NullableString16(
176 manifest.gcm_sender_id.string().substr(
177 0, Manifest::kMaxIPCStringLength),
178 manifest.gcm_sender_id.is_null());
179 for (auto& related_application : manifest.related_applications) {
180 if (!related_application.url.is_valid())
181 related_application.url = GURL();
182 related_application.id =
183 base::NullableString16(related_application.id.string().substr(
184 0, Manifest::kMaxIPCStringLength),
185 related_application.id.is_null());
186 }
187 // theme_color and background_color are 32 bit unsigned integers with 64 bit
188 // integers simply being used to encode the occurence of an error. Therefore,
189 // any value outside the range of a 32 bit integer is invalid.
190 if (manifest.theme_color < std::numeric_limits<int32_t>::min() ||
191 manifest.theme_color > std::numeric_limits<int32_t>::max())
192 manifest.theme_color = Manifest::kInvalidOrMissingColor;
193 if (manifest.background_color < std::numeric_limits<int32_t>::min() ||
194 manifest.background_color > std::numeric_limits<int32_t>::max())
195 manifest.background_color = Manifest::kInvalidOrMissingColor;
196
197 callback->Run(manifest);
198 callbacks->Remove(request_id);
199 if (callbacks->IsEmpty()) {
200 delete callbacks;
201 pending_get_callbacks_.erase(render_frame_host);
202 }
203 }
204
205 void ManifestManagerHost::OnHasManifestResponse(
206 RenderFrameHost* render_frame_host,
207 int request_id,
208 bool has_manifest) {
209 HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host);
210 if (!callbacks) {
211 DVLOG(1) << "Unexpected HasManifestResponse from renderer. "
212 "Killing renderer.";
213 KillRenderer(render_frame_host);
214 return;
215 }
216
217 HasManifestCallback* callback = callbacks->Lookup(request_id);
218 if (!callback) {
219 DVLOG(1) << "Received a request_id (" << request_id << ") from renderer "
220 "with no associated callback. Killing renderer.";
221 KillRenderer(render_frame_host);
222 return;
223 }
224
225 callback->Run(has_manifest);
226 callbacks->Remove(request_id);
227 if (callbacks->IsEmpty()) {
228 delete callbacks;
229 pending_has_callbacks_.erase(render_frame_host);
230 }
231 }
232
233 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698