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 BASE_EVENT_RECORDER_H_
6#define BASE_EVENT_RECORDER_H_
7
8#include "base/base_export.h"
9#include "base/basictypes.h"
10#include "build/build_config.h"
11
12#if defined(OS_WIN)
13#include <stdio.h>
14#include <string.h>
15#include <windows.h>
16#endif
17
18namespace base {
19
20class FilePath;
21
22// A class for recording and playing back keyboard and mouse input events.
23//
24// Note - if you record events, and the playback with the windows in
25//        different sizes or positions, the playback will fail.  When
26//        recording and playing, you should move the relevant windows
27//        to constant sizes and locations.
28// TODO(mbelshe) For now this is a singleton.  I believe that this class
29//        could be easily modified to:
30//             support two simultaneous recorders
31//             be playing back events while already recording events.
32//        Why?  Imagine if the product had a "record a macro" feature.
33//        You might be recording globally, while recording or playing back
34//        a macro.  I don't think two playbacks make sense.
35class BASE_EXPORT EventRecorder {
36 public:
37  // Get the singleton EventRecorder.
38  // We can only handle one recorder/player at a time.
39  static EventRecorder* current() {
40    if (!current_)
41      current_ = new EventRecorder();
42    return current_;
43  }
44
45  // Starts recording events.
46  // Will clobber the file if it already exists.
47  // Returns true on success, or false if an error occurred.
48  bool StartRecording(const FilePath& filename);
49
50  // Stops recording.
51  void StopRecording();
52
53  // Is the EventRecorder currently recording.
54  bool is_recording() const { return is_recording_; }
55
56  // Plays events previously recorded.
57  // Returns true on success, or false if an error occurred.
58  bool StartPlayback(const FilePath& filename);
59
60  // Stops playback.
61  void StopPlayback();
62
63  // Is the EventRecorder currently playing.
64  bool is_playing() const { return is_playing_; }
65
66#if defined(OS_WIN)
67  // C-style callbacks for the EventRecorder.
68  // Used for internal purposes only.
69  LRESULT RecordWndProc(int nCode, WPARAM wParam, LPARAM lParam);
70  LRESULT PlaybackWndProc(int nCode, WPARAM wParam, LPARAM lParam);
71#endif
72
73 private:
74  // Create a new EventRecorder.  Events are saved to the file filename.
75  // If the file already exists, it will be deleted before recording
76  // starts.
77  EventRecorder()
78      : is_recording_(false),
79        is_playing_(false),
80#if defined(OS_WIN)
81        journal_hook_(NULL),
82        file_(NULL),
83#endif
84        playback_first_msg_time_(0),
85        playback_start_time_(0) {
86#if defined(OS_WIN)
87    memset(&playback_msg_, 0, sizeof(playback_msg_));
88#endif
89  }
90  ~EventRecorder();
91
92  static EventRecorder* current_;  // Our singleton.
93
94  bool is_recording_;
95  bool is_playing_;
96#if defined(OS_WIN)
97  HHOOK journal_hook_;
98  FILE* file_;
99  EVENTMSG playback_msg_;
100#endif
101  int playback_first_msg_time_;
102  int playback_start_time_;
103
104  DISALLOW_COPY_AND_ASSIGN(EventRecorder);
105};
106
107}  // namespace base
108
109#endif // BASE_EVENT_RECORDER_H_
110