blob: f390d722ea1aac3c90e8ddb1f496dc5b4ebe285c [file] [log] [blame]
[email protected]c5dbef02011-05-13 05:06:091// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]703e807a2009-03-28 19:56:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/extension_function.h"
6
[email protected]93d49d72009-10-23 20:00:207#include "base/json/json_writer.h"
[email protected]73404a372009-04-17 23:09:108#include "base/logging.h"
[email protected]703e807a2009-03-28 19:56:519#include "chrome/browser/extensions/extension_function_dispatcher.h"
[email protected]eaa7dd182010-12-14 11:09:0010#include "chrome/browser/extensions/extension_service.h"
[email protected]8ecad5e2010-12-02 21:18:3311#include "chrome/browser/profiles/profile.h"
[email protected]c5dbef02011-05-13 05:06:0912#include "chrome/common/extensions/extension_messages.h"
13#include "content/browser/renderer_host/render_process_host.h"
14#include "content/browser/renderer_host/render_view_host.h"
15#include "content/browser/user_metrics.h"
16#include "content/common/notification_source.h"
17#include "content/common/notification_type.h"
18#include "content/common/result_codes.h"
19
20ExtensionFunction::RenderViewHostTracker::RenderViewHostTracker(
21 ExtensionFunction* function)
22 : function_(function) {
23 registrar_.Add(this,
24 NotificationType::RENDER_VIEW_HOST_DELETED,
25 Source<RenderViewHost>(function->render_view_host()));
26}
27
28void ExtensionFunction::RenderViewHostTracker::Observe(
29 NotificationType type,
30 const NotificationSource& source,
31 const NotificationDetails& details) {
32 CHECK(type == NotificationType::RENDER_VIEW_HOST_DELETED);
33 CHECK(Source<RenderViewHost>(source).ptr() ==
34 function_->render_view_host());
35 function_->SetRenderViewHost(NULL);
36}
[email protected]942690b132010-05-11 06:42:1437
[email protected]3a3d47472010-07-15 21:03:5438ExtensionFunction::ExtensionFunction()
[email protected]9931fbfc2010-07-23 09:15:5139 : request_id_(-1),
40 profile_(NULL),
41 has_callback_(false),
[email protected]6451e332010-10-05 00:14:5342 include_incognito_(false),
43 user_gesture_(false) {
[email protected]3a3d47472010-07-15 21:03:5444}
45
46ExtensionFunction::~ExtensionFunction() {
47}
48
[email protected]c5dbef02011-05-13 05:06:0949void ExtensionFunction::SetRenderViewHost(RenderViewHost* render_view_host) {
50 render_view_host_ = render_view_host;
51 tracker_.reset(render_view_host ? new RenderViewHostTracker(this) : NULL);
52}
53
[email protected]9adb9692010-10-29 23:14:0254const Extension* ExtensionFunction::GetExtension() {
[email protected]eaa7dd182010-12-14 11:09:0055 ExtensionService* service = profile_->GetExtensionService();
[email protected]942690b132010-05-11 06:42:1456 DCHECK(service);
57 return service->GetExtensionById(extension_id_, false);
58}
[email protected]703e807a2009-03-28 19:56:5159
[email protected]3a3d47472010-07-15 21:03:5460Browser* ExtensionFunction::GetCurrentBrowser() {
[email protected]c5dbef02011-05-13 05:06:0961 return dispatcher()->GetCurrentBrowser(render_view_host_, include_incognito_);
[email protected]3a3d47472010-07-15 21:03:5462}
63
64AsyncExtensionFunction::AsyncExtensionFunction()
65 : args_(NULL), bad_message_(false) {
66}
67
68AsyncExtensionFunction::~AsyncExtensionFunction() {
69}
70
[email protected]438c97d2010-05-21 23:30:1571void AsyncExtensionFunction::SetArgs(const ListValue* args) {
[email protected]30294edf2009-11-10 00:24:3872 DCHECK(!args_.get()); // Should only be called once.
[email protected]16f47e082011-01-18 02:16:5973 args_.reset(args->DeepCopy());
[email protected]b83e4602009-05-15 22:58:3374}
75
76const std::string AsyncExtensionFunction::GetResult() {
77 std::string json;
[email protected]24f57132009-05-18 21:23:0578 // Some functions might not need to return any results.
79 if (result_.get())
[email protected]93d49d72009-10-23 20:00:2080 base::JSONWriter::Write(result_.get(), false, &json);
[email protected]b83e4602009-05-15 22:58:3381 return json;
82}
83
[email protected]3a3d47472010-07-15 21:03:5484const std::string AsyncExtensionFunction::GetError() {
85 return error_;
86}
87
88void AsyncExtensionFunction::Run() {
89 if (!RunImpl())
90 SendResponse(false);
91}
92
[email protected]b83e4602009-05-15 22:58:3393void AsyncExtensionFunction::SendResponse(bool success) {
[email protected]c5dbef02011-05-13 05:06:0994 if (!render_view_host_ || !dispatcher())
[email protected]32dda362009-06-05 19:07:0195 return;
[email protected]73404a372009-04-17 23:09:1096 if (bad_message_) {
[email protected]c5dbef02011-05-13 05:06:0997 HandleBadMessage();
98 return;
99 }
100
101 render_view_host_->Send(new ExtensionMsg_Response(
102 render_view_host_->routing_id(), request_id_, success,
103 GetResult(), GetError()));
104}
105
106void AsyncExtensionFunction::HandleBadMessage() {
107 LOG(ERROR) << "bad extension message " << name_ << " : terminating renderer.";
108 if (RenderProcessHost::run_renderer_in_process()) {
109 // In single process mode it is better if we don't suicide but just crash.
110 CHECK(false);
[email protected]703e807a2009-03-28 19:56:51111 } else {
[email protected]c5dbef02011-05-13 05:06:09112 NOTREACHED();
113 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_EFD"));
114 base::KillProcess(render_view_host_->process()->GetHandle(),
115 ResultCodes::KILLED_BAD_MESSAGE, false);
[email protected]703e807a2009-03-28 19:56:51116 }
117}
[email protected]73404a372009-04-17 23:09:10118
[email protected]35213ce92010-04-08 19:06:15119bool AsyncExtensionFunction::HasOptionalArgument(size_t index) {
[email protected]35213ce92010-04-08 19:06:15120 Value* value;
[email protected]438c97d2010-05-21 23:30:15121 return args_->Get(index, &value) && !value->IsType(Value::TYPE_NULL);
[email protected]35213ce92010-04-08 19:06:15122}
[email protected]3a3d47472010-07-15 21:03:54123
124SyncExtensionFunction::SyncExtensionFunction() {
125}
126
127SyncExtensionFunction::~SyncExtensionFunction() {
128}
129
130void SyncExtensionFunction::Run() {
131 SendResponse(RunImpl());
132}