1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/extensions/api/declarative/declarative_api.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/task_runner_util.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
12 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/extensions/api/events.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/common/extension_api.h"
20 #include "extensions/common/permissions/permissions_data.h"
21
22 using extensions::api::events::Rule;
23
24 namespace AddRules = extensions::api::events::Event::AddRules;
25 namespace GetRules = extensions::api::events::Event::GetRules;
26 namespace RemoveRules = extensions::api::events::Event::RemoveRules;
27
28
29 namespace extensions {
30
31 namespace {
32
33 const char kWebRequest[] = "declarativeWebRequest.";
34 const char kWebView[] = "webview.";
35 const char kWebViewExpectedError[] = "Webview event with Webview ID expected.";
36
IsWebViewEvent(const std::string & event_name)37 bool IsWebViewEvent(const std::string& event_name) {
38 // Sample event names:
39 // webview.onRequest.
40 // webview.OnMessage.
41 return event_name.compare(0, strlen(kWebView), kWebView) == 0;
42 }
43
GetWebRequestEventName(const std::string & event_name)44 std::string GetWebRequestEventName(const std::string& event_name) {
45 std::string web_request_event_name(event_name);
46 if (IsWebViewEvent(web_request_event_name))
47 web_request_event_name.replace(0, strlen(kWebView), kWebRequest);
48 return web_request_event_name;
49 }
50
51 } // namespace
52
RulesFunction()53 RulesFunction::RulesFunction()
54 : rules_registry_(NULL) {
55 }
56
~RulesFunction()57 RulesFunction::~RulesFunction() {}
58
HasPermission()59 bool RulesFunction::HasPermission() {
60 std::string event_name;
61 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name));
62 if (IsWebViewEvent(event_name) &&
63 extension_->permissions_data()->HasAPIPermission(
64 extensions::APIPermission::kWebView))
65 return true;
66 Feature::Availability availability =
67 ExtensionAPI::GetSharedInstance()->IsAvailable(
68 event_name, extension_, Feature::BLESSED_EXTENSION_CONTEXT,
69 source_url());
70 return availability.is_available();
71 }
72
RunAsync()73 bool RulesFunction::RunAsync() {
74 std::string event_name;
75 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name));
76
77 int webview_instance_id = 0;
78 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &webview_instance_id));
79 int embedder_process_id = render_view_host()->GetProcess()->GetID();
80
81 bool has_webview = webview_instance_id != 0;
82 if (has_webview != IsWebViewEvent(event_name))
83 EXTENSION_FUNCTION_ERROR(kWebViewExpectedError);
84 event_name = GetWebRequestEventName(event_name);
85
86 // If we are not operating on a particular <webview>, then the key is (0, 0).
87 RulesRegistryService::WebViewKey key(
88 webview_instance_id ? embedder_process_id : 0, webview_instance_id);
89
90 RulesRegistryService* rules_registry_service =
91 RulesRegistryService::Get(GetProfile());
92 rules_registry_ = rules_registry_service->GetRulesRegistry(key, event_name);
93 // Raw access to this function is not available to extensions, therefore
94 // there should never be a request for a nonexisting rules registry.
95 EXTENSION_FUNCTION_VALIDATE(rules_registry_.get());
96
97 if (content::BrowserThread::CurrentlyOn(rules_registry_->owner_thread())) {
98 bool success = RunAsyncOnCorrectThread();
99 SendResponse(success);
100 } else {
101 scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
102 content::BrowserThread::GetMessageLoopProxyForThread(
103 rules_registry_->owner_thread());
104 base::PostTaskAndReplyWithResult(
105 message_loop_proxy.get(),
106 FROM_HERE,
107 base::Bind(&RulesFunction::RunAsyncOnCorrectThread, this),
108 base::Bind(&RulesFunction::SendResponse, this));
109 }
110
111 return true;
112 }
113
RunAsyncOnCorrectThread()114 bool EventsEventAddRulesFunction::RunAsyncOnCorrectThread() {
115 scoped_ptr<AddRules::Params> params(AddRules::Params::Create(*args_));
116 EXTENSION_FUNCTION_VALIDATE(params.get());
117
118 error_ = rules_registry_->AddRules(extension_id(), params->rules);
119
120 if (error_.empty())
121 results_ = AddRules::Results::Create(params->rules);
122
123 return error_.empty();
124 }
125
RunAsyncOnCorrectThread()126 bool EventsEventRemoveRulesFunction::RunAsyncOnCorrectThread() {
127 scoped_ptr<RemoveRules::Params> params(RemoveRules::Params::Create(*args_));
128 EXTENSION_FUNCTION_VALIDATE(params.get());
129
130 if (params->rule_identifiers.get()) {
131 error_ = rules_registry_->RemoveRules(extension_id(),
132 *params->rule_identifiers);
133 } else {
134 error_ = rules_registry_->RemoveAllRules(extension_id());
135 }
136
137 return error_.empty();
138 }
139
RunAsyncOnCorrectThread()140 bool EventsEventGetRulesFunction::RunAsyncOnCorrectThread() {
141 scoped_ptr<GetRules::Params> params(GetRules::Params::Create(*args_));
142 EXTENSION_FUNCTION_VALIDATE(params.get());
143
144 std::vector<linked_ptr<Rule> > rules;
145 if (params->rule_identifiers.get()) {
146 rules_registry_->GetRules(
147 extension_id(), *params->rule_identifiers, &rules);
148 } else {
149 rules_registry_->GetAllRules(extension_id(), &rules);
150 }
151
152 results_ = GetRules::Results::Create(rules);
153
154 return true;
155 }
156
157 } // namespace extensions
158