summaryrefslogtreecommitdiffstats
path: root/chrome/browser/automation/automation_resource_tracker.h
blob: 58703e772c6a41b9db194eb063afc7388c870fd5 (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) 2010 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_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
#define CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__

#include <map>

#include "base/basictypes.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_type.h"
#include "ipc/ipc_message.h"

template <class T> class Source;

// Template trick so that AutomationResourceTracker can be used with non-pointer
// types.
template <class T>
struct AutomationResourceTraits {
  typedef T ValueType;
};

template <class T>
struct AutomationResourceTraits<T*> {
  typedef T ValueType;
};

// This class exists for the sole purpose of allowing some of the implementation
// of AutomationResourceTracker to live in a .cc file.
class AutomationResourceTrackerImpl {
 public:
  explicit AutomationResourceTrackerImpl(IPC::Message::Sender* sender)
    : sender_(sender) {}

  virtual ~AutomationResourceTrackerImpl() {}

  // These need to be implemented in AutomationResourceTracker,
  // since it needs to call the subclass's type-specific notification
  // registration functions.
  virtual void AddObserverTypeProxy(void* resource) = 0;
  virtual void RemoveObserverTypeProxy(void* resource) = 0;

  int AddImpl(void* resource);
  void RemoveImpl(void* resource);
  int GenerateHandle();
  bool ContainsResourceImpl(void* resource);
  bool ContainsHandleImpl(int handle);
  void* GetResourceImpl(int handle);
  int GetHandleImpl(void* resource);
  void HandleCloseNotification(void* resource);

 protected:
  typedef std::map<void*, int> ResourceToHandleMap;
  typedef std::map<int, void*> HandleToResourceMap;
  ResourceToHandleMap resource_to_handle_;
  HandleToResourceMap handle_to_resource_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AutomationResourceTrackerImpl);

  IPC::Message::Sender* sender_;
};

// This template defines a superclass for an object that wants to track
// a particular kind of application resource (like windows or tabs) for
// automation purposes.  The only things that a subclass should need to
// define are AddObserver and RemoveObserver for the given resource's
// close notifications.
template <class T>
class AutomationResourceTracker : public NotificationObserver,
                                  private AutomationResourceTrackerImpl {
 public:
  explicit AutomationResourceTracker(IPC::Message::Sender* automation)
    : AutomationResourceTrackerImpl(automation) {}

  virtual ~AutomationResourceTracker() {
  }

  // The implementations for these should call the NotificationService
  // to add and remove this object as an observer for the appropriate
  // resource closing notification.
  virtual void AddObserver(T resource) = 0;
  virtual void RemoveObserver(T resource) = 0;

  // Adds the given resource to this tracker, and returns a handle that
  // can be used to refer to that resource.  If the resource is already
  // being tracked, the handle may be the same as one returned previously.
  int Add(T resource) {
    return AddImpl(resource);
  }

  // Removes the given resource from this tracker.  If the resource is not
  // currently present in the tracker, this is a no-op.
  void Remove(T resource) {
    RemoveImpl(resource);
  }

  // Returns true if this tracker currently tracks the resource pointed to
  // by the parameter.
  bool ContainsResource(T resource) {
    return ContainsResourceImpl(resource);
  }

  // Returns true if this tracker currently tracks the given handle.
  bool ContainsHandle(int handle) {
    return ContainsHandleImpl(handle);
  }

  // Returns the resource pointer associated with a given handle, or NULL
  // if that handle is not present in the mapping.
  T GetResource(int handle) {
    return static_cast<T>(GetResourceImpl(handle));
  }

  // Returns the handle associated with a given resource pointer, or 0 if
  // the resource is not currently in the mapping.
  int GetHandle(T resource) {
    return GetHandleImpl(resource);
  }

  // NotificationObserver implementation--the only thing that this tracker
  // does in response to notifications is to tell the AutomationProxy
  // that the associated handle is now invalid.
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
     T resource =
        Source<typename AutomationResourceTraits<T>::ValueType>(source).ptr();

     CloseResource(resource);
  }

 protected:
  // Removes |resource| from the tracker, and handles sending the close
  // notification back to the client. This typically should not be called
  // directly, unless there is no appropriate notification available
  // for the resource type.
  void CloseResource(T resource) {
    HandleCloseNotification(resource);
  }

  NotificationRegistrar registrar_;

 private:
  // These proxy calls from the base Impl class to the template's subclss.
  virtual void AddObserverTypeProxy(void* resource) {
    AddObserver(static_cast<T>(resource));
  }
  virtual void RemoveObserverTypeProxy(void* resource) {
    RemoveObserver(static_cast<T>(resource));
  }

  DISALLOW_COPY_AND_ASSIGN(AutomationResourceTracker);
};

#endif  // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__