15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/extensions/extension_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_string_value_serializer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_messages.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/render_messages.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/extensions/chrome_v8_context.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/renderer/extensions/console.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/extensions/dispatcher.h"
21fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "chrome/renderer/extensions/messaging_bindings.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/extensions/user_script_scheduler.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/extensions/user_script_slave.h"
24b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/renderer/web_apps.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view_visitor.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebConsoleMessage.h"
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ConsoleMessageLevel;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebConsoleMessage;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebDataSource;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebFrame;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebURLRequest;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebScopedUserGesture;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebView;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Keeps a mapping from the frame pointer to a UserScriptScheduler object.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We store this mapping per process, because a frame can jump from one
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// document to another with adoptNode, and so having the object be a
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderViewObserver means it might miss some notifications after it moves.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<WebFrame*, UserScriptScheduler*> SchedulerMap;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::LazyInstance<SchedulerMap> g_schedulers =
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A RenderViewVisitor class that iterates through the set of available
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views, looking for a view of the given type, in the given browser window
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and within the given extension.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to accumulate the list of views associated with an extension.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ViewAccumulator : public content::RenderViewVisitor {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewAccumulator(const std::string& extension_id,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int browser_window_id,
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  ViewType view_type)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : extension_id_(extension_id),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_window_id_(browser_window_id),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        view_type_(view_type) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<content::RenderView*> views() { return views_; }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns false to terminate the iteration.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool Visit(content::RenderView* render_view) OVERRIDE {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionHelper* helper = ExtensionHelper::Get(render_view);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ViewTypeMatches(helper->view_type(), view_type_))
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url = render_view->GetWebView()->mainFrame()->document().url();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!url.SchemeIs(kExtensionScheme))
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id = url.host();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension_id != extension_id_)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (browser_window_id_ != extension_misc::kUnknownWindowId &&
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        helper->browser_window_id() != browser_window_id_) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views_.push_back(render_view);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (view_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;  // There can be only one...
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |type| "isa" |match|.
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static bool ViewTypeMatches(ViewType type, ViewType match) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == match)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // INVALID means match all.
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (match == VIEW_TYPE_INVALID)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int browser_window_id_;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ViewType view_type_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<content::RenderView*> views_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<content::RenderView*> ExtensionHelper::GetExtensionViews(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int browser_window_id,
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ViewType view_type) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewAccumulator accumulator(extension_id, browser_window_id, view_type);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderView::ForEach(&accumulator);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return accumulator.views();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::RenderView* ExtensionHelper::GetBackgroundPage(
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewAccumulator accumulator(extension_id, extension_misc::kUnknownWindowId,
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderView::ForEach(&accumulator);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_LE(accumulator.views().size(), 1u);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (accumulator.views().size() == 0)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return accumulator.views()[0];
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionHelper::ExtensionHelper(content::RenderView* render_view,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 Dispatcher* dispatcher)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : content::RenderViewObserver(render_view),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::RenderViewObserverTracker<ExtensionHelper>(render_view),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_(dispatcher),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_app_icon_requests_(0),
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      view_type_(VIEW_TYPE_INVALID),
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_id_(-1),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_window_id_(-1) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionHelper::~ExtensionHelper() {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionHelper::OnMessageReceived(const IPC::Message& message) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ExtensionHelper, message)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_Response, OnExtensionResponse)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnExtensionDispatchOnConnect)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnExtensionDeliverMessage)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnExtensionDispatchOnDisconnect)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_ExecuteCode, OnExecuteCode)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_GetApplicationInfo, OnGetApplicationInfo)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabId, OnSetTabId)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnUpdateBrowserWindowId)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnNotifyRendererViewType)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnAddMessageToConsole)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnAppWindowClosed);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::DidFinishDocumentLoad(WebFrame* frame) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_->user_script_slave()->InjectScripts(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frame, UserScript::DOCUMENT_END);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != g_schedulers.Get().end())
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i->second->DidFinishDocumentLoad();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::DidFinishLoad(WebKit::WebFrame* frame) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != g_schedulers.Get().end())
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i->second->DidFinishLoad();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::DidCreateDocumentElement(WebFrame* frame) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_->user_script_slave()->InjectScripts(
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frame, UserScript::DOCUMENT_START);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != g_schedulers.Get().end())
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i->second->DidCreateDocumentElement();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_->DidCreateDocumentElement(frame);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::DidStartProvisionalLoad(WebKit::WebFrame* frame) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != g_schedulers.Get().end())
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i->second->DidStartProvisionalLoad();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::DraggableRegionsChanged(WebKit::WebFrame* frame) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::WebVector<WebKit::WebDraggableRegion> webregions =
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frame->document().draggableRegions();
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<DraggableRegion> regions;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < webregions.size(); ++i) {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DraggableRegion region;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    region.bounds = webregions[i].bounds;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    region.draggable = webregions[i].draggable;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    regions.push_back(region);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::FrameDetached(WebFrame* frame) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This could be called before DidCreateDataSource, in which case the frame
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // won't be in the map.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulerMap::iterator i = g_schedulers.Get().find(frame);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i == g_schedulers.Get().end())
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete i->second;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_schedulers.Get().erase(i);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check first if we created a scheduler for the frame, since this function
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // gets called for navigations within the document.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_schedulers.Get().count(frame))
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_schedulers.Get()[frame] = new UserScriptScheduler(frame, dispatcher_);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnExtensionResponse(int request_id,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          bool success,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const base::ListValue& response,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const std::string& error) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_->OnExtensionResponse(request_id,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   success,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   response,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   error);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id,
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                               const std::string& module_name,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const std::string& function_name,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const base::ListValue& args,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bool user_gesture) {
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  dispatcher_->InvokeModuleSystemMethod(
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      render_view(), extension_id, module_name, function_name, args,
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      user_gesture);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnExtensionDispatchOnConnect(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int target_port_id,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& channel_name,
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue& source_tab,
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ExtensionMsg_ExternalConnectionInfo& info) {
267fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  MessagingBindings::DispatchOnConnect(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_->v8_context_set().GetAll(),
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      target_port_id, channel_name, source_tab,
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      info.source_id, info.target_id, info.source_url,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ExtensionHelper::OnExtensionDeliverMessage(int target_id,
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                                const std::string& message) {
276fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  MessagingBindings::DeliverMessage(dispatcher_->v8_context_set().GetAll(),
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        target_id,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        message,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        render_view());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionHelper::OnExtensionDispatchOnDisconnect(
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int port_id,
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& error_message) {
285fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  MessagingBindings::DispatchOnDisconnect(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_->v8_context_set().GetAll(),
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      port_id, error_message,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnExecuteCode(
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ExtensionMsg_ExecuteCode_Params& params) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebView* webview = render_view()->GetWebView();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebFrame* main_frame = webview->mainFrame();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!main_frame) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ListValue val;
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Send(new ExtensionHostMsg_ExecuteCodeFinished(routing_id(),
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  params.request_id,
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  "No main frame",
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  -1,
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  GURL(std::string()),
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  val));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome.tabs.executeScript() only supports execution in either the top frame
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or all frames.  We handle both cases in the top frame.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulerMap::iterator i = g_schedulers.Get().find(main_frame);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != g_schedulers.Get().end())
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i->second->ExecuteCode(params);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnGetApplicationInfo(int page_id) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebApplicationInfo app_info;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (page_id == render_view()->GetPageId()) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string16 error;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_apps::ParseWebAppFromWebDocument(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        render_view()->GetWebView()->mainFrame(), &app_info, &error);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prune out any data URLs in the set of icons.  The browser process expects
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any icon with a data URL to have originated from a favicon.  We don't want
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to decode arbitrary data URLs in the browser process.  See
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://b/issue?id=1162972
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < app_info.icons.size(); ++i) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (app_info.icons[i].url.SchemeIs(chrome::kDataScheme)) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      app_info.icons.erase(app_info.icons.begin() + i);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      --i;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new ExtensionHostMsg_DidGetApplicationInfo(
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      routing_id(), page_id, app_info));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionHelper::OnNotifyRendererViewType(ViewType type) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  view_type_ = type;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnSetTabId(int init_tab_id) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(tab_id_, -1);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(init_tab_id, 0);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_id_ = init_tab_id;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnUpdateBrowserWindowId(int window_id) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser_window_id_ = window_id;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnAddMessageToConsole(ConsoleMessageLevel level,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const std::string& message) {
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  console::AddMessage(render_view(), level, message);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionHelper::OnAppWindowClosed() {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::HandleScope scope;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v8::Handle<v8::Context> script_context =
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view()->GetWebView()->mainFrame()->mainWorldScriptContext();
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChromeV8Context* chrome_v8_context =
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_->v8_context_set().GetByV8Context(script_context);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!chrome_v8_context)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  chrome_v8_context->module_system()->CallModuleMethod(
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      "app.window", "onAppWindowClosed");
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
368