Home | History | Annotate | Download | only in automation
      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