1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "ipc/ipc_message.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Template trick so that AutomationResourceTracker can be used with non-pointer
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// types.
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T>
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct AutomationResourceTraits {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef T ValueType;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T>
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct AutomationResourceTraits<T*> {
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef T ValueType;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class exists for the sole purpose of allowing some of the implementation
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of AutomationResourceTracker to live in a .cc file.
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AutomationResourceTrackerImpl {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit AutomationResourceTrackerImpl(IPC::Message::Sender* sender);
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ~AutomationResourceTrackerImpl();
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen protected:
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These need to be implemented in AutomationResourceTracker,
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // since it needs to call the subclass's type-specific notification
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // registration functions.
41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void AddObserverTypeProxy(const void* resource) = 0;
42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void RemoveObserverTypeProxy(const void* resource) = 0;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  int AddImpl(const void* resource);
45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void RemoveImpl(const void* resource);
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GenerateHandle();
47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool ContainsResourceImpl(const void* resource);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ContainsHandleImpl(int handle);
49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const void* GetResourceImpl(int handle);
50513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  int GetHandleImpl(const void* resource);
51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void HandleCloseNotification(const void* resource);
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  typedef std::map<const void*, int> ResourceToHandleMap;
55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  typedef std::map<int, const void*> HandleToResourceMap;
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceToHandleMap resource_to_handle_;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HandleToResourceMap handle_to_resource_;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  IPC::Message::Sender* sender_;
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DISALLOW_COPY_AND_ASSIGN(AutomationResourceTrackerImpl);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This template defines a superclass for an object that wants to track
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a particular kind of application resource (like windows or tabs) for
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// automation purposes.  The only things that a subclass should need to
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// define are AddObserver and RemoveObserver for the given resource's
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// close notifications.
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T>
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass AutomationResourceTracker : public AutomationResourceTrackerImpl,
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                  public NotificationObserver {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit AutomationResourceTracker(IPC::Message::Sender* automation)
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : AutomationResourceTrackerImpl(automation) {}
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The implementations for these should call the NotificationService
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to add and remove this object as an observer for the appropriate
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // resource closing notification.
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void AddObserver(T resource) = 0;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void RemoveObserver(T resource) = 0;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Adds the given resource to this tracker, and returns a handle that
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // can be used to refer to that resource.  If the resource is already
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // being tracked, the handle may be the same as one returned previously.
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int Add(T resource) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return AddImpl(resource);
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Removes the given resource from this tracker.  If the resource is not
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // currently present in the tracker, this is a no-op.
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Remove(T resource) {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RemoveImpl(resource);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if this tracker currently tracks the resource pointed to
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // by the parameter.
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ContainsResource(T resource) {
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ContainsResourceImpl(resource);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns true if this tracker currently tracks the given handle.
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ContainsHandle(int handle) {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ContainsHandleImpl(handle);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the resource pointer associated with a given handle, or NULL
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // if that handle is not present in the mapping.
109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // The casts here allow this to compile with both T = Foo and T = const Foo.
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  T GetResource(int handle) {
111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return static_cast<T>(const_cast<void*>(GetResourceImpl(handle)));
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the handle associated with a given resource pointer, or 0 if
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the resource is not currently in the mapping.
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetHandle(T resource) {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return GetHandleImpl(resource);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NotificationObserver implementation--the only thing that this tracker
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // does in response to notifications is to tell the AutomationProxy
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that the associated handle is now invalid.
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details) {
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     T resource =
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        Source<typename AutomationResourceTraits<T>::ValueType>(source).ptr();
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     CloseResource(resource);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Removes |resource| from the tracker, and handles sending the close
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification back to the client. This typically should not be called
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // directly, unless there is no appropriate notification available
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for the resource type.
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CloseResource(T resource) {
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HandleCloseNotification(resource);
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These proxy calls from the base Impl class to the template's subclss.
142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // The casts here allow this to compile with both T = Foo and T = const Foo.
143513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void AddObserverTypeProxy(const void* resource) {
144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    AddObserver(static_cast<T>(const_cast<void*>(resource)));
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void RemoveObserverTypeProxy(const void* resource) {
147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    RemoveObserver(static_cast<T>(const_cast<void*>(resource)));
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NotificationRegistrar registrar_;
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AutomationResourceTracker);
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_TRACKER_H__
157