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/location_bar_controller.h" 6 7 #include "chrome/browser/extensions/active_script_controller.h" 8 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 9 #include "chrome/browser/extensions/extension_action_manager.h" 10 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser_finder.h" 12 #include "chrome/browser/ui/browser_window.h" 13 #include "chrome/browser/ui/location_bar/location_bar.h" 14 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" 15 #include "content/public/browser/web_contents.h" 16 #include "extensions/browser/extension_registry.h" 17 #include "extensions/common/feature_switch.h" 18 19 namespace extensions { 20 21 LocationBarController::LocationBarController( 22 content::WebContents* web_contents) 23 : web_contents_(web_contents), 24 browser_context_(web_contents->GetBrowserContext()), 25 action_manager_(ExtensionActionManager::Get(browser_context_)), 26 should_show_page_actions_( 27 !FeatureSwitch::extension_action_redesign()->IsEnabled()), 28 extension_registry_observer_(this) { 29 if (should_show_page_actions_) 30 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 31 } 32 33 LocationBarController::~LocationBarController() { 34 } 35 36 std::vector<ExtensionAction*> LocationBarController::GetCurrentActions() { 37 const ExtensionSet& extensions = 38 ExtensionRegistry::Get(browser_context_)->enabled_extensions(); 39 std::vector<ExtensionAction*> current_actions; 40 if (!should_show_page_actions_) 41 return current_actions; 42 43 ActiveScriptController* active_script_controller = 44 ActiveScriptController::GetForWebContents(web_contents_); 45 for (ExtensionSet::const_iterator iter = extensions.begin(); 46 iter != extensions.end(); 47 ++iter) { 48 // Right now, we can consolidate these actions because we only want to show 49 // one action per extension. If clicking on an active script action ever 50 // has a response, then we will need to split the actions. 51 ExtensionAction* action = action_manager_->GetPageAction(**iter); 52 if (!action && active_script_controller->WantsToRun(iter->get())) { 53 ExtensionActionMap::iterator existing = 54 active_script_actions_.find((*iter)->id()); 55 if (existing != active_script_actions_.end()) { 56 action = existing->second.get(); 57 } else { 58 linked_ptr<ExtensionAction> active_script_action( 59 ExtensionActionManager::Get(browser_context_)-> 60 GetBestFitAction(**iter, ActionInfo::TYPE_PAGE).release()); 61 active_script_action->SetIsVisible( 62 ExtensionAction::kDefaultTabId, true); 63 active_script_actions_[(*iter)->id()] = active_script_action; 64 action = active_script_action.get(); 65 } 66 } 67 68 if (action) 69 current_actions.push_back(action); 70 } 71 72 return current_actions; 73 } 74 75 void LocationBarController::OnExtensionLoaded( 76 content::BrowserContext* browser_context, 77 const Extension* extension) { 78 if (action_manager_->GetPageAction(*extension)) { 79 ExtensionActionAPI::Get(browser_context)-> 80 NotifyPageActionsChanged(web_contents_); 81 } 82 83 // We might also need to update the location bar if the extension can remove 84 // the bookmark star. 85 if (UIOverrides::RemovesBookmarkButton(extension)) { 86 Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); 87 // In a perfect world, this can never be NULL. Unfortunately, since a 88 // LocationBarController is attached to most WebContents, we can't make that 89 // guarantee. 90 if (!browser) 91 return; 92 // window() can be NULL if this is called before CreateBrowserWindow() 93 // completes, and there won't be a location bar if the window has no toolbar 94 // (e.g., and app window). 95 LocationBar* location_bar = 96 browser->window() ? browser->window()->GetLocationBar() : NULL; 97 if (!location_bar) 98 return; 99 location_bar->UpdateBookmarkStarVisibility(); 100 } 101 } 102 103 void LocationBarController::OnExtensionUnloaded( 104 content::BrowserContext* browser_context, 105 const Extension* extension, 106 UnloadedExtensionInfo::Reason reason) { 107 if (action_manager_->GetPageAction(*extension)) { 108 ExtensionActionAPI::Get(browser_context)-> 109 NotifyPageActionsChanged(web_contents_); 110 } 111 } 112 113 } // namespace extensions 114