summaryrefslogtreecommitdiffstats
path: root/extensions/browser/app_window/app_window_registry.h
blob: d273fbb131c14d62b8e91269f655058e4965b6a3 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright 2014 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 EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_REGISTRY_H_
#define EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_REGISTRY_H_

#include <list>
#include <set>
#include <string>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "ui/gfx/native_widget_types.h"

namespace content {
class BrowserContext;
class DevToolsAgentHost;
class WebContents;
}

namespace extensions {

class AppWindow;

// The AppWindowRegistry tracks the AppWindows for all platform apps for a
// particular browser context.
class AppWindowRegistry : public KeyedService {
 public:
  class Observer {
   public:
    // Called just after a app window was added.
    virtual void OnAppWindowAdded(AppWindow* app_window);
    // Called when the window icon changes.
    virtual void OnAppWindowIconChanged(AppWindow* app_window);
    // Called just after a app window was removed.
    virtual void OnAppWindowRemoved(AppWindow* app_window);
    // Called just after a app window was hidden. This is different from
    // window visibility as a minimize does not hide a window, but does make
    // it not visible.
    virtual void OnAppWindowHidden(AppWindow* app_window);
    // Called just after a app window was shown.
    virtual void OnAppWindowShown(AppWindow* app_window, bool was_hidden);
    // Called just after a app window was activated.
    virtual void OnAppWindowActivated(AppWindow* app_window);

   protected:
    virtual ~Observer();
  };

  typedef std::list<AppWindow*> AppWindowList;
  typedef AppWindowList::const_iterator const_iterator;
  typedef std::set<std::string> InspectedWindowSet;

  explicit AppWindowRegistry(content::BrowserContext* context);
  ~AppWindowRegistry() override;

  // Returns the instance for the given browser context, or NULL if none. This
  // is a convenience wrapper around
  // AppWindowRegistry::Factory::GetForBrowserContext().
  static AppWindowRegistry* Get(content::BrowserContext* context);

  void AddAppWindow(AppWindow* app_window);
  void AppWindowIconChanged(AppWindow* app_window);
  // Called by |app_window| when it is activated.
  void AppWindowActivated(AppWindow* app_window);
  void AppWindowHidden(AppWindow* app_window);
  void AppWindowShown(AppWindow* app_window, bool was_hidden);
  void RemoveAppWindow(AppWindow* app_window);

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Returns a set of windows owned by the application identified by app_id.
  AppWindowList GetAppWindowsForApp(const std::string& app_id) const;
  const AppWindowList& app_windows() const { return app_windows_; }

  // Close all app windows associated with an app.
  void CloseAllAppWindowsForApp(const std::string& app_id);

  // Helper functions to find app windows with particular attributes.
  AppWindow* GetAppWindowForWebContents(
      const content::WebContents* web_contents) const;
  AppWindow* GetAppWindowForNativeWindow(gfx::NativeWindow window) const;
  // Returns an app window for the given app, or NULL if no app windows are
  // open. If there is a window for the given app that is active, that one will
  // be returned, otherwise an arbitrary window will be returned.
  AppWindow* GetCurrentAppWindowForApp(const std::string& app_id) const;
  // Returns an app window for the given app and window key, or NULL if no app
  // window with the key are open. If there is a window for the given app and
  // key that is active, that one will be returned, otherwise an arbitrary
  // window will be returned.
  AppWindow* GetAppWindowForAppAndKey(const std::string& app_id,
                                      const std::string& window_key) const;

  // Returns whether a AppWindow's ID was last known to have a DevToolsAgent
  // attached to it, which should be restored during a reload of a corresponding
  // newly created |web_contents|.
  bool HadDevToolsAttached(content::WebContents* web_contents) const;

  class Factory : public BrowserContextKeyedServiceFactory {
   public:
    static AppWindowRegistry* GetForBrowserContext(
        content::BrowserContext* context,
        bool create);

    static Factory* GetInstance();

   private:
    friend struct base::DefaultSingletonTraits<Factory>;

    Factory();
    ~Factory() override;

    // BrowserContextKeyedServiceFactory
    KeyedService* BuildServiceInstanceFor(
        content::BrowserContext* context) const override;
    bool ServiceIsCreatedWithBrowserContext() const override;
    bool ServiceIsNULLWhileTesting() const override;
    content::BrowserContext* GetBrowserContextToUse(
        content::BrowserContext* context) const override;
  };

 protected:
  void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached);

 private:
  // Ensures the specified |app_window| is included in |app_windows_|.
  // Otherwise adds |app_window| to the back of |app_windows_|.
  void AddAppWindowToList(AppWindow* app_window);

  // Bring |app_window| to the front of |app_windows_|. If it is not in the
  // list, add it first.
  void BringToFront(AppWindow* app_window);

  // Create a key that identifies an AppWindow across App reloads. If the window
  // was given an id in CreateParams, the key is the extension id, a colon
  // separator, and the AppWindow's |id|. If there is no |id|, the
  // chrome-extension://extension-id/page.html URL will be used. If the
  // WebContents is not for a AppWindow, return an empty string.
  std::string GetWindowKeyForWebContents(
      content::WebContents* web_contents) const;

  content::BrowserContext* context_;
  AppWindowList app_windows_;
  InspectedWindowSet inspected_windows_;
  base::ObserverList<Observer> observers_;
  base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_REGISTRY_H_