| // Copyright (c) 2011 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 BASE_EVENT_RECORDER_H_ |
| #define BASE_EVENT_RECORDER_H_ |
| #pragma once |
| |
| #include "base/base_api.h" |
| #include "base/basictypes.h" |
| #include "build/build_config.h" |
| |
| #if defined(OS_WIN) |
| #include <stdio.h> |
| #include <string.h> |
| #include <windows.h> |
| #endif |
| |
| class FilePath; |
| |
| namespace base { |
| |
| // A class for recording and playing back keyboard and mouse input events. |
| // |
| // Note - if you record events, and the playback with the windows in |
| // different sizes or positions, the playback will fail. When |
| // recording and playing, you should move the relevant windows |
| // to constant sizes and locations. |
| // TODO(mbelshe) For now this is a singleton. I believe that this class |
| // could be easily modified to: |
| // support two simultaneous recorders |
| // be playing back events while already recording events. |
| // Why? Imagine if the product had a "record a macro" feature. |
| // You might be recording globally, while recording or playing back |
| // a macro. I don't think two playbacks make sense. |
| class BASE_API EventRecorder { |
| public: |
| // Get the singleton EventRecorder. |
| // We can only handle one recorder/player at a time. |
| static EventRecorder* current() { |
| if (!current_) |
| current_ = new EventRecorder(); |
| return current_; |
| } |
| |
| // Starts recording events. |
| // Will clobber the file if it already exists. |
| // Returns true on success, or false if an error occurred. |
| bool StartRecording(const FilePath& filename); |
| |
| // Stops recording. |
| void StopRecording(); |
| |
| // Is the EventRecorder currently recording. |
| bool is_recording() const { return is_recording_; } |
| |
| // Plays events previously recorded. |
| // Returns true on success, or false if an error occurred. |
| bool StartPlayback(const FilePath& filename); |
| |
| // Stops playback. |
| void StopPlayback(); |
| |
| // Is the EventRecorder currently playing. |
| bool is_playing() const { return is_playing_; } |
| |
| #if defined(OS_WIN) |
| // C-style callbacks for the EventRecorder. |
| // Used for internal purposes only. |
| LRESULT RecordWndProc(int nCode, WPARAM wParam, LPARAM lParam); |
| LRESULT PlaybackWndProc(int nCode, WPARAM wParam, LPARAM lParam); |
| #endif |
| |
| private: |
| // Create a new EventRecorder. Events are saved to the file filename. |
| // If the file already exists, it will be deleted before recording |
| // starts. |
| explicit EventRecorder() |
| : is_recording_(false), |
| is_playing_(false), |
| #if defined(OS_WIN) |
| journal_hook_(NULL), |
| file_(NULL), |
| #endif |
| playback_first_msg_time_(0), |
| playback_start_time_(0) { |
| #if defined(OS_WIN) |
| memset(&playback_msg_, 0, sizeof(playback_msg_)); |
| #endif |
| } |
| ~EventRecorder(); |
| |
| static EventRecorder* current_; // Our singleton. |
| |
| bool is_recording_; |
| bool is_playing_; |
| #if defined(OS_WIN) |
| HHOOK journal_hook_; |
| FILE* file_; |
| EVENTMSG playback_msg_; |
| #endif |
| int playback_first_msg_time_; |
| int playback_start_time_; |
| |
| DISALLOW_COPY_AND_ASSIGN(EventRecorder); |
| }; |
| |
| } // namespace base |
| |
| #endif // BASE_EVENT_RECORDER_H_ |