Home | History | Annotate | Download | only in extensions
      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 "base/logging.h"
      8 #include "chrome/browser/extensions/active_script_controller.h"
      9 #include "chrome/browser/extensions/extension_action.h"
     10 #include "chrome/browser/extensions/page_action_controller.h"
     11 #include "chrome/common/extensions/api/extension_action/action_info.h"
     12 #include "content/public/browser/invalidate_type.h"
     13 #include "content/public/browser/navigation_details.h"
     14 #include "content/public/browser/web_contents.h"
     15 #include "extensions/browser/extension_registry.h"
     16 
     17 namespace extensions {
     18 
     19 LocationBarController::LocationBarController(
     20     content::WebContents* web_contents)
     21     : WebContentsObserver(web_contents),
     22       web_contents_(web_contents),
     23       active_script_controller_(new ActiveScriptController(web_contents_)),
     24       page_action_controller_(new PageActionController(web_contents_)),
     25       extension_registry_observer_(this) {
     26   extension_registry_observer_.Add(
     27       ExtensionRegistry::Get(web_contents_->GetBrowserContext()));
     28 }
     29 
     30 LocationBarController::~LocationBarController() {
     31 }
     32 
     33 std::vector<ExtensionAction*> LocationBarController::GetCurrentActions() {
     34   const ExtensionSet& extensions =
     35       ExtensionRegistry::Get(web_contents_->GetBrowserContext())
     36           ->enabled_extensions();
     37   std::vector<ExtensionAction*> current_actions;
     38   for (ExtensionSet::const_iterator iter = extensions.begin();
     39        iter != extensions.end();
     40        ++iter) {
     41     // Right now, we can consolidate these actions because we only want to show
     42     // one action per extension. If clicking on an active script action ever
     43     // has a response, then we will need to split the actions.
     44     ExtensionAction* action =
     45         page_action_controller_->GetActionForExtension(*iter);
     46     if (!action)
     47       action = active_script_controller_->GetActionForExtension(*iter);
     48     if (action)
     49       current_actions.push_back(action);
     50   }
     51 
     52   return current_actions;
     53 }
     54 
     55 LocationBarController::Action LocationBarController::OnClicked(
     56     const ExtensionAction* action) {
     57   const Extension* extension =
     58       ExtensionRegistry::Get(web_contents_->GetBrowserContext())
     59           ->enabled_extensions().GetByID(action->extension_id());
     60   CHECK(extension) << action->extension_id();
     61 
     62   Action page_action =
     63       page_action_controller_->GetActionForExtension(extension) ?
     64           page_action_controller_->OnClicked(extension) :
     65           ACTION_NONE;
     66   Action active_script_action =
     67       active_script_controller_->GetActionForExtension(extension) ?
     68           active_script_controller_->OnClicked(extension) :
     69           ACTION_NONE;
     70 
     71   // PageAction response takes priority.
     72   return page_action != ACTION_NONE ? page_action : active_script_action;
     73 }
     74 
     75 // static
     76 void LocationBarController::NotifyChange(content::WebContents* web_contents) {
     77   web_contents->NotifyNavigationStateChanged(
     78       content::INVALIDATE_TYPE_PAGE_ACTIONS);
     79 }
     80 
     81 void LocationBarController::DidNavigateMainFrame(
     82     const content::LoadCommittedDetails& details,
     83     const content::FrameNavigateParams& params) {
     84   if (details.is_in_page)
     85     return;
     86 
     87   page_action_controller_->OnNavigated();
     88   active_script_controller_->OnNavigated();
     89 }
     90 
     91 void LocationBarController::OnExtensionUnloaded(
     92     content::BrowserContext* browser_context,
     93     const Extension* extension,
     94     UnloadedExtensionInfo::Reason reason) {
     95   bool should_update = false;
     96   if (page_action_controller_->GetActionForExtension(extension)) {
     97     page_action_controller_->OnExtensionUnloaded(extension);
     98     should_update = true;
     99   }
    100   if (active_script_controller_->GetActionForExtension(extension)) {
    101     active_script_controller_->OnExtensionUnloaded(extension);
    102     should_update = true;
    103   }
    104 
    105   if (should_update)
    106     NotifyChange(web_contents());
    107 }
    108 
    109 }  // namespace extensions
    110