1// Copyright (c) 2013 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 CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_H_
6#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/callback.h"
13#include "base/compiler_specific.h"
14#include "base/memory/ref_counted.h"
15#include "base/values.h"
16#include "content/common/content_export.h"
17
18namespace content {
19
20// Utility classes for processing DevTools remote debugging messages.
21// https://developers.google.com/chrome-developer-tools/docs/debugger-protocol
22class DevToolsProtocol {
23 public:
24  typedef base::Callback<void(const std::string& message)> Notifier;
25
26  class Response;
27
28  class Message : public base::RefCountedThreadSafe<Message> {
29   public:
30    std::string domain() { return domain_; }
31    std::string method() { return method_; }
32    base::DictionaryValue* params() { return params_.get(); }
33    virtual std::string Serialize() = 0;
34
35   protected:
36    friend class base::RefCountedThreadSafe<Message>;
37    virtual ~Message();
38    Message(const std::string& method,
39            base::DictionaryValue* params);
40
41    std::string domain_;
42    std::string method_;
43    scoped_ptr<base::DictionaryValue> params_;
44
45   private:
46    DISALLOW_COPY_AND_ASSIGN(Message);
47  };
48
49  class Command : public Message {
50   public:
51    int id() { return id_; }
52
53    virtual std::string Serialize() OVERRIDE;
54
55    // Creates success response. Takes ownership of |result|.
56    scoped_refptr<Response> SuccessResponse(base::DictionaryValue* result);
57
58    // Creates error response.
59    scoped_refptr<Response> InternalErrorResponse(const std::string& message);
60
61    // Creates error response.
62    scoped_refptr<Response> InvalidParamResponse(const std::string& param);
63
64    // Creates error response.
65    scoped_refptr<Response> NoSuchMethodErrorResponse();
66
67    // Creates async response promise.
68    scoped_refptr<Response> AsyncResponsePromise();
69
70   protected:
71    virtual  ~Command();
72
73   private:
74    friend class DevToolsProtocol;
75    Command(int id, const std::string& method,
76            base::DictionaryValue* params);
77
78    int id_;
79
80    DISALLOW_COPY_AND_ASSIGN(Command);
81  };
82
83  class Response : public base::RefCountedThreadSafe<Response> {
84   public:
85    std::string Serialize();
86
87    bool is_async_promise() { return is_async_promise_; }
88
89   private:
90    friend class base::RefCountedThreadSafe<Response>;
91    friend class Command;
92    friend class DevToolsProtocol;
93    virtual  ~Response();
94
95    Response(int id, base::DictionaryValue* result);
96    Response(int id, int error_code, const std::string& error_message);
97
98    int id_;
99    scoped_ptr<base::DictionaryValue> result_;
100    int error_code_;
101    std::string error_message_;
102    bool is_async_promise_;
103
104    DISALLOW_COPY_AND_ASSIGN(Response);
105  };
106
107  class Notification : public Message {
108   public:
109
110    virtual std::string Serialize() OVERRIDE;
111
112   private:
113    friend class DevToolsProtocol;
114    virtual ~Notification();
115
116    // Takes ownership of |params|.
117    Notification(const std::string& method,
118                 base::DictionaryValue* params);
119
120    DISALLOW_COPY_AND_ASSIGN(Notification);
121  };
122
123  class CONTENT_EXPORT Handler {
124   public:
125    typedef base::Callback<scoped_refptr<DevToolsProtocol::Response>(
126        scoped_refptr<DevToolsProtocol::Command> command)> CommandHandler;
127
128    virtual ~Handler();
129
130    virtual scoped_refptr<DevToolsProtocol::Response> HandleCommand(
131        scoped_refptr<DevToolsProtocol::Command> command);
132
133    void SetNotifier(const Notifier& notifier);
134
135   protected:
136    Handler();
137
138    void RegisterCommandHandler(const std::string& command,
139                                const CommandHandler& handler);
140
141    // Sends notification to the client. Takes ownership of |params|.
142    void SendNotification(const std::string& method,
143                          base::DictionaryValue* params);
144
145    void SendAsyncResponse(scoped_refptr<DevToolsProtocol::Response> response);
146
147    // Sends message to client, the caller is presumed to properly
148    // format the message.
149    void SendRawMessage(const std::string& message);
150
151   private:
152    typedef std::map<std::string, CommandHandler> CommandHandlers;
153
154    Notifier notifier_;
155    CommandHandlers command_handlers_;
156
157    DISALLOW_COPY_AND_ASSIGN(Handler);
158  };
159
160  CONTENT_EXPORT static scoped_refptr<Command> ParseCommand(
161      const std::string& json,
162      std::string* error_response);
163
164  CONTENT_EXPORT static scoped_refptr<Command> CreateCommand(
165      int id,
166      const std::string& method,
167      base::DictionaryValue* params);
168
169  static scoped_refptr<Notification> ParseNotification(
170      const std::string& json);
171
172  static scoped_refptr<Notification> CreateNotification(
173      const std::string& method, base::DictionaryValue* params);
174
175 private:
176  static base::DictionaryValue* ParseMessage(const std::string& json,
177                                             std::string* error_response);
178
179  DevToolsProtocol() {}
180  ~DevToolsProtocol() {}
181};
182
183}  // namespace content
184
185#endif  // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_H_
186