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 #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