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