[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 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 "chrome/browser/extensions/extension_function.h" |
| 6 | |
[email protected] | 93d49d7 | 2009-10-23 20:00:20 | [diff] [blame] | 7 | #include "base/json/json_writer.h" |
[email protected] | 73404a37 | 2009-04-17 23:09:10 | [diff] [blame] | 8 | #include "base/logging.h" |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 9 | #include "chrome/browser/extensions/extension_function_dispatcher.h" |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 10 | #include "chrome/browser/extensions/extension_service.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 11 | #include "chrome/browser/profiles/profile.h" |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 12 | #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 | |
| 20 | ExtensionFunction::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 | |
| 28 | void 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] | 942690b13 | 2010-05-11 06:42:14 | [diff] [blame] | 37 | |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 38 | ExtensionFunction::ExtensionFunction() |
[email protected] | 9931fbfc | 2010-07-23 09:15:51 | [diff] [blame] | 39 | : request_id_(-1), |
| 40 | profile_(NULL), |
| 41 | has_callback_(false), |
[email protected] | 6451e33 | 2010-10-05 00:14:53 | [diff] [blame] | 42 | include_incognito_(false), |
| 43 | user_gesture_(false) { |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 44 | } |
| 45 | |
| 46 | ExtensionFunction::~ExtensionFunction() { |
| 47 | } |
| 48 | |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 49 | void 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] | 9adb969 | 2010-10-29 23:14:02 | [diff] [blame] | 54 | const Extension* ExtensionFunction::GetExtension() { |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 55 | ExtensionService* service = profile_->GetExtensionService(); |
[email protected] | 942690b13 | 2010-05-11 06:42:14 | [diff] [blame] | 56 | DCHECK(service); |
| 57 | return service->GetExtensionById(extension_id_, false); |
| 58 | } |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 59 | |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 60 | Browser* ExtensionFunction::GetCurrentBrowser() { |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 61 | return dispatcher()->GetCurrentBrowser(render_view_host_, include_incognito_); |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | AsyncExtensionFunction::AsyncExtensionFunction() |
| 65 | : args_(NULL), bad_message_(false) { |
| 66 | } |
| 67 | |
| 68 | AsyncExtensionFunction::~AsyncExtensionFunction() { |
| 69 | } |
| 70 | |
[email protected] | 438c97d | 2010-05-21 23:30:15 | [diff] [blame] | 71 | void AsyncExtensionFunction::SetArgs(const ListValue* args) { |
[email protected] | 30294edf | 2009-11-10 00:24:38 | [diff] [blame] | 72 | DCHECK(!args_.get()); // Should only be called once. |
[email protected] | 16f47e08 | 2011-01-18 02:16:59 | [diff] [blame] | 73 | args_.reset(args->DeepCopy()); |
[email protected] | b83e460 | 2009-05-15 22:58:33 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | const std::string AsyncExtensionFunction::GetResult() { |
| 77 | std::string json; |
[email protected] | 24f5713 | 2009-05-18 21:23:05 | [diff] [blame] | 78 | // Some functions might not need to return any results. |
| 79 | if (result_.get()) |
[email protected] | 93d49d7 | 2009-10-23 20:00:20 | [diff] [blame] | 80 | base::JSONWriter::Write(result_.get(), false, &json); |
[email protected] | b83e460 | 2009-05-15 22:58:33 | [diff] [blame] | 81 | return json; |
| 82 | } |
| 83 | |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 84 | const std::string AsyncExtensionFunction::GetError() { |
| 85 | return error_; |
| 86 | } |
| 87 | |
| 88 | void AsyncExtensionFunction::Run() { |
| 89 | if (!RunImpl()) |
| 90 | SendResponse(false); |
| 91 | } |
| 92 | |
[email protected] | b83e460 | 2009-05-15 22:58:33 | [diff] [blame] | 93 | void AsyncExtensionFunction::SendResponse(bool success) { |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 94 | if (!render_view_host_ || !dispatcher()) |
[email protected] | 32dda36 | 2009-06-05 19:07:01 | [diff] [blame] | 95 | return; |
[email protected] | 73404a37 | 2009-04-17 23:09:10 | [diff] [blame] | 96 | if (bad_message_) { |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 97 | 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 | |
| 106 | void 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] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 111 | } else { |
[email protected] | c5dbef0 | 2011-05-13 05:06:09 | [diff] [blame^] | 112 | NOTREACHED(); |
| 113 | UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_EFD")); |
| 114 | base::KillProcess(render_view_host_->process()->GetHandle(), |
| 115 | ResultCodes::KILLED_BAD_MESSAGE, false); |
[email protected] | 703e807a | 2009-03-28 19:56:51 | [diff] [blame] | 116 | } |
| 117 | } |
[email protected] | 73404a37 | 2009-04-17 23:09:10 | [diff] [blame] | 118 | |
[email protected] | 35213ce9 | 2010-04-08 19:06:15 | [diff] [blame] | 119 | bool AsyncExtensionFunction::HasOptionalArgument(size_t index) { |
[email protected] | 35213ce9 | 2010-04-08 19:06:15 | [diff] [blame] | 120 | Value* value; |
[email protected] | 438c97d | 2010-05-21 23:30:15 | [diff] [blame] | 121 | return args_->Get(index, &value) && !value->IsType(Value::TYPE_NULL); |
[email protected] | 35213ce9 | 2010-04-08 19:06:15 | [diff] [blame] | 122 | } |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 123 | |
| 124 | SyncExtensionFunction::SyncExtensionFunction() { |
| 125 | } |
| 126 | |
| 127 | SyncExtensionFunction::~SyncExtensionFunction() { |
| 128 | } |
| 129 | |
| 130 | void SyncExtensionFunction::Run() { |
| 131 | SendResponse(RunImpl()); |
| 132 | } |