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