1// Copyright 2014 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_details.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.h" 16#include "extensions/browser/extension_function_dispatcher.h" 17 18using content::WebContents; 19using content::RenderViewHost; 20using extensions::WindowController; 21 22ChromeExtensionFunctionDetails::ChromeExtensionFunctionDetails( 23 UIThreadExtensionFunction* function) 24 : function_(function) { 25} 26 27ChromeExtensionFunctionDetails::~ChromeExtensionFunctionDetails() { 28} 29 30Profile* ChromeExtensionFunctionDetails::GetProfile() const { 31 return Profile::FromBrowserContext(function_->browser_context()); 32} 33 34bool ChromeExtensionFunctionDetails::CanOperateOnWindow( 35 const extensions::WindowController* window_controller) const { 36 // |extension()| is NULL for unit tests only. 37 if (function_->extension() != NULL && 38 !window_controller->IsVisibleToExtension(function_->extension())) { 39 return false; 40 } 41 42 if (GetProfile() == window_controller->profile()) 43 return true; 44 45 if (!function_->include_incognito()) 46 return false; 47 48 return GetProfile()->HasOffTheRecordProfile() && 49 GetProfile()->GetOffTheRecordProfile() == window_controller->profile(); 50} 51 52// TODO(stevenjb): Replace this with GetExtensionWindowController(). 53Browser* ChromeExtensionFunctionDetails::GetCurrentBrowser() const { 54 // If the delegate has an associated browser, return it. 55 if (function_->dispatcher()) { 56 extensions::WindowController* window_controller = 57 function_->dispatcher()->delegate()->GetExtensionWindowController(); 58 if (window_controller) { 59 Browser* browser = window_controller->GetBrowser(); 60 if (browser) 61 return browser; 62 } 63 } 64 65 // Otherwise, try to default to a reasonable browser. If |include_incognito_| 66 // is true, we will also search browsers in the incognito version of this 67 // profile. Note that the profile may already be incognito, in which case 68 // we will search the incognito version only, regardless of the value of 69 // |include_incognito|. Look only for browsers on the active desktop as it is 70 // preferable to pretend no browser is open then to return a browser on 71 // another desktop. 72 if (function_->render_view_host()) { 73 Profile* profile = Profile::FromBrowserContext( 74 function_->render_view_host()->GetProcess()->GetBrowserContext()); 75 Browser* browser = chrome::FindAnyBrowser( 76 profile, function_->include_incognito(), chrome::GetActiveDesktop()); 77 if (browser) 78 return browser; 79 } 80 81 // NOTE(rafaelw): This can return NULL in some circumstances. In particular, 82 // a background_page onload chrome.tabs api call can make it into here 83 // before the browser is sufficiently initialized to return here, or 84 // all of this profile's browser windows may have been closed. 85 // A similar situation may arise during shutdown. 86 // TODO(rafaelw): Delay creation of background_page until the browser 87 // is available. http://code.google.com/p/chromium/issues/detail?id=13284 88 return NULL; 89} 90 91extensions::WindowController* 92ChromeExtensionFunctionDetails::GetExtensionWindowController() const { 93 // If the delegate has an associated window controller, return it. 94 if (function_->dispatcher()) { 95 extensions::WindowController* window_controller = 96 function_->dispatcher()->delegate()->GetExtensionWindowController(); 97 if (window_controller) 98 return window_controller; 99 } 100 101 return extensions::WindowControllerList::GetInstance() 102 ->CurrentWindowForFunction(*this); 103} 104 105content::WebContents* 106ChromeExtensionFunctionDetails::GetAssociatedWebContents() { 107 content::WebContents* web_contents = function_->GetAssociatedWebContents(); 108 if (web_contents) 109 return web_contents; 110 111 Browser* browser = GetCurrentBrowser(); 112 if (!browser) 113 return NULL; 114 return browser->tab_strip_model()->GetActiveWebContents(); 115} 116