automation_resource_tracker.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
6#define CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
7#pragma once
8
9#include <map>
10
11#include "base/basictypes.h"
12#include "chrome/common/notification_observer.h"
13#include "chrome/common/notification_registrar.h"
14#include "chrome/common/notification_type.h"
15#include "ipc/ipc_message.h"
16
17template <class T> class Source;
18
19// Template trick so that AutomationResourceTracker can be used with non-pointer
20// types.
21template <class T>
22struct AutomationResourceTraits {
23  typedef T ValueType;
24};
25
26template <class T>
27struct AutomationResourceTraits<T*> {
28  typedef T ValueType;
29};
30
31// This class exists for the sole purpose of allowing some of the implementation
32// of AutomationResourceTracker to live in a .cc file.
33class AutomationResourceTrackerImpl {
34 public:
35  explicit AutomationResourceTrackerImpl(IPC::Message::Sender* sender);
36  virtual ~AutomationResourceTrackerImpl();
37
38  // These need to be implemented in AutomationResourceTracker,
39  // since it needs to call the subclass's type-specific notification
40  // registration functions.
41  virtual void AddObserverTypeProxy(void* resource) = 0;
42  virtual void RemoveObserverTypeProxy(void* resource) = 0;
43
44  int AddImpl(void* resource);
45  void RemoveImpl(void* resource);
46  int GenerateHandle();
47  bool ContainsResourceImpl(void* resource);
48  bool ContainsHandleImpl(int handle);
49  void* GetResourceImpl(int handle);
50  int GetHandleImpl(void* resource);
51  void HandleCloseNotification(void* resource);
52
53 protected:
54  typedef std::map<void*, int> ResourceToHandleMap;
55  typedef std::map<int, void*> HandleToResourceMap;
56  ResourceToHandleMap resource_to_handle_;
57  HandleToResourceMap handle_to_resource_;
58
59 private:
60  DISALLOW_COPY_AND_ASSIGN(AutomationResourceTrackerImpl);
61
62  IPC::Message::Sender* sender_;
63};
64
65// This template defines a superclass for an object that wants to track
66// a particular kind of application resource (like windows or tabs) for
67// automation purposes.  The only things that a subclass should need to
68// define are AddObserver and RemoveObserver for the given resource's
69// close notifications.
70template <class T>
71class AutomationResourceTracker : public NotificationObserver,
72                                  private AutomationResourceTrackerImpl {
73 public:
74  explicit AutomationResourceTracker(IPC::Message::Sender* automation)
75    : AutomationResourceTrackerImpl(automation) {}
76
77  virtual ~AutomationResourceTracker() {
78  }
79
80  // The implementations for these should call the NotificationService
81  // to add and remove this object as an observer for the appropriate
82  // resource closing notification.
83  virtual void AddObserver(T resource) = 0;
84  virtual void RemoveObserver(T resource) = 0;
85
86  // Adds the given resource to this tracker, and returns a handle that
87  // can be used to refer to that resource.  If the resource is already
88  // being tracked, the handle may be the same as one returned previously.
89  int Add(T resource) {
90    return AddImpl(resource);
91  }
92
93  // Removes the given resource from this tracker.  If the resource is not
94  // currently present in the tracker, this is a no-op.
95  void Remove(T resource) {
96    RemoveImpl(resource);
97  }
98
99  // Returns true if this tracker currently tracks the resource pointed to
100  // by the parameter.
101  bool ContainsResource(T resource) {
102    return ContainsResourceImpl(resource);
103  }
104
105  // Returns true if this tracker currently tracks the given handle.
106  bool ContainsHandle(int handle) {
107    return ContainsHandleImpl(handle);
108  }
109
110  // Returns the resource pointer associated with a given handle, or NULL
111  // if that handle is not present in the mapping.
112  T GetResource(int handle) {
113    return static_cast<T>(GetResourceImpl(handle));
114  }
115
116  // Returns the handle associated with a given resource pointer, or 0 if
117  // the resource is not currently in the mapping.
118  int GetHandle(T resource) {
119    return GetHandleImpl(resource);
120  }
121
122  // NotificationObserver implementation--the only thing that this tracker
123  // does in response to notifications is to tell the AutomationProxy
124  // that the associated handle is now invalid.
125  virtual void Observe(NotificationType type,
126                       const NotificationSource& source,
127                       const NotificationDetails& details) {
128     T resource =
129        Source<typename AutomationResourceTraits<T>::ValueType>(source).ptr();
130
131     CloseResource(resource);
132  }
133
134 protected:
135  // Removes |resource| from the tracker, and handles sending the close
136  // notification back to the client. This typically should not be called
137  // directly, unless there is no appropriate notification available
138  // for the resource type.
139  void CloseResource(T resource) {
140    HandleCloseNotification(resource);
141  }
142
143  NotificationRegistrar registrar_;
144
145 private:
146  // These proxy calls from the base Impl class to the template's subclss.
147  virtual void AddObserverTypeProxy(void* resource) {
148    AddObserver(static_cast<T>(resource));
149  }
150  virtual void RemoveObserverTypeProxy(void* resource) {
151    RemoveObserver(static_cast<T>(resource));
152  }
153
154  DISALLOW_COPY_AND_ASSIGN(AutomationResourceTracker);
155};
156
157#endif  // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
158