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

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, 6 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
9 #include "base/stl_util.h"
10 #include "content/common/manifest_manager_messages.h"
11 #include "content/public/browser/render_frame_host.h" 8 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/common/manifest.h" 9 #include "content/public/common/manifest.h"
14 #include "content/public/common/result_codes.h" 10 #include "content/public/common/service_registry.h"
15 11
16 namespace content { 12 namespace content {
17 13
18 namespace { 14 class ManifestManagerHost::FrameManifestManagerHost {
15 public:
16 FrameManifestManagerHost(ManifestManagerHost* owner,
17 RenderFrameHost* render_frame_host)
18 : owner_(owner), render_frame_host_(render_frame_host) {
19 render_frame_host->GetServiceRegistry()->ConnectToRemoteService(
20 mojo::GetProxy(&manifest_manager_));
21 manifest_manager_.set_connection_error_handler(
22 base::Bind(&ManifestManagerHost::FrameManifestManagerHost::DeleteThis,
23 base::Unretained(this)));
24 }
19 25
20 void KillRenderer(RenderFrameHost* render_frame_host) { 26 ~FrameManifestManagerHost() {
21 base::ProcessHandle process_handle = 27 for (GetCallbackMap::const_iterator it(&get_callbacks_); !it.IsAtEnd();
22 render_frame_host->GetProcess()->GetHandle(); 28 it.Advance()) {
23 if (process_handle == base::kNullProcessHandle) 29 it.GetCurrentValue()->Run(Manifest());
24 return; 30 }
25 render_frame_host->GetProcess()->Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE, 31 for (HasCallbackMap::const_iterator it(&has_callbacks_); !it.IsAtEnd();
26 false); 32 it.Advance()) {
27 } 33 it.GetCurrentValue()->Run(false);
34 }
35 }
28 36
29 } // anonymous namespace 37 // Calls the given callback with the manifest associated with the
38 // given RenderFrameHost. If the frame has no manifest or if getting it failed
39 // the callback will have an empty manifest.
40 void GetManifest(const GetManifestCallback& callback) {
41 int request_id = get_callbacks_.Add(new GetManifestCallback(callback));
42
43 manifest_manager_->RequestManifest(
44 base::Bind(&ManifestManagerHost::FrameManifestManagerHost::
45 OnRequestManifestResponse,
46 base::Unretained(this), request_id));
47 }
48
49 // Calls the given callback with a bool indicating whether or not the document
50 // associated with the given RenderFrameHost has a manifest.
51 void HasManifest(const HasManifestCallback& callback) {
52 int request_id = has_callbacks_.Add(new HasManifestCallback(callback));
53
54 manifest_manager_->HasManifest(base::Bind(
55 &ManifestManagerHost::FrameManifestManagerHost::OnHasManifestResponse,
56 base::Unretained(this), request_id));
57 }
58
59 private:
60 using GetCallbackMap = IDMap<GetManifestCallback, IDMapOwnPointer>;
61 using HasCallbackMap = IDMap<HasManifestCallback, IDMapOwnPointer>;
62
63 void DeleteThis() { owner_->RenderFrameDeleted(render_frame_host_); }
64
65 void OnRequestManifestResponse(int request_id, const Manifest& manifest) {
66 get_callbacks_.Lookup(request_id)->Run(manifest);
67 get_callbacks_.Remove(request_id);
68 DeleteIfIdle();
69 }
70
71 void OnHasManifestResponse(int request_id, bool has_manifest) {
72 has_callbacks_.Lookup(request_id)->Run(has_manifest);
73 has_callbacks_.Remove(request_id);
74 DeleteIfIdle();
75 }
76
77 void DeleteIfIdle() {
78 if (get_callbacks_.IsEmpty() && has_callbacks_.IsEmpty())
79 DeleteThis();
80 }
81
82 ManifestManagerHost* owner_;
83 RenderFrameHost* render_frame_host_;
84 blink::mojom::ManifestManagerPtr manifest_manager_;
85 GetCallbackMap get_callbacks_;
86 HasCallbackMap has_callbacks_;
87
88 DISALLOW_COPY_AND_ASSIGN(FrameManifestManagerHost);
89 };
30 90
31 ManifestManagerHost::ManifestManagerHost(WebContents* web_contents) 91 ManifestManagerHost::ManifestManagerHost(WebContents* web_contents)
32 : WebContentsObserver(web_contents) { 92 : WebContentsObserver(web_contents) {}
33 }
34 93
35 ManifestManagerHost::~ManifestManagerHost() { 94 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 95
56 void ManifestManagerHost::RenderFrameDeleted( 96 void ManifestManagerHost::RenderFrameDeleted(
57 RenderFrameHost* render_frame_host) { 97 RenderFrameHost* render_frame_host) {
58 { 98 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 } 99 }
92 100
93 void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host, 101 void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host,
94 const GetManifestCallback& callback) { 102 const GetManifestCallback& callback) {
95 GetCallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host); 103 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 } 104 }
106 105
107 void ManifestManagerHost::HasManifest(RenderFrameHost* render_frame_host, 106 void ManifestManagerHost::HasManifest(RenderFrameHost* render_frame_host,
108 const HasManifestCallback& callback) { 107 const HasManifestCallback& callback) {
109 HasCallbackMap* callbacks = HasCallbackMapForFrame(render_frame_host); 108 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 } 109 }
120 110
121 bool ManifestManagerHost::OnMessageReceived( 111 ManifestManagerHost::FrameManifestManagerHost&
122 const IPC::Message& message, RenderFrameHost* render_frame_host) { 112 ManifestManagerHost::GetOrCreateHostForFrame(
123 bool handled = true; 113 RenderFrameHost* render_frame_host) {
124 114 std::unique_ptr<ManifestManagerHost::FrameManifestManagerHost>& host =
125 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(ManifestManagerHost, message, 115 hosts_[render_frame_host];
126 render_frame_host) 116 if (!host)
127 IPC_MESSAGE_HANDLER(ManifestManagerHostMsg_RequestManifestResponse, 117 host.reset(new FrameManifestManagerHost(this, render_frame_host));
128 OnRequestManifestResponse) 118 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 } 119 }
136 120
137 void ManifestManagerHost::OnRequestManifestResponse( 121 } // 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