| // Copyright (c) 2006-2008 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/ipc_message.h" |
| #include "chrome/common/notification_service.h" |
| |
| // 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: |
| AutomationResourceTrackerImpl(IPC::Message::Sender* sender) |
| : cleared_mappings_(false), 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 ClearAllMappingsImpl(); |
| void* GetResourceImpl(int handle); |
| int GetHandleImpl(void* resource); |
| void HandleCloseNotification(void* resource); |
| |
| protected: |
| bool cleared_mappings_; |
| typedef std::map<void*, int> ResourceToHandleMap; |
| typedef std::map<int, void*> HandleToResourceMap; |
| ResourceToHandleMap resource_to_handle_; |
| HandleToResourceMap handle_to_resource_; |
| |
| private: |
| DISALLOW_EVIL_CONSTRUCTORS(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, ***and a destructor that calls ClearAllMappings***. |
| template <class T> |
| class AutomationResourceTracker : public NotificationObserver, |
| private AutomationResourceTrackerImpl { |
| public: |
| AutomationResourceTracker(IPC::Message::Sender* automation) |
| : AutomationResourceTrackerImpl(automation) {} |
| |
| virtual ~AutomationResourceTracker() { |
| // NOTE: Be sure to call ClearAllMappings() from the destructor of your |
| // subclass! It can't be called here, because it eventually uses |
| // the subclass's RemoveObserver, which no longer exists by the time |
| // this base class destructor is executed. |
| DCHECK(cleared_mappings_); |
| } |
| |
| // Removes all mappings from this tracker, including unregistering from |
| // any associated resource notifications (via Remove calling RemoveObserver). |
| void ClearAllMappings() { |
| ClearAllMappingsImpl(); |
| } |
| |
| // 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(); |
| |
| HandleCloseNotification(resource); |
| } |
| 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_EVIL_CONSTRUCTORS(AutomationResourceTracker); |
| }; |
| |
| #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__ |