summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/script_badge_controller.h
blob: ec31f22c7e2a6861954e013d7a39f64394ae3567 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_EXTENSIONS_SCRIPT_BADGE_CONTROLLER_H_
#define CHROME_BROWSER_EXTENSIONS_SCRIPT_BADGE_CONTROLLER_H_

#include <map>
#include <set>
#include <string>

#include "base/compiler_specific.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/location_bar_controller.h"
#include "chrome/browser/extensions/script_executor.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"

class ExtensionAction;
class ExtensionService;
class GURL;

namespace base {
class ListValue;
}  // namespace base

namespace IPC {
class Message;
}

namespace extensions {

class Extension;

// A LocationBarController which displays icons whenever a script is executing
// in a tab. It accomplishes this two different ways:
//
// - For content_script declarations, this receives IPCs from the renderer
//   notifying that a content script is running (either on this tab or one of
//   its frames), which is recorded.
// - Observes a ScriptExecutor so that successfully-executed scripts
//   can cause a script badge to appear.
//
// When extension IDs are recorded a NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED
// is sent, and those extensions will be returned from GetCurrentActions until
// the next page navigation.
class ScriptBadgeController
    : public LocationBarController,
      public ScriptExecutor::Observer,
      public TabHelper::ContentScriptObserver,
      public content::WebContentsObserver,
      public content::NotificationObserver {
 public:
  explicit ScriptBadgeController(content::WebContents* web_contents,
                                 ScriptExecutor* script_executor,
                                 TabHelper* tab_helper);
  virtual ~ScriptBadgeController();

  // LocationBarController implementation.
  virtual std::vector<ExtensionAction*> GetCurrentActions() const OVERRIDE;
  virtual void GetAttentionFor(const std::string& extension_id) OVERRIDE;
  virtual Action OnClicked(const std::string& extension_id,
                           int mouse_button) OVERRIDE;
  virtual void NotifyChange() OVERRIDE;

  // ScriptExecutor::Observer implementation.
  virtual void OnExecuteScriptFinished(
      const std::string& extension_id,
      const std::string& error,
      int32 on_page_id,
      const GURL& on_url,
      const base::ListValue& script_result) OVERRIDE;

  // TabHelper::ContentScriptObserver implementation.
  virtual void OnContentScriptsExecuting(
      const content::WebContents* web_contents,
      const ExecutingScriptsMap& extension_ids,
      int32 on_page_id,
      const GURL& on_url) OVERRIDE;

 private:
  // Gets the ExtensionService for |tab_contents_|.
  ExtensionService* GetExtensionService();

  // Gets the current page ID, or -1 if no navigation entry has been committed.
  int32 GetPageID();

  // content::WebContentsObserver implementation.
  virtual void DidNavigateMainFrame(
      const content::LoadCommittedDetails& details,
      const content::FrameNavigateParams& params) OVERRIDE;

  // content::NotificationObserver implementation.
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  // Adds the extension's icon to the list of script badges.  Returns
  // the script badge ExtensionAction that was added, or NULL if
  // extension_id isn't valid.
  ExtensionAction* AddExtensionToCurrentActions(
      const std::string& extension_id);

  // Called when an extension is running script on the current tab,
  // and tries to insert an extension into the relevant collections.
  // Returns true if any change was made.
  bool MarkExtensionExecuting(const std::string& extension_id);

  // Tries to erase an extension from the relevant collections, and returns
  // whether any change was made.
  bool EraseExtension(const Extension* extension);

  // The current extension actions in the order they appeared.  These come from
  // calls to ExecuteScript or getAttention on the current frame.
  std::vector<ExtensionAction*> current_actions_;

  // The extensions that have actions in current_actions_.
  std::set<std::string> extensions_in_current_actions_;

  // Listen to extension unloaded notifications.
  content::NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(ScriptBadgeController);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_SCRIPT_BADGE_CONTROLLER_H_