1 // Copyright (c) 2011 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.
5 #ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
6 #define CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
10 #include "base/basictypes.h"
11 #include "content/public/browser/notification_observer.h"
12 #include "content/public/browser/notification_registrar.h"
13 #include "content/public/browser/notification_source.h"
14 #include "content/public/browser/notification_types.h"
15 #include "ipc/ipc_sender.h"
17 // Template trick so that AutomationResourceTracker can be used with non-pointer
20 struct AutomationResourceTraits
{
25 struct AutomationResourceTraits
<T
*> {
29 // This class exists for the sole purpose of allowing some of the implementation
30 // of AutomationResourceTracker to live in a .cc file.
31 class AutomationResourceTrackerImpl
{
33 explicit AutomationResourceTrackerImpl(IPC::Sender
* sender
);
34 virtual ~AutomationResourceTrackerImpl();
37 // These need to be implemented in AutomationResourceTracker,
38 // since it needs to call the subclass's type-specific notification
39 // registration functions.
40 virtual void AddObserverTypeProxy(const void* resource
) = 0;
41 virtual void RemoveObserverTypeProxy(const void* resource
) = 0;
43 int AddImpl(const void* resource
);
44 void RemoveImpl(const void* resource
);
46 bool ContainsResourceImpl(const void* resource
);
47 bool ContainsHandleImpl(int handle
);
48 const void* GetResourceImpl(int handle
);
49 int GetHandleImpl(const void* resource
);
50 void HandleCloseNotification(const void* resource
);
53 typedef std::map
<const void*, int> ResourceToHandleMap
;
54 typedef std::map
<int, const void*> HandleToResourceMap
;
56 ResourceToHandleMap resource_to_handle_
;
57 HandleToResourceMap handle_to_resource_
;
61 DISALLOW_COPY_AND_ASSIGN(AutomationResourceTrackerImpl
);
64 // This template defines a superclass for an object that wants to track
65 // a particular kind of application resource (like windows or tabs) for
66 // automation purposes. The only things that a subclass should need to
67 // define are AddObserver and RemoveObserver for the given resource's
68 // close notifications.
70 class AutomationResourceTracker
: public AutomationResourceTrackerImpl
,
71 public content::NotificationObserver
{
73 explicit AutomationResourceTracker(IPC::Sender
* automation
)
74 : AutomationResourceTrackerImpl(automation
) {}
76 // The implementations for these should call the NotificationService
77 // to add and remove this object as an observer for the appropriate
78 // resource closing notification.
79 virtual void AddObserver(T resource
) = 0;
80 virtual void RemoveObserver(T resource
) = 0;
82 // Adds the given resource to this tracker, and returns a handle that
83 // can be used to refer to that resource. If the resource is already
84 // being tracked, the handle may be the same as one returned previously.
86 return AddImpl(resource
);
89 // Removes the given resource from this tracker. If the resource is not
90 // currently present in the tracker, this is a no-op.
91 void Remove(T resource
) {
95 // Returns true if this tracker currently tracks the resource pointed to
97 bool ContainsResource(T resource
) {
98 return ContainsResourceImpl(resource
);
101 // Returns true if this tracker currently tracks the given handle.
102 bool ContainsHandle(int handle
) {
103 return ContainsHandleImpl(handle
);
106 // Returns the resource pointer associated with a given handle, or NULL
107 // if that handle is not present in the mapping.
108 // The casts here allow this to compile with both T = Foo and T = const Foo.
109 T
GetResource(int handle
) {
110 return static_cast<T
>(const_cast<void*>(GetResourceImpl(handle
)));
113 // Returns the handle associated with a given resource pointer, or 0 if
114 // the resource is not currently in the mapping.
115 int GetHandle(T resource
) {
116 return GetHandleImpl(resource
);
119 // content::NotificationObserver implementation--the only thing that this
120 // tracker does in response to notifications is to tell the AutomationProxy
121 // that the associated handle is now invalid.
122 virtual void Observe(int type
,
123 const content::NotificationSource
& source
,
124 const content::NotificationDetails
& details
) {
125 T resource
= content::Source
<typename AutomationResourceTraits
<T
>::
126 ValueType
>(source
).ptr();
128 CloseResource(resource
);
132 // Removes |resource| from the tracker, and handles sending the close
133 // notification back to the client. This typically should not be called
134 // directly, unless there is no appropriate notification available
135 // for the resource type.
136 void CloseResource(T resource
) {
137 HandleCloseNotification(resource
);
140 // These proxy calls from the base Impl class to the template's subclss.
141 // The casts here allow this to compile with both T = Foo and T = const Foo.
142 virtual void AddObserverTypeProxy(const void* resource
) {
143 AddObserver(static_cast<T
>(const_cast<void*>(resource
)));
145 virtual void RemoveObserverTypeProxy(const void* resource
) {
146 RemoveObserver(static_cast<T
>(const_cast<void*>(resource
)));
149 content::NotificationRegistrar registrar_
;
152 DISALLOW_COPY_AND_ASSIGN(AutomationResourceTracker
);
155 #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__