summaryrefslogtreecommitdiffstats
path: root/chrome/browser/background/background_application_list_model.h
blob: 0dbc407704699a6a7012f3736a8b8ddf2e9297c6 (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
158
// 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_BACKGROUND_BACKGROUND_APPLICATION_LIST_MODEL_H_
#define CHROME_BROWSER_BACKGROUND_BACKGROUND_APPLICATION_LIST_MODEL_H_

#include <map>
#include <string>

#include "base/basictypes.h"
#include "base/observer_list.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/common/extension.h"

class Profile;

namespace gfx {
class ImageSkia;
}

// Model for list of Background Applications associated with a Profile (i.e.
// extensions with kBackgroundPermission set, or hosted apps with a
// BackgroundContents).
class BackgroundApplicationListModel : public content::NotificationObserver {
 public:
  // Observer is informed of changes to the model.  Users of the
  // BackgroundApplicationListModel should anticipate that associated data,
  // e. g. the Icon, may exist and yet not be immediately available.  When the
  // data becomes available, OnApplicationDataChanged will be invoked for all
  // Observers of the model.
  class Observer {
   public:
    // Invoked when data that the model associates with the extension, such as
    // the Icon, has changed.
    virtual void OnApplicationDataChanged(
        const extensions::Extension* extension,
        Profile* profile);

    // Invoked when the model detects a previously unknown extension and/or when
    // it no longer detects a previously known extension.
    virtual void OnApplicationListChanged(Profile* profile);

   protected:
    virtual ~Observer();
  };

  // Create a new model associated with profile.
  explicit BackgroundApplicationListModel(Profile* profile);

  virtual ~BackgroundApplicationListModel();

  // Associate observer with this model.
  void AddObserver(Observer* observer);

  // Return the icon associated with |extension| or NULL.  NULL indicates either
  // that there is no icon associated with the extension, or that a pending
  // task to retrieve the icon has not completed.  See the Observer class above.
  //
  // NOTE: The model manages the ImageSkia result, that is it "owns" the memory,
  //       releasing it if the associated background application is unloaded.
  // NOTE: All icons are currently sized as
  //       ExtensionIconSet::EXTENSION_ICON_BITTY.
  const gfx::ImageSkia* GetIcon(const extensions::Extension* extension);

  // Return the position of |extension| within this list model.
  int GetPosition(const extensions::Extension* extension) const;

  // Return the extension at the specified |position| in this list model.
  const extensions::Extension* GetExtension(int position) const;

  // Returns true if the passed extension is a background app.
  static bool IsBackgroundApp(const extensions::Extension& extension,
                              Profile* profile);

  // Dissociate observer from this model.
  void RemoveObserver(Observer* observer);

  extensions::ExtensionList::const_iterator begin() const {
    return extensions_.begin();
  }

  extensions::ExtensionList::const_iterator end() const {
    return extensions_.end();
  }

  size_t size() const {
    return extensions_.size();
  }

 private:
  // Contains data associated with a background application that is not
  // represented by the Extension class.
  class Application;

  // Associates extension id strings with Application objects.
  typedef std::map<std::string, Application*> ApplicationMap;

  // Identifies and caches data related to the extension.
  void AssociateApplicationData(const extensions::Extension* extension);

  // Clears cached data related to |extension|.
  void DissociateApplicationData(const extensions::Extension* extension);

  // Returns the Application associated with |extension| or NULL.
  const Application* FindApplication(
      const extensions::Extension* extension) const;

  // Returns the Application associated with |extension| or NULL.
  Application* FindApplication(const extensions::Extension* extension);

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

  // Notifies observers that some of the data associated with this background
  // application, e. g. the Icon, has changed.
  void SendApplicationDataChangedNotifications(
      const extensions::Extension* extension);

  // Notifies observers that at least one background application has been added
  // or removed.
  void SendApplicationListChangedNotifications();

  // Invoked by Observe for NOTIFICATION_EXTENSION_LOADED.
  void OnExtensionLoaded(const extensions::Extension* extension);

  // Invoked by Observe for NOTIFICATION_EXTENSION_UNLOADED.
  void OnExtensionUnloaded(const extensions::Extension* extension);

  // Invoked by Observe for NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED.
  void OnExtensionPermissionsUpdated(
      const extensions::Extension* extension,
      extensions::UpdatedExtensionPermissionsInfo::Reason reason,
      const extensions::PermissionSet* permissions);

  // Refresh the list of background applications and generate notifications.
  void Update();

  // Determines if the given extension has to be considered a "background app"
  // due to its use of PushMessaging. Normally every extension that expectes
  // push messages is classified as "background app", however there are some
  // rare exceptions, so this function implements a whitelist.
  static bool RequiresBackgroundModeForPushMessaging(
      const extensions::Extension& extension);

  ApplicationMap applications_;
  extensions::ExtensionList extensions_;
  ObserverList<Observer> observers_;
  Profile* profile_;
  content::NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(BackgroundApplicationListModel);
};

#endif  // CHROME_BROWSER_BACKGROUND_BACKGROUND_APPLICATION_LIST_MODEL_H_