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 IPC_IPC_LOGGING_H_
6#define IPC_IPC_LOGGING_H_
7
8#include "ipc/ipc_message.h"  // For IPC_MESSAGE_LOG_ENABLED.
9
10#ifdef IPC_MESSAGE_LOG_ENABLED
11
12#include <vector>
13
14#include "base/containers/hash_tables.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/singleton.h"
17#include "base/message_loop/message_loop.h"
18#include "ipc/ipc_export.h"
19
20// Logging function. |name| is a string in ASCII and |params| is a string in
21// UTF-8.
22typedef void (*LogFunction)(std::string* name,
23                            const IPC::Message* msg,
24                            std::string* params);
25
26typedef base::hash_map<uint32, LogFunction > LogFunctionMap;
27
28namespace IPC {
29
30class Message;
31class Sender;
32
33// One instance per process.  Needs to be created on the main thread (the UI
34// thread in the browser) but OnPreDispatchMessage/OnPostDispatchMessage
35// can be called on other threads.
36class IPC_EXPORT Logging {
37 public:
38  // Implemented by consumers of log messages.
39  class Consumer {
40   public:
41    virtual void Log(const LogData& data) = 0;
42
43   protected:
44    virtual ~Consumer() {}
45  };
46
47  void SetConsumer(Consumer* consumer);
48
49  ~Logging();
50  static Logging* GetInstance();
51
52  // Enable and Disable are NOT cross-process; they only affect the
53  // current thread/process.  If you want to modify the value for all
54  // processes, perhaps your intent is to call
55  // g_browser_process->SetIPCLoggingEnabled().
56  void Enable();
57  void Disable();
58  bool Enabled() const { return enabled_; }
59
60  // Called by child processes to give the logger object the channel to send
61  // logging data to the browser process.
62  void SetIPCSender(Sender* sender);
63
64  // Called in the browser process when logging data from a child process is
65  // received.
66  void OnReceivedLoggingMessage(const Message& message);
67
68  void OnSendMessage(Message* message, const std::string& channel_id);
69  void OnPreDispatchMessage(const Message& message);
70  void OnPostDispatchMessage(const Message& message,
71                             const std::string& channel_id);
72
73  // Like the *MsgLog functions declared for each message class, except this
74  // calls the correct one based on the message type automatically.  Defined in
75  // ipc_logging.cc.
76  static void GetMessageText(uint32 type, std::string* name,
77                             const Message* message, std::string* params);
78
79  static void set_log_function_map(LogFunctionMap* functions) {
80    log_function_map_ = functions;
81  }
82
83  static LogFunctionMap* log_function_map() {
84    return log_function_map_;
85  }
86
87 private:
88  typedef enum {
89    ANSI_COLOR_RESET = -1,
90    ANSI_COLOR_BLACK,
91    ANSI_COLOR_RED,
92    ANSI_COLOR_GREEN,
93    ANSI_COLOR_YELLOW,
94    ANSI_COLOR_BLUE,
95    ANSI_COLOR_MAGENTA,
96    ANSI_COLOR_CYAN,
97    ANSI_COLOR_WHITE
98  } ANSIColor;
99  const char* ANSIEscape(ANSIColor color);
100  ANSIColor DelayColor(double delay);
101
102  friend struct DefaultSingletonTraits<Logging>;
103  Logging();
104
105  void OnSendLogs();
106  void Log(const LogData& data);
107
108  bool enabled_;
109  bool enabled_on_stderr_;  // only used on POSIX for now
110  bool enabled_color_; // only used on POSIX for now
111
112  std::vector<LogData> queued_logs_;
113  bool queue_invoke_later_pending_;
114
115  Sender* sender_;
116  base::MessageLoop* main_thread_;
117
118  Consumer* consumer_;
119
120  static LogFunctionMap* log_function_map_;
121};
122
123}  // namespace IPC
124
125#endif // IPC_MESSAGE_LOG_ENABLED
126
127#endif  // IPC_IPC_LOGGING_H_
128