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 8 #include <map> 9 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" 16 17 // Template trick so that AutomationResourceTracker can be used with non-pointer 18 // types. 19 template <class T> 20 struct AutomationResourceTraits { 21 typedef T ValueType; 22 }; 23 24 template <class T> 25 struct AutomationResourceTraits<T*> { 26 typedef T ValueType; 27 }; 28 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 { 32 public: 33 explicit AutomationResourceTrackerImpl(IPC::Sender* sender); 34 virtual ~AutomationResourceTrackerImpl(); 35 36 protected: 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; 42 43 int AddImpl(const void* resource); 44 void RemoveImpl(const void* resource); 45 int GenerateHandle(); 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); 51 52 private: 53 typedef std::map<const void*, int> ResourceToHandleMap; 54 typedef std::map<int, const void*> HandleToResourceMap; 55 56 ResourceToHandleMap resource_to_handle_; 57 HandleToResourceMap handle_to_resource_; 58 59 IPC::Sender* sender_; 60 61 DISALLOW_COPY_AND_ASSIGN(AutomationResourceTrackerImpl); 62 }; 63 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. 69 template <class T> 70 class AutomationResourceTracker : public AutomationResourceTrackerImpl, 71 public content::NotificationObserver { 72 public: 73 explicit AutomationResourceTracker(IPC::Sender* automation) 74 : AutomationResourceTrackerImpl(automation) {} 75 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; 81 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. 85 int Add(T resource) { 86 return AddImpl(resource); 87 } 88 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) { 92 RemoveImpl(resource); 93 } 94 95 // Returns true if this tracker currently tracks the resource pointed to 96 // by the parameter. 97 bool ContainsResource(T resource) { 98 return ContainsResourceImpl(resource); 99 } 100 101 // Returns true if this tracker currently tracks the given handle. 102 bool ContainsHandle(int handle) { 103 return ContainsHandleImpl(handle); 104 } 105 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))); 111 } 112 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); 117 } 118 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(); 127 128 CloseResource(resource); 129 } 130 131 protected: 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); 138 } 139 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))); 144 } 145 virtual void RemoveObserverTypeProxy(const void* resource) { 146 RemoveObserver(static_cast<T>(const_cast<void*>(resource))); 147 } 148 149 content::NotificationRegistrar registrar_; 150 151 private: 152 DISALLOW_COPY_AND_ASSIGN(AutomationResourceTracker); 153 }; 154 155 #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__ 156