1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/location_bar_controller.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/active_script_controller.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_action.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/page_action_controller.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/api/extension_action/action_info.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/invalidate_type.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/web_contents.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace extensions {
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)LocationBarController::LocationBarController(
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    content::WebContents* web_contents)
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : WebContentsObserver(web_contents),
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      web_contents_(web_contents),
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      active_script_controller_(new ActiveScriptController(web_contents_)),
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      page_action_controller_(new PageActionController(web_contents_)),
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      extension_registry_observer_(this) {
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  extension_registry_observer_.Add(
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ExtensionRegistry::Get(web_contents_->GetBrowserContext()));
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)LocationBarController::~LocationBarController() {
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::vector<ExtensionAction*> LocationBarController::GetCurrentActions() {
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const ExtensionSet& extensions =
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistry::Get(web_contents_->GetBrowserContext())
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->enabled_extensions();
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<ExtensionAction*> current_actions;
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (ExtensionSet::const_iterator iter = extensions.begin();
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       iter != extensions.end();
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++iter) {
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Right now, we can consolidate these actions because we only want to show
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // one action per extension. If clicking on an active script action ever
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // has a response, then we will need to split the actions.
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ExtensionAction* action =
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        page_action_controller_->GetActionForExtension(*iter);
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!action)
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      action = active_script_controller_->GetActionForExtension(*iter);
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (action)
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      current_actions.push_back(action);
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return current_actions;
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)LocationBarController::Action LocationBarController::OnClicked(
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ExtensionAction* action) {
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension =
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionRegistry::Get(web_contents_->GetBrowserContext())
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->enabled_extensions().GetByID(action->extension_id());
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CHECK(extension) << action->extension_id();
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Action page_action =
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      page_action_controller_->GetActionForExtension(extension) ?
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          page_action_controller_->OnClicked(extension) :
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ACTION_NONE;
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Action active_script_action =
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      active_script_controller_->GetActionForExtension(extension) ?
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          active_script_controller_->OnClicked(extension) :
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ACTION_NONE;
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // PageAction response takes priority.
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return page_action != ACTION_NONE ? page_action : active_script_action;
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void LocationBarController::NotifyChange(content::WebContents* web_contents) {
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  web_contents->NotifyNavigationStateChanged(
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      content::INVALIDATE_TYPE_PAGE_ACTIONS);
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void LocationBarController::DidNavigateMainFrame(
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::LoadCommittedDetails& details,
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const content::FrameNavigateParams& params) {
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (details.is_in_page)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  page_action_controller_->OnNavigated();
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  active_script_controller_->OnNavigated();
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void LocationBarController::OnExtensionUnloaded(
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    content::BrowserContext* browser_context,
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const Extension* extension,
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    UnloadedExtensionInfo::Reason reason) {
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool should_update = false;
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (page_action_controller_->GetActionForExtension(extension)) {
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    page_action_controller_->OnExtensionUnloaded(extension);
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    should_update = true;
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (active_script_controller_->GetActionForExtension(extension)) {
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    active_script_controller_->OnExtensionUnloaded(extension);
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    should_update = true;
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (should_update)
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    NotifyChange(web_contents());
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace extensions
110