blob: cf4220f3d31d3dada2661a28e70baf15fe5c1e11 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string>
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop_proxy.h"
#include "base/optional.h"
#include "cobalt/debug/debug_client.h"
#include "cobalt/debug/debug_server.h"
#include "cobalt/debug/debugger_event_target.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/opaque_handle.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/wrappable.h"
namespace cobalt {
namespace debug {
// Custom interface to communicate with the debugger, modeled after
// chrome.debugger extension API.
class Debugger : public script::Wrappable, public DebugClient::Delegate {
// JavaScript callback to be run when debugger at/detaches.
typedef script::CallbackFunction<void()> AttachCallback;
typedef script::ScriptValue<AttachCallback> AttachCallbackArg;
// JavaScript callback to be run when a debug command has been executed.
typedef script::CallbackFunction<void(base::optional<std::string>)>
typedef script::ScriptValue<CommandCallback> CommandCallbackArg;
// Callback to be run to get the debug server. The debug server is owned by
// the web module to which it connects, and this callback allows this object
// to get a reference to it.
typedef base::Callback<DebugServer*()> GetDebugServerCallback;
// Thread-safe ref-counted struct used to pass asynchronously executed
// command callbacks around. Stores the message loop the callback must be
// executed on as well as the callback itself.
struct CommandCallbackInfo
: public base::RefCountedThreadSafe<CommandCallbackInfo> {
CommandCallbackInfo(Debugger* const debugger, const CommandCallbackArg& cb)
: callback(debugger, cb),
message_loop_proxy(base::MessageLoopProxy::current()) {}
CommandCallbackArg::Reference callback;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
friend class base::RefCountedThreadSafe<CommandCallbackInfo>;
explicit Debugger(const GetDebugServerCallback& get_debug_server_callback);
// Non-standard JavaScript extension API.
void Attach(const AttachCallbackArg& callback);
void Detach(const AttachCallbackArg& callback);
void SendCommand(const std::string& method, const std::string& json_params,
const CommandCallbackArg& callback);
const base::optional<std::string>& last_error() const { return last_error_; }
const scoped_refptr<DebuggerEventTarget>& on_event() const {
return on_event_;
// Called by the debug server with the response of a command on the message
// loop the command was sent from (the message loop of this object).
// Passes the response to the JavaScript callback registered with the command.
void OnCommandResponse(
const scoped_refptr<CommandCallbackInfo>& callback_info,
const base::optional<std::string>& response) const;
// DebugClient::Delegate implementation.
void OnDebugClientEvent(
const std::string& method,
const base::optional<std::string>& json_params) OVERRIDE;
void OnDebugClientDetach(const std::string& reason) OVERRIDE;
// Runs a script command callback with the specified response.
// Should be called from the same message loop as the script command that it
// is a response for.
void RunCommandCallback(
const scoped_refptr<CommandCallbackInfo>& callback_info,
base::optional<std::string> response) const;
// Callback to be run to get a reference to the debug server.
GetDebugServerCallback get_debug_server_callback_;
// Debug client that connects to the server.
scoped_ptr<DebugClient> debug_client_;
// This will be defined if there was an error since the last operation.
// TODO: Chrome implements similar functionality throughout the
// app using the chrome.runtime.lastError object. When we add support for
// Cobalt's equivalent to the runtime extension API, we may wish to consider
// using that and removing this attribute.
base::optional<std::string> last_error_;
// Handler for debugger events.
scoped_refptr<DebuggerEventTarget> on_event_;
} // namespace debug
} // namespace cobalt