Home | History | Annotate | Download | only in extensions
      1 // Copyright 2013 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/chrome_extension_function.h"
      6 
      7 #include "chrome/browser/extensions/window_controller.h"
      8 #include "chrome/browser/extensions/window_controller_list.h"
      9 #include "chrome/browser/profiles/profile.h"
     10 #include "chrome/browser/ui/browser.h"
     11 #include "chrome/browser/ui/browser_finder.h"
     12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     13 #include "content/public/browser/render_process_host.h"
     14 #include "content/public/browser/render_view_host.h"
     15 #include "extensions/browser/extension_function_dispatcher.h"
     16 
     17 using content::RenderViewHost;
     18 using content::WebContents;
     19 
     20 ChromeUIThreadExtensionFunction::ChromeUIThreadExtensionFunction() {
     21 }
     22 
     23 Profile* ChromeUIThreadExtensionFunction::GetProfile() const {
     24   return Profile::FromBrowserContext(context_);
     25 }
     26 
     27 bool ChromeUIThreadExtensionFunction::CanOperateOnWindow(
     28     const extensions::WindowController* window_controller) const {
     29   const extensions::Extension* extension = GetExtension();
     30   // |extension| is NULL for unit tests only.
     31   if (extension != NULL && !window_controller->IsVisibleToExtension(extension))
     32     return false;
     33 
     34   if (GetProfile() == window_controller->profile())
     35     return true;
     36 
     37   if (!include_incognito())
     38     return false;
     39 
     40   return GetProfile()->HasOffTheRecordProfile() &&
     41          GetProfile()->GetOffTheRecordProfile() == window_controller->profile();
     42 }
     43 
     44 // TODO(stevenjb): Replace this with GetExtensionWindowController().
     45 Browser* ChromeUIThreadExtensionFunction::GetCurrentBrowser() {
     46   // If the delegate has an associated browser, return it.
     47   if (dispatcher()) {
     48     extensions::WindowController* window_controller =
     49         dispatcher()->delegate()->GetExtensionWindowController();
     50     if (window_controller) {
     51       Browser* browser = window_controller->GetBrowser();
     52       if (browser)
     53         return browser;
     54     }
     55   }
     56 
     57   // Otherwise, try to default to a reasonable browser. If |include_incognito_|
     58   // is true, we will also search browsers in the incognito version of this
     59   // profile. Note that the profile may already be incognito, in which case
     60   // we will search the incognito version only, regardless of the value of
     61   // |include_incognito|. Look only for browsers on the active desktop as it is
     62   // preferable to pretend no browser is open then to return a browser on
     63   // another desktop.
     64   if (render_view_host_) {
     65     Profile* profile = Profile::FromBrowserContext(
     66         render_view_host_->GetProcess()->GetBrowserContext());
     67     Browser* browser = chrome::FindAnyBrowser(
     68         profile, include_incognito_, chrome::GetActiveDesktop());
     69     if (browser)
     70       return browser;
     71   }
     72 
     73   // NOTE(rafaelw): This can return NULL in some circumstances. In particular,
     74   // a background_page onload chrome.tabs api call can make it into here
     75   // before the browser is sufficiently initialized to return here, or
     76   // all of this profile's browser windows may have been closed.
     77   // A similar situation may arise during shutdown.
     78   // TODO(rafaelw): Delay creation of background_page until the browser
     79   // is available. http://code.google.com/p/chromium/issues/detail?id=13284
     80   return NULL;
     81 }
     82 
     83 extensions::WindowController*
     84 ChromeUIThreadExtensionFunction::GetExtensionWindowController() {
     85   // If the delegate has an associated window controller, return it.
     86   if (dispatcher()) {
     87     extensions::WindowController* window_controller =
     88         dispatcher()->delegate()->GetExtensionWindowController();
     89     if (window_controller)
     90       return window_controller;
     91   }
     92 
     93   return extensions::WindowControllerList::GetInstance()
     94       ->CurrentWindowForFunction(this);
     95 }
     96 
     97 content::WebContents*
     98 ChromeUIThreadExtensionFunction::GetAssociatedWebContents() {
     99   content::WebContents* web_contents =
    100       UIThreadExtensionFunction::GetAssociatedWebContents();
    101   if (web_contents)
    102     return web_contents;
    103 
    104   Browser* browser = GetCurrentBrowser();
    105   if (!browser)
    106     return NULL;
    107   return browser->tab_strip_model()->GetActiveWebContents();
    108 }
    109 
    110 ChromeUIThreadExtensionFunction::~ChromeUIThreadExtensionFunction() {
    111 }
    112 
    113 ChromeAsyncExtensionFunction::ChromeAsyncExtensionFunction() {
    114 }
    115 
    116 ChromeAsyncExtensionFunction::~ChromeAsyncExtensionFunction() {}
    117 
    118 ExtensionFunction::ResponseAction ChromeAsyncExtensionFunction::Run() {
    119   return RunAsync() ? RespondLater() : RespondNow(Error(error_));
    120 }
    121 
    122 // static
    123 bool ChromeAsyncExtensionFunction::ValidationFailure(
    124     ChromeAsyncExtensionFunction* function) {
    125   return false;
    126 }
    127 
    128 ChromeSyncExtensionFunction::ChromeSyncExtensionFunction() {
    129 }
    130 
    131 ChromeSyncExtensionFunction::~ChromeSyncExtensionFunction() {}
    132 
    133 ExtensionFunction::ResponseAction ChromeSyncExtensionFunction::Run() {
    134   return RespondNow(RunSync() ? ArgumentList(results_.Pass()) : Error(error_));
    135 }
    136 
    137 // static
    138 bool ChromeSyncExtensionFunction::ValidationFailure(
    139     ChromeSyncExtensionFunction* function) {
    140   return false;
    141 }
    142