Use multiline attribute to check for IA2_STATE_MULTILINE.
[chromium-blink-merge.git] / content / browser / manifest / manifest_manager_host.cc
blob14d07e203ee3a9b69274bfd67ca661a4a5cf10e0
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
3 // found in the LICENSE file.
5 #include "content/browser/manifest/manifest_manager_host.h"
7 #include "base/stl_util.h"
8 #include "content/common/manifest_manager_messages.h"
9 #include "content/public/browser/render_frame_host.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/common/manifest.h"
12 #include "content/public/common/result_codes.h"
14 namespace content {
16 namespace {
18 void KillRenderer(RenderFrameHost* render_frame_host) {
19 base::ProcessHandle process_handle =
20 render_frame_host->GetProcess()->GetHandle();
21 if (process_handle == base::kNullProcessHandle)
22 return;
23 render_frame_host->GetProcess()->Shutdown(RESULT_CODE_KILLED_BAD_MESSAGE,
24 false);
27 } // anonymous namespace
29 ManifestManagerHost::ManifestManagerHost(WebContents* web_contents)
30 : WebContentsObserver(web_contents) {
33 ManifestManagerHost::~ManifestManagerHost() {
34 STLDeleteValues(&pending_callbacks_);
37 ManifestManagerHost::CallbackMap* ManifestManagerHost::GetCallbackMapForFrame(
38 RenderFrameHost* render_frame_host) {
39 FrameCallbackMap::iterator it = pending_callbacks_.find(render_frame_host);
40 return it != pending_callbacks_.end() ? it->second : 0;
43 void ManifestManagerHost::RenderFrameDeleted(
44 RenderFrameHost* render_frame_host) {
45 CallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
46 if (!callbacks)
47 return;
49 // Before deleting the callbacks, make sure they are called with a failure
50 // state. Do this in a block so the iterator is destroyed before |callbacks|.
52 CallbackMap::const_iterator it(callbacks);
53 for (; !it.IsAtEnd(); it.Advance())
54 it.GetCurrentValue()->Run(Manifest());
57 delete callbacks;
58 pending_callbacks_.erase(render_frame_host);
61 void ManifestManagerHost::GetManifest(RenderFrameHost* render_frame_host,
62 const GetManifestCallback& callback) {
63 CallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
64 if (!callbacks) {
65 callbacks = new CallbackMap();
66 pending_callbacks_[render_frame_host] = callbacks;
69 int request_id = callbacks->Add(new GetManifestCallback(callback));
71 render_frame_host->Send(new ManifestManagerMsg_RequestManifest(
72 render_frame_host->GetRoutingID(), request_id));
75 bool ManifestManagerHost::OnMessageReceived(
76 const IPC::Message& message, RenderFrameHost* render_frame_host) {
77 bool handled = true;
79 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(ManifestManagerHost, message,
80 render_frame_host)
81 IPC_MESSAGE_HANDLER(ManifestManagerHostMsg_RequestManifestResponse,
82 OnRequestManifestResponse)
83 IPC_MESSAGE_UNHANDLED(handled = false)
84 IPC_END_MESSAGE_MAP()
86 return handled;
89 void ManifestManagerHost::OnRequestManifestResponse(
90 RenderFrameHost* render_frame_host,
91 int request_id,
92 const Manifest& insecure_manifest) {
93 CallbackMap* callbacks = GetCallbackMapForFrame(render_frame_host);
94 if (!callbacks) {
95 DVLOG(1) << "Unexpected RequestManifestResponse to from renderer. "
96 "Killing renderer.";
97 KillRenderer(render_frame_host);
98 return;
101 GetManifestCallback* callback = callbacks->Lookup(request_id);
102 if (!callback) {
103 DVLOG(1) << "Received a request_id (" << request_id << ") from renderer "
104 "with no associated callback. Killing renderer.";
105 KillRenderer(render_frame_host);
106 return;
109 // When receiving a Manifest, the browser process can't trust that it is
110 // coming from a known and secure source. It must be processed accordingly.
111 Manifest manifest = insecure_manifest;
112 manifest.name = base::NullableString16(
113 manifest.name.string().substr(0, Manifest::kMaxIPCStringLength),
114 manifest.name.is_null());
115 manifest.short_name = base::NullableString16(
116 manifest.short_name.string().substr(0, Manifest::kMaxIPCStringLength),
117 manifest.short_name.is_null());
118 if (!manifest.start_url.is_valid())
119 manifest.start_url = GURL();
120 for (size_t i = 0; i < manifest.icons.size(); ++i) {
121 if (!manifest.icons[i].src.is_valid())
122 manifest.icons[i].src = GURL();
123 manifest.icons[i].type = base::NullableString16(
124 manifest.icons[i].type.string().substr(0,
125 Manifest::kMaxIPCStringLength),
126 manifest.icons[i].type.is_null());
128 manifest.gcm_sender_id = base::NullableString16(
129 manifest.gcm_sender_id.string().substr(
130 0, Manifest::kMaxIPCStringLength),
131 manifest.gcm_sender_id.is_null());
133 callback->Run(manifest);
134 callbacks->Remove(request_id);
135 if (callbacks->IsEmpty()) {
136 delete callbacks;
137 pending_callbacks_.erase(render_frame_host);
141 } // namespace content