1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_function_dispatcher.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_string_value_serializer.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/metrics/sparse_histogram.h" 13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/process.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_frame_host.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/web_contents.h" 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/result_codes.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/api_activity_monitor.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_function_registry.h" 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "extensions/browser/extension_message_filter.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/process_manager.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_map.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/quota_service.h" 330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "extensions/common/extension_api.h" 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace extensions { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Notifies the ApiActivityMonitor that an extension API function has been 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// called. May be called from any thread. 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NotifyApiFunctionCalled(const std::string& extension_id, 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& api_name, 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> args, 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::BrowserContext* browser_context) { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The ApiActivityMonitor can only be accessed from the main (UI) thread. If 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we're running on the wrong thread, re-dispatch from the main thread. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&NotifyApiFunctionCalled, 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_id, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) api_name, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Passed(&args), 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) browser_context)); 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The BrowserContext may become invalid after the task above is posted. 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ApiActivityMonitor* monitor = 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionsBrowserClient::Get()->GetApiActivityMonitor(browser_context); 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (monitor) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitor->OnApiFunctionCalled(extension_id, api_name, args.Pass()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Separate copy of ExtensionAPI used for IO thread extension functions. We need 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this because ExtensionAPI has mutable data. It should be possible to remove 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this once all the extension APIs are updated to the feature system. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Static { 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Static() : api(ExtensionAPI::CreateWithDefaultConfiguration()) {} 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_ptr<ExtensionAPI> api; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Kills the specified process because it sends us a malformed message. 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void KillBadMessageSender(base::ProcessHandle process) { 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED(); 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (process) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::KillProcess(process, content::RESULT_CODE_KILLED_BAD_MESSAGE, false); 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void CommonResponseCallback(IPC::Sender* ipc_sender, 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int routing_id, 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ProcessHandle peer_process, 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int request_id, 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionFunction::ResponseType type, 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue& results, 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& error) { 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(ipc_sender); 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == ExtensionFunction::BAD_MESSAGE) { 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The renderer has done validation before sending extension api requests. 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Therefore, we should never receive a request that is invalid in a way 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // that JSON validation in the renderer should have caught. It could be an 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // attacker trying to exploit the browser, so we crash the renderer instead. 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(ERROR) << 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "Terminating renderer because of malformed extension message."; 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (content::RenderProcessHost::run_renderer_in_process()) { 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // In single process mode it is better if we don't suicide but just crash. 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(false); 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) KillBadMessageSender(peer_process); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ipc_sender->Send(new ExtensionMsg_Response( 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) routing_id, request_id, type == ExtensionFunction::SUCCEEDED, results, 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error)); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IOThreadResponseCallback( 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::WeakPtr<ExtensionMessageFilter>& ipc_sender, 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int routing_id, 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int request_id, 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionFunction::ResponseType type, 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue& results, 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& error) { 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ipc_sender.get()) 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CommonResponseCallback(ipc_sender.get(), 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) routing_id, 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ipc_sender->PeerHandle(), 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_id, 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) type, 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) results, 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : public content::WebContentsObserver { 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UIThreadResponseCallbackWrapper( 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::WeakPtr<ExtensionFunctionDispatcher>& dispatcher, 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RenderViewHost* render_view_host) 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : content::WebContentsObserver( 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) content::WebContents::FromRenderViewHost(render_view_host)), 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher_(dispatcher), 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) render_view_host_(render_view_host), 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_ptr_factory_(this) { 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~UIThreadResponseCallbackWrapper() { 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // content::WebContentsObserver overrides. 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void RenderViewDeleted( 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RenderViewHost* render_view_host) OVERRIDE { 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (render_view_host != render_view_host_) 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (dispatcher_.get()) { 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dispatcher_->ui_thread_response_callback_wrappers_ 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .erase(render_view_host); 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delete this; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionFunction::ResponseCallback CreateCallback(int request_id) { 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return base::Bind( 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &UIThreadResponseCallbackWrapper::OnExtensionFunctionCompleted, 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request_id); 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnExtensionFunctionCompleted(int request_id, 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionFunction::ResponseType type, 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue& results, 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& error) { 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CommonResponseCallback( 1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) render_view_host_, render_view_host_->GetRoutingID(), 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) render_view_host_->GetProcess()->GetHandle(), request_id, type, 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) results, error); 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) content::RenderViewHost* render_view_host_; 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::WeakPtrFactory<UIThreadResponseCallbackWrapper> weak_ptr_factory_; 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UIThreadResponseCallbackWrapper); 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 198e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochWindowController* 199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochExtensionFunctionDispatcher::Delegate::GetExtensionWindowController() const { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::WebContents* 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionFunctionDispatcher::Delegate::GetAssociatedWebContents() const { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochcontent::WebContents* 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochExtensionFunctionDispatcher::Delegate::GetVisibleWebContents() const { 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return GetAssociatedWebContents(); 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionFunctionDispatcher::GetAllFunctionNames( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string>* names) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFunctionRegistry::GetInstance()->GetAllNames(names); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionFunctionDispatcher::OverrideFunction( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, ExtensionFunctionFactory factory) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExtensionFunctionRegistry::GetInstance()->OverrideFunction(name, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionFunctionDispatcher::DispatchOnIOThread( 226e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch InfoMap* extension_info_map, 227e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void* profile_id, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int render_process_id, 229e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::WeakPtr<ExtensionMessageFilter> ipc_sender, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int routing_id, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionHostMsg_Request_Params& params) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map->extensions().GetByID(params.extension_id); 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extension) 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ExtensionFunction::ResponseCallback callback( 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&IOThreadResponseCallback, ipc_sender, routing_id, 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.request_id)); 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ExtensionFunction> function( 242e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CreateExtensionFunction(params, 243e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch extension, 244e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch render_process_id, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map->process_map(), 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_global_io_data.Get().api.get(), 247e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch profile_id, 248e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callback)); 2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!function.get()) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IOThreadExtensionFunction* function_io = 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->AsIOThreadExtensionFunction(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!function_io) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) function_io->set_ipc_sender(ipc_sender, routing_id); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_io->set_extension_info_map(extension_info_map); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->set_include_incognito( 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map->IsIncognitoEnabled(extension->id())); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!CheckPermissions(function.get(), params, callback)) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 266e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuotaService* quota = extension_info_map->GetQuotaService(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string violation_error = quota->Assess(extension->id(), 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) function.get(), 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ¶ms.arguments, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (violation_error.empty()) { 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); 273e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch NotifyApiFunctionCalled(extension->id(), 274e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch params.name, 275e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch args.Pass(), 276e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static_cast<content::BrowserContext*>(profile_id)); 277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", 278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch function->histogram_value()); 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->Run()->Execute(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->OnQuotaExceeded(violation_error); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* browser_context, 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Delegate* delegate) 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : browser_context_(browser_context), 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_(delegate) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionFunctionDispatcher::Dispatch( 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionHostMsg_Request_Params& params, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host) { 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UIThreadResponseCallbackWrapperMap::const_iterator 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) iter = ui_thread_response_callback_wrappers_.find(render_view_host); 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UIThreadResponseCallbackWrapper* callback_wrapper = NULL; 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (iter == ui_thread_response_callback_wrappers_.end()) { 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_wrapper = new UIThreadResponseCallbackWrapper(AsWeakPtr(), 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_view_host); 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ui_thread_response_callback_wrappers_[render_view_host] = callback_wrapper; 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_wrapper = iter->second; 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DispatchWithCallbackInternal( 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params, render_view_host, NULL, 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_wrapper->CreateCallback(params.request_id)); 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionFunctionDispatcher::DispatchWithCallbackInternal( 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionHostMsg_Request_Params& params, 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RenderViewHost* render_view_host, 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderFrameHost* render_frame_host, 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ExtensionFunction::ResponseCallback& callback) { 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(render_view_host || render_frame_host); 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(yzshen): There is some shared logic between this method and 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // DispatchOnIOThread(). It is nice to deduplicate. 322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessMap* process_map = ProcessMap::Get(browser_context_); 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!process_map) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 326e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension = 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registry->enabled_extensions().GetByID(params.extension_id); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extension) { 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension = 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->enabled_extensions().GetHostedAppByURL(params.source_url); 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int process_id = render_view_host ? render_view_host->GetProcess()->GetID() : 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_host->GetProcess()->GetID(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ExtensionFunction> function( 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CreateExtensionFunction(params, 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extension, 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process_id, 340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *process_map, 341e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ExtensionAPI::GetSharedInstance(), 342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) browser_context_, 343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) callback)); 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!function.get()) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UIThreadExtensionFunction* function_ui = 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->AsUIThreadExtensionFunction(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!function_ui) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (render_view_host) { 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function_ui->SetRenderViewHost(render_view_host); 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function_ui->SetRenderFrameHost(render_frame_host); 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_ui->set_dispatcher(AsWeakPtr()); 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) function_ui->set_browser_context(browser_context_); 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension && 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionsBrowserClient::Get()->CanExtensionCrossIncognito( 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension, browser_context_)) { 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->set_include_incognito(true); 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!CheckPermissions(function.get(), params, callback)) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!extension) { 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Skip all of the UMA, quota, event page, activity logging stuff if there 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // isn't an extension, e.g. if the function call was from WebUI. 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->Run()->Execute(); 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); 377e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuotaService* quota = extension_system->quota_service(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string violation_error = quota->Assess(extension->id(), 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) function.get(), 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ¶ms.arguments, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now()); 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (violation_error.empty()) { 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> args(params.arguments.DeepCopy()); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // See crbug.com/39178. 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionsBrowserClient::Get()->PermitExternalProtocolHandler(); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyApiFunctionCalled( 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension->id(), params.name, args.Pass(), browser_context_); 390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.FunctionCalls", 391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch function->histogram_value()); 392010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->Run()->Execute(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->OnQuotaExceeded(violation_error); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: do not access |this| after this point. We may have been deleted 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if function->Run() ended up closing the tab that owns us. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if extension was uninstalled by management.uninstall. 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!registry->enabled_extensions().GetByID(params.extension_id)) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only adjust the keepalive count for UIThreadExtensionFunction for 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now, largely for simplicity's sake. This is OK because currently, only 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the webRequest API uses IOThreadExtensionFunction, and that API is not 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compatible with lazy background pages. 408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) extension_system->process_manager()->IncrementLazyKeepaliveCount(extension); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionFunctionDispatcher::OnExtensionFunctionCompleted( 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension) { 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionSystem::Get(browser_context_) 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->process_manager() 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->DecrementLazyKeepaliveCount(extension); 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionFunctionDispatcher::CheckPermissions( 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFunction* function, 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionHostMsg_Request_Params& params, 42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ExtensionFunction::ResponseCallback& callback) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!function->HasPermission()) { 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Permission denied for " << params.name; 42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendAccessDenied(callback); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionHostMsg_Request_Params& params, 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int requesting_process_id, 438e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const ProcessMap& process_map, 439e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ExtensionAPI* api, 440e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void* profile_id, 44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ExtensionFunction::ResponseCallback& callback) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFunction* function = 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionFunctionRegistry::GetInstance()->NewFunction(params.name); 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!function) { 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unknown Extension API - " << params.name; 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SendAccessDenied(callback); 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->SetArgs(¶ms.arguments); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->set_source_url(params.source_url); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->set_request_id(params.request_id); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->set_has_callback(params.has_callback); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->set_user_gesture(params.user_gesture); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function->set_extension(extension); 456e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch function->set_profile_id(profile_id); 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) function->set_response_callback(callback); 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function->set_source_tab_id(params.source_tab_id); 4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->set_source_context_type( 4606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) process_map.GetMostLikelyContextType(extension, requesting_process_id)); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return function; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionFunctionDispatcher::SendAccessDenied( 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const ExtensionFunction::ResponseCallback& callback) { 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue empty_list; 46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(ExtensionFunction::FAILED, empty_list, 47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "Access to extension API denied."); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 472e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 473e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace extensions 474