浏览代码

platform meesage cpp

/siyaoH-1.17-PlatformMessage
siyao 4 年前
当前提交
55b07fc4
共有 51 个文件被更改,包括 4218 次插入84 次删除
  1. 131
      com.unity.uiwidgets/Runtime/services/platform_channel.cs
  2. 81
      com.unity.uiwidgets/Runtime/services/system_channels.cs
  3. 45
      engine/Build.bee.cs
  4. 16
      engine/src/shell/platform/embedder/embedder.h
  5. 198
      engine/src/shell/platform/unity/windows/text_input_plugin.cc
  6. 49
      engine/src/shell/platform/unity/windows/text_input_plugin.h
  7. 313
      engine/src/shell/platform/unity/windows/uiwidgets_windows.cc
  8. 69
      engine/src/shell/platform/unity/windows/window_state.h
  9. 93
      engine/src/shell/platform/common/cpp/client_wrapper/basic_message_channel_unittests.cc
  10. 105
      engine/src/shell/platform/common/cpp/client_wrapper/byte_stream_wrappers.h
  11. 330
      engine/src/shell/platform/common/cpp/client_wrapper/encodable_value_unittests.cc
  12. 45
      engine/src/shell/platform/common/cpp/client_wrapper/engine_method_result.cc
  13. 108
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/basic_message_channel.h
  14. 34
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/binary_messenger.h
  15. 428
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/encodable_value.h
  16. 70
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/engine_method_result.h
  17. 32
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_message_codec.h
  18. 40
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_method_codec.h
  19. 16
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_type.h
  20. 48
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/message_codec.h
  21. 33
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_call.h
  22. 82
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_channel.h
  23. 70
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_codec.h
  24. 42
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_result.h
  25. 48
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registrar.h
  26. 26
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registry.h
  27. 32
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_message_codec.h
  28. 40
      engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_method_codec.h
  29. 70
      engine/src/shell/platform/common/cpp/client_wrapper/json_message_codec.cc
  30. 140
      engine/src/shell/platform/common/cpp/client_wrapper/json_method_codec.cc
  31. 23
      engine/src/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc
  32. 94
      engine/src/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc
  33. 160
      engine/src/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc
  34. 95
      engine/src/shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc
  35. 383
      engine/src/shell/platform/common/cpp/client_wrapper/standard_codec.cc
  36. 54
      engine/src/shell/platform/common/cpp/client_wrapper/standard_codec_serializer.h
  37. 173
      engine/src/shell/platform/common/cpp/client_wrapper/standard_message_codec_unittests.cc
  38. 105
      engine/src/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc
  39. 58
      engine/src/shell/platform/common/cpp/incoming_message_dispatcher.cc
  40. 78
      engine/src/shell/platform/common/cpp/incoming_message_dispatcher.h
  41. 24
      engine/src/shell/platform/common/cpp/public/uiwidgets_export.h
  42. 61
      engine/src/shell/platform/common/cpp/public/uiwidgets_messenger.h
  43. 28
      engine/src/shell/platform/common/cpp/public/uiwidgets_plugin_registrar.h
  44. 132
      engine/src/shell/platform/unity/windows/public/uiwidgets_windows.h

131
com.unity.uiwidgets/Runtime/services/platform_channel.cs


namespace Unity.UIWidgets.service {
public delegate Future<object> Handler(MethodCall call);
public class MethodChannel {
public MethodChannel(string name, MethodCodec codec, BinaryMessenger binaryMessenger = null) {
codec = new StandardMethodCodec();

}
public readonly BinaryMessenger _binaryMessenger;
/*public void setMethodCallHandler( Handler handler) {
binaryMessenger.setMessageHandler(
name,

/*
public Future<T> _invokeMethod<T>(string method, bool missingOk, object arguments ) {
// async
D.assert(method != null);
// await
///???
var result = binaryMessenger.send(
name,
codec.encodeMethodCall(new MethodCall(method, arguments))
);
if (result == null) {
if (missingOk) {
return null;
}
throw new MissingPluginException($"No implementation found for method $method on channel {name}");
}
return (Future<T>)codec.decodeEnvelope(result);
}
public Future _invokeMethod(string method, bool missingOk, object arguments ) {
// async
D.assert(method != null);
// await
byte[] result = binaryMessenger.send(
// public Future<T> _invokeMethod<T>(string method, bool missingOk, object arguments ) {
// // async
// D.assert(method != null);
// // await
// ///???
// var result = binaryMessenger.send(
// name,
// codec.encodeMethodCall(new MethodCall(method, arguments))
// );
// return result.then_<byte[]>(r => {
// if (result == null) {
// if (missingOk) {
// return FutureOr.nil;
// }
// throw new MissingPluginException($"No implementation found for method $method on channel {name}");
// }
// return FutureOr.value(r);
// }).to<T>();
// }
public Future _invokeMethod(string method, bool missingOk, object arguments) {
D.assert(method != null);
return binaryMessenger.send(
if (result == null) {
if (missingOk) {
return null;
}
throw new MissingPluginException($"No implementation found for method $method on channel {name}");
}
return (Future)codec.decodeEnvelope(result);
public virtual Future<T> invokeMethod<T>(string method, object arguments = null) {
return _invokeMethod<T>(method, missingOk: false, arguments: arguments);
// public virtual Future<T> invokeMethod<T>(string method, object arguments = null) {
// return _invokeMethod<T>(method, missingOk: false, arguments: arguments);
// }
public virtual Future invokeMethod(string method, object arguments = null) {
return _invokeMethod(method, missingOk: false, arguments: arguments);
public virtual Future invokeMethod(string method, object arguments = null) {
return _invokeMethod(method, missingOk: false, arguments: arguments);
}*/
// Future<List<T>> invokeListMethod<T>(String method, object arguments ) {
// var result = invokeMethod<List<dynamic>>(method, arguments).to<List<T>>();
// return result;
// }
/*public class OptionalMethodChannel : MethodChannel {
public OptionalMethodChannel(string name, MethodCodec codec, BinaryMessenger binaryMessenger = null) : base(name, codec)
{
public class OptionalMethodChannel : MethodChannel {
public OptionalMethodChannel(String name, MethodCodec codec = null)
: base(name, codec) {
public override Future<T> invokeMethod<T>(string method, object arguments = null) {
return base._invokeMethod<T>(method, missingOk: true, arguments: arguments);
public static OptionalMethodChannel create(String name, MethodCodec codec = null) {
codec = codec ?? new StandardMethodCodec();
return new OptionalMethodChannel(name, codec);
public override Future invokeMethod(string method, object arguments = null) {
// public override Future<T> invokeMethod<T>(String method, object arguments =null) {
// return base._invokeMethod<T>(method, missingOk: true, arguments: arguments);
// }
public override Future invokeMethod(String method, object arguments = null) {
}*/
// public override Future<List<T>> invokeListMethod<T>(String method, object arguments ) {
// List<dynamic> result = await invokeMethod<List<T>>(method, arguments);
// return result.cast<T>();
// }
//
// public override Future<Dictionary<K, V>> invokeMapMethod<K, V>(String method, object arguments = null) {
// Dictionary<object, object> result = await invokeMethod<Dictionary<object, dynamic>>(method, arguments);
// return result.cast<K, V>();
// }
}
// class BasicMessageChannel<T> {
// /// Creates a [BasicMessageChannel] with the specified [name], [codec] and [binaryMessenger].
// ///
// /// The [name] and [codec] arguments cannot be null. The default [ServicesBinding.defaultBinaryMessenger]
// /// instance is used if [binaryMessenger] is null.
// const BasicMessageChannel(this.name, this.codec, { BinaryMessenger binaryMessenger })
// : assert(name != null),
// assert(codec != null),
// _binaryMessenger = binaryMessenger;
//
// /// The logical channel on which communication happens, not null.
// final String name;
//
// /// The message codec used by this channel, not null.
// final MessageCodec<T> codec;
//
// /// The messenger which sends the bytes for this channel, not null.
// BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; // ignore: deprecated_member_use_from_same_package
// final BinaryMessenger _binaryMessenger;
//
// /// Sends the specified [message] to the platform plugins on this channel.
// ///
// /// Returns a [Future] which completes to the received response, which may
// /// be null.
// Future<T> send(T message) async {
// return codec.decodeMessage(await binaryMessenger.send(name, codec.encodeMessage(message)));
// }
}

81
com.unity.uiwidgets/Runtime/services/system_channels.cs


using UnityEngine;
namespace Unity.UIWidgets.service {
/*class SystemChannels {
class SystemChannels {
public static MethodChannel navigation = new MethodChannel(
"flutter/navigation",
JSONMethodCodec()
);
public static MethodChannel platform = new OptionalMethodChannel(
"flutter/platform",
JSONMethodCodec()
);
public static MethodChannel textInput = new OptionalMethodChannel(
"flutter/textinput",
JSONMethodCodec()
);
public static BasicMessageChannel<object> keyEvent = BasicMessageChannel<object>(
"flutter/keyevent",
JSONMessageCodec()
// public static MethodChannel navigation = new MethodChannel(
// "flutter/navigation",
// JSONMethodCodec()
// );
// public static MethodChannel platform = new OptionalMethodChannel(
// "flutter/platform",
// JSONMethodCodec()
// );
public static MethodChannel textInput = new OptionalMethodChannel(
"flutter/textinput",
new JSONMethodCodec()
public static BasicMessageChannel<string> lifecycle = BasicMessageChannel<string>(
"flutter/lifecycle",
StringCodec());
// public static BasicMessageChannel<object> keyEvent = new BasicMessageChannel<object>(
// "flutter/keyevent",
// new JSONMessageCodec()
// );
public static BasicMessageChannel<object> system = BasicMessageChannel<object>(
"flutter/system",
JSONMessageCodec()
);
public static BasicMessageChannel<object> accessibility = BasicMessageChannel<object>(
"flutter/accessibility",
StandardMessageCodec()
);
public static MethodChannel platform_views = new MethodChannel(
"flutter/platform_views",
StandardMethodCodec()
);
public static MethodChannel skia = new MethodChannel(
"flutter/skia",
JSONMethodCodec()
);
}*/
// public static BasicMessageChannel<string> lifecycle = BasicMessageChannel<string>(
// "flutter/lifecycle",
// StringCodec());
//
// public static BasicMessageChannel<object> system = BasicMessageChannel<object>(
// "flutter/system",
// JSONMessageCodec()
// );
//
// public static BasicMessageChannel<object> accessibility = BasicMessageChannel<object>(
// "flutter/accessibility",
// StandardMessageCodec()
// );
//
// public static MethodChannel platform_views = new MethodChannel(
// "flutter/platform_views",
// StandardMethodCodec()
// );
//
// public static MethodChannel skia = new MethodChannel(
// "flutter/skia",
// JSONMethodCodec()
// );
}
}

45
engine/Build.bee.cs


"src/shell/gpu/gpu_surface_software_delegate.cc",
"src/shell/gpu/gpu_surface_software_delegate.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/basic_message_channel.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/binary_messenger.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/encodable_value.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/engine_method_result.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_message_codec.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_method_codec.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_type.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/message_codec.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_call.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_channel.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_codec.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_result.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registrar.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registry.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_message_codec.h",
"src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_method_codec.h",
"src/shell/platform/common/cpp/client_wrapper/basic_message_channel_unittests.cc",
"src/shell/platform/common/cpp/client_wrapper/byte_stream_wrappers.h",
"src/shell/platform/common/cpp/client_wrapper/encodable_value_unittests.cc",
"src/shell/platform/common/cpp/client_wrapper/engine_method_result.cc",
"src/shell/platform/common/cpp/client_wrapper/json_message_codec.cc",
"src/shell/platform/common/cpp/client_wrapper/json_method_codec.cc",
"src/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc",
"src/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc",
"src/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc",
"src/shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc",
"src/shell/platform/common/cpp/client_wrapper/standard_codec.cc",
"src/shell/platform/common/cpp/client_wrapper/standard_codec_serializer.h",
"src/shell/platform/common/cpp/client_wrapper/standard_message_codec_unittests.cc",
"src/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc",
"src/shell/platform/common/cpp/public/uiwidgets_messenger.h",
"src/shell/platform/common/cpp/public/uiwidgets_plugin_registrar.h",
"src/shell/platform/common/cpp/public/uiwigets_export.h",
"src/shell/platform/common/cpp/incoming_message_dispatcher.cc",
"src/shell/platform/common/cpp/incoming_message_dispatcher.h",
"src/shell/platform/embedder/embedder.cc",
"src/shell/platform/embedder/embedder.h",
"src/shell/platform/embedder/embedder_engine.cc",

"src/shell/platform/unity/windows/unity_surface_manager.h",
"src/shell/platform/unity/windows/win32_task_runner.cc",
"src/shell/platform/unity/windows/win32_task_runner.h",
"src/shell/platform/unity/windows/text_input_plugin.cc",
"src/shell/platform/unity/windows/public/uiwidgets_windows.h",
"src/shell/platform/unity/windows/uiwidgets_windows.cc",
"src/shell/platform/unity/windows/text_input_plugin.h",
"src/shell/platform/unity/windows/window_state.h",
};
var macSources = new NPath[] {

16
engine/src/shell/platform/embedder/embedder.h


extern "C" {
#endif
#ifndef UIWIDGETS_EXPORT
#define UIWIDGETS_EXPORT
#endif // UIWIDGETS_EXPORT
#ifdef UIWIDGETS_API_SYMBOL_PREFIX
#define UIWIDGETS_EMBEDDING_CONCAT(a, b) a##b
#define UIWIDGETS_EMBEDDING_ADD_PREFIX(symbol, prefix) \
UIWIDGETS_EMBEDDING_CONCAT(prefix, symbol)
#define UIWIDGETS_API_SYMBOL(symbol) \
UIWIDGETS_EMBEDDING_ADD_PREFIX(symbol, UIWIDGETS_API_SYMBOL_PREFIX)
#else
#define UIWIDGETS_API_SYMBOL(symbol) symbol
#endif
#define UIWIDGETS_ENGINE_VERSION 1
typedef enum {
kSuccess = 0,
kInvalidLibraryVersion,

198
engine/src/shell/platform/unity/windows/text_input_plugin.cc


// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shell/platform/unity/windows/text_input_plugin.h"
#include <windows.h>
#include <cstdint>
#include <iostream>
#include "shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_method_codec.h"
static constexpr char kSetEditingStateMethod[] = "TextInput.setEditingState";
static constexpr char kClearClientMethod[] = "TextInput.clearClient";
static constexpr char kSetClientMethod[] = "TextInput.setClient";
static constexpr char kShowMethod[] = "TextInput.show";
static constexpr char kHideMethod[] = "TextInput.hide";
static constexpr char kMultilineInputType[] = "TextInputType.multiline";
static constexpr char kUpdateEditingStateMethod[] =
"TextInputClient.updateEditingState";
static constexpr char kPerformActionMethod[] = "TextInputClient.performAction";
static constexpr char kSelectionBaseKey[] = "selectionBase";
static constexpr char kSelectionExtentKey[] = "selectionExtent";
static constexpr char kTextKey[] = "text";
static constexpr char kChannelName[] = "flutter/textinput";
static constexpr char kBadArgumentError[] = "Bad Arguments";
static constexpr char kInternalConsistencyError[] =
"Internal Consistency Error";
namespace uiwidgets {
// void TextInputPlugin::CharHook(Win32FlutterWindow* window,
// char32_t code_point) {
// if (active_model_ == nullptr) {
// return;
// }
// active_model_->AddCharacter(code_point);
// SendStateUpdate(*active_model_);
// }
// void TextInputPlugin::KeyboardHook(Win32FlutterWindow* window,
// int key,
// int scancode,
// int action,
// int mods) {
// if (active_model_ == nullptr) {
// return;
// }
// if (action == WM_KEYDOWN) {
// switch (key) {
// case VK_LEFT:
// if (active_model_->MoveCursorBack()) {
// SendStateUpdate(*active_model_);
// }
// break;
// case VK_RIGHT:
// if (active_model_->MoveCursorForward()) {
// SendStateUpdate(*active_model_);
// }
// break;
// case VK_END:
// active_model_->MoveCursorToEnd();
// SendStateUpdate(*active_model_);
// break;
// case VK_HOME:
// active_model_->MoveCursorToBeginning();
// SendStateUpdate(*active_model_);
// break;
// case VK_BACK:
// if (active_model_->Backspace()) {
// SendStateUpdate(*active_model_);
// }
// break;
// case VK_DELETE:
// if (active_model_->Delete()) {
// SendStateUpdate(*active_model_);
// }
// break;
// case VK_RETURN:
// EnterPressed(active_model_.get());
// break;
// default:
// break;
// }
// }
// }
TextInputPlugin::TextInputPlugin(uiwidgets::BinaryMessenger* messenger)
: channel_(std::make_unique<uiwidgets::MethodChannel<rapidjson::Document>>(
messenger,
kChannelName,
&uiwidgets::JsonMethodCodec::GetInstance()))/*,
active_model_(nullptr)*/ {
channel_->SetMethodCallHandler(
[this](
const uiwidgets::MethodCall<rapidjson::Document>& call,
std::unique_ptr<uiwidgets::MethodResult<rapidjson::Document>> result) {
HandleMethodCall(call, std::move(result));
});
}
TextInputPlugin::~TextInputPlugin() = default;
void TextInputPlugin::HandleMethodCall(
const uiwidgets::MethodCall<rapidjson::Document>& method_call,
std::unique_ptr<uiwidgets::MethodResult<rapidjson::Document>> result) {
const std::string& method = method_call.method_name();
if (method.compare(kShowMethod) == 0 || method.compare(kHideMethod) == 0) {
// These methods are no-ops.
} else if (method.compare(kClearClientMethod) == 0) {
//active_model_ = nullptr;
} else {
// Every following method requires args.
if (!method_call.arguments() || method_call.arguments()->IsNull()) {
result->Error(kBadArgumentError, "Method invoked without args");
return;
}
const rapidjson::Document& args = *method_call.arguments();
if (method.compare(kSetClientMethod) == 0) {
const rapidjson::Value& client_id_json = args[0];
const rapidjson::Value& client_config = args[1];
if (client_id_json.IsNull()) {
result->Error(kBadArgumentError, "Could not set client, ID is null.");
return;
}
if (client_config.IsNull()) {
result->Error(kBadArgumentError,
"Could not set client, missing arguments.");
return;
}
int client_id = client_id_json.GetInt();
//active_model_ =
// std::make_unique<TextInputModel>(client_id, client_config);
} else if (method.compare(kSetEditingStateMethod) == 0) {
/*if (active_model_ == nullptr) {
result->Error(
kInternalConsistencyError,
"Set editing state has been invoked, but no client is set.");
return;
}*/
auto text = args.FindMember(kTextKey);
if (text == args.MemberEnd() || text->value.IsNull()) {
result->Error(kBadArgumentError,
"Set editing state has been invoked, but without text.");
return;
}
auto selection_base = args.FindMember(kSelectionBaseKey);
auto selection_extent = args.FindMember(kSelectionExtentKey);
if (selection_base == args.MemberEnd() ||
selection_base->value.IsNull() ||
selection_extent == args.MemberEnd() ||
selection_extent->value.IsNull()) {
result->Error(kInternalConsistencyError,
"Selection base/extent values invalid.");
return;
}
/* active_model_->SetEditingState(selection_base->value.GetInt(),
selection_extent->value.GetInt(),
text->value.GetString());*/
} else {
// Unhandled method.
result->NotImplemented();
return;
}
}
// All error conditions return early, so if nothing has gone wrong indicate
// success.
result->Success();
}
// void TextInputPlugin::SendStateUpdate(const TextInputModel& model) {
// channel_->InvokeMethod(kUpdateEditingStateMethod, model.GetState());
// }
// void TextInputPlugin::EnterPressed(TextInputModel* model) {
// if (model->input_type() == kMultilineInputType) {
// model->AddCharacter('\n');
// SendStateUpdate(*model);
// }
// auto args = std::make_unique<rapidjson::Document>(rapidjson::kArrayType);
// auto& allocator = args->GetAllocator();
// args->PushBack(model->client_id(), allocator);
// args->PushBack(rapidjson::Value(model->input_action(), allocator).Move(),
// allocator);
// channel_->InvokeMethod(kPerformActionMethod, std::move(args));
// }
} // namespace flutter

49
engine/src/shell/platform/unity/windows/text_input_plugin.h


#ifndef UIWidgets_SHELL_PLATFORM_WINDOWS_TEXT_INPUT_PLUGIN_H_
#define UIWidgets_SHELL_PLATFORM_WINDOWS_TEXT_INPUT_PLUGIN_H_
#include <map>
#include <memory>
#include "rapidjson/document.h"
#include "rapidjson/rapidjson.h"
#include "shell/platform/common/cpp/client_wrapper/include/uiwidgets/binary_messenger.h"
#include "shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_channel.h"
//#include "shell/platform/common/cpp/text_input_model.h"
//#include "shell/platform/windows/keyboard_hook_handler.h"
#include "shell/platform/unity/windows/public/uiwidgets_windows.h"
namespace uiwidgets {
// class Win32UIWidgetsWindow;
// class TextInputPlugin : public KeyboardHookHandler {
class TextInputPlugin {
public:
explicit TextInputPlugin(uiwidgets::BinaryMessenger* messenger);
virtual ~TextInputPlugin();
//void KeyboardHook(Win32UIWidgetsWindow* window, int key, int scancode,
// int action, int mods) override;
//void CharHook(Win32UIWidgetsWindow* window, char32_t code_point) override;
private:
//void SendStateUpdate(const TextInputModel& model);
//void EnterPressed(TextInputModel* model);
void HandleMethodCall(
const uiwidgets::MethodCall<rapidjson::Document>& method_call,
std::unique_ptr<uiwidgets::MethodResult<rapidjson::Document>> result);
std::unique_ptr<uiwidgets::MethodChannel<rapidjson::Document>> channel_;
//std::unique_ptr<TextInputModel> active_model_;
};
} // namespace uiwidgets
#endif

313
engine/src/shell/platform/unity/windows/uiwidgets_windows.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shell/platform/unity/windows/public/uiwidgets_windows.h"
#include <assert.h>
#include <algorithm>
#include <chrono>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <vector>
#include "shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registrar.h"
//#include "shell/platform/common/cpp/incoming_message_dispatcher.h"
//#include "shell/platform/common/cpp/path_utils.h"
#include "shell/platform/embedder/embedder.h"
//#include "shell/platform/unity/windows/dpi_utils.h"
//#include "shell/platform/unity/windows/key_event_handler.h"
//#include "shell/platform/unity/windows/keyboard_hook_handler.h"
//#include "shell/platform/unity/windows/platform_handler.h"
#include "shell/platform/unity/windows/text_input_plugin.h"
//#include "shell/platform/unity/windows/win32_uiwidgets_window.h"
#include "shell/platform/unity/windows/win32_task_runner.h"
#include "shell/platform/unity/windows/window_state.h"
//static_assert(UIWIDGETS_ENGINE_VERSION == 1, "");
// Spins up an instance of the UIWidgets Engine.
//
// This function launches the UIWidgets Engine in a background thread, supplying
// the necessary callbacks for rendering within a win32window (if one is
// provided).
//
// Returns the state object for the engine, or null on failure to start the
// engine.
//static std::unique_ptr<UIWidgetsDesktopEngineState> RunUIWidgetsEngine(
// uiwidgets::Win32UIWidgetsWindow* window,
// const UIWidgetsDesktopEngineProperties& engine_properties) {
// auto state = std::make_unique<UIWidgetsDesktopEngineState>();
//
// // UIWidgetsProjectArgs is expecting a full argv, so when processing it for
// // flags the first item is treated as the executable and ignored. Add a dummy
// // value so that all provided arguments are used.
// std::vector<const char*> argv = {"placeholder"};
// if (engine_properties.switches_count > 0) {
// argv.insert(argv.end(), &engine_properties.switches[0],
// &engine_properties.switches[engine_properties.switches_count]);
// }
//
// window->CreateRenderSurface();
//
// // Provide the necessary callbacks for rendering within a win32 child window.
// UIWidgetsRendererConfig config = {};
// config.type = kOpenGL;
// config.open_gl.struct_size = sizeof(config.open_gl);
// config.open_gl.make_current = [](void* user_data) -> bool {
// auto host = static_cast<uiwidgets::Win32UIWidgetsWindow*>(user_data);
// return host->MakeCurrent();
// };
// config.open_gl.clear_current = [](void* user_data) -> bool {
// auto host = static_cast<uiwidgets::Win32UIWidgetsWindow*>(user_data);
// return host->ClearContext();
// };
// config.open_gl.present = [](void* user_data) -> bool {
// auto host = static_cast<uiwidgets::Win32UIWidgetsWindow*>(user_data);
// return host->SwapBuffers();
// };
// config.open_gl.fbo_callback = [](void* user_data) -> uint32_t { return 0; };
// config.open_gl.gl_proc_resolver = [](void* user_data,
// const char* what) -> void* {
// return reinterpret_cast<void*>(eglGetProcAddress(what));
// };
// config.open_gl.make_resource_current = [](void* user_data) -> bool {
// auto host = static_cast<uiwidgets::Win32UIWidgetsWindow*>(user_data);
// return host->MakeResourceCurrent();
// };
//
// // Configure task runner interop.
// auto state_ptr = state.get();
// state->task_runner = std::make_unique<uiwidgets::Win32TaskRunner>(
// GetCurrentThreadId(), [state_ptr](const auto* task) {
// if (UIWidgetsEngineRunTask(state_ptr->engine, task) != kSuccess) {
// std::cerr << "Could not post an engine task." << std::endl;
// }
// });
// UIWidgetsTaskRunnerDescription platform_task_runner = {};
// platform_task_runner.struct_size = sizeof(UIWidgetsTaskRunnerDescription);
// platform_task_runner.user_data = state->task_runner.get();
// platform_task_runner.runs_task_on_current_thread_callback =
// [](void* user_data) -> bool {
// return reinterpret_cast<uiwidgets::Win32TaskRunner*>(user_data)
// ->RunsTasksOnCurrentThread();
// };
// platform_task_runner.post_task_callback = [](UIWidgetsTask task,
// uint64_t target_time_nanos,
// void* user_data) -> void {
// reinterpret_cast<uiwidgets::Win32TaskRunner*>(user_data)->PostTask(
// task, target_time_nanos);
// };
//
// UIWidgetsCustomTaskRunners custom_task_runners = {};
// custom_task_runners.struct_size = sizeof(UIWidgetsCustomTaskRunners);
// custom_task_runners.platform_task_runner = &platform_task_runner;
//
// std::filesystem::path assets_path(engine_properties.assets_path);
// std::filesystem::path icu_path(engine_properties.icu_data_path);
// if (assets_path.is_relative() || icu_path.is_relative()) {
// // Treat relative paths as relative to the directory of this executable.
// std::filesystem::path executable_location =
// uiwidgets::GetExecutableDirectory();
// if (executable_location.empty()) {
// std::cerr
// << "Unable to find executable location to resolve resource paths."
// << std::endl;
// return nullptr;
// }
// assets_path = std::filesystem::path(executable_location) / assets_path;
// icu_path = std::filesystem::path(executable_location) / icu_path;
// }
// std::string assets_path_string = assets_path.u8string();
// std::string icu_path_string = icu_path.u8string();
//
// UIWidgetsProjectArgs args = {};
// args.struct_size = sizeof(UIWidgetsProjectArgs);
// args.assets_path = assets_path_string.c_str();
// args.icu_data_path = icu_path_string.c_str();
// args.command_line_argc = static_cast<int>(argv.size());
// args.command_line_argv = &argv[0];
// args.platform_message_callback =
// [](const UIWidgetsPlatformMessage* engine_message,
// void* user_data) -> void {
// auto window = reinterpret_cast<uiwidgets::Win32UIWidgetsWindow*>(user_data);
// return window->HandlePlatformMessage(engine_message);
// };
// args.custom_task_runners = &custom_task_runners;
//
// UIWIDGETS_API_SYMBOL(UIWidgetsEngine) engine = nullptr;
// auto result =
// UIWidgetsEngineRun(UIWIDGETS_ENGINE_VERSION, &config, &args, window, &engine);
// if (result != kSuccess || engine == nullptr) {
// std::cerr << "Failed to start UIWidgets engine: error " << result
// << std::endl;
// return nullptr;
// }
// state->engine = engine;
// return state;
//}
//
//UIWidgetsDesktopViewControllerRef UIWidgetsDesktopCreateViewController(
// int width,
// int height,
// const UIWidgetsDesktopEngineProperties& engine_properties) {
// UIWidgetsDesktopViewControllerRef state =
// uiwidgets::Win32UIWidgetsWindow::CreateWin32UIWidgetsWindow(width, height);
//
// auto engine_state = RunUIWidgetsEngine(state->view.get(), engine_properties);
//
// if (!engine_state) {
// return nullptr;
// }
// state->view->SetState(engine_state->engine);
// state->engine_state = std::move(engine_state);
// return state;
//}
//
//UIWidgetsDesktopViewControllerRef UIWidgetsDesktopCreateViewControllerLegacy(
// int initial_width,
// int initial_height,
// const char* assets_path,
// const char* icu_data_path,
// const char** arguments,
// size_t argument_count) {
// std::filesystem::path assets_path_fs = std::filesystem::u8path(assets_path);
// std::filesystem::path icu_data_path_fs =
// std::filesystem::u8path(icu_data_path);
// UIWidgetsDesktopEngineProperties engine_properties = {};
// engine_properties.assets_path = assets_path_fs.c_str();
// engine_properties.icu_data_path = icu_data_path_fs.c_str();
// engine_properties.switches = arguments;
// engine_properties.switches_count = argument_count;
//
// return UIWidgetsDesktopCreateViewController(initial_width, initial_height,
// engine_properties);
//}
//
//uint64_t UIWidgetsDesktopProcessMessages(
// UIWidgetsDesktopViewControllerRef controller) {
// return controller->engine_state->task_runner->ProcessTasks().count();
//}
//
//void UIWidgetsDesktopDestroyViewController(
// UIWidgetsDesktopViewControllerRef controller) {
// UIWidgetsEngineShutdown(controller->engine_state->engine);
// delete controller;
//}
//
//UIWidgetsDesktopPluginRegistrarRef UIWidgetsDesktopGetPluginRegistrar(
// UIWidgetsDesktopViewControllerRef controller,
// const char* plugin_name) {
// // Currently, one registrar acts as the registrar for all plugins, so the
// // name is ignored. It is part of the API to reduce churn in the future when
// // aligning more closely with the UIWidgets registrar system.
//
// return controller->view->GetRegistrar();
//}
//
//UIWidgetsDesktopViewRef UIWidgetsDesktopGetView(
// UIWidgetsDesktopViewControllerRef controller) {
// return controller->view_wrapper.get();
//}
//
//HWND UIWidgetsDesktopViewGetHWND(UIWidgetsDesktopViewRef view) {
// return view->window->GetWindowHandle();
//}
//
//UINT UIWidgetsDesktopGetDpiForHWND(HWND hwnd) {
// return uiwidgets::GetDpiForHWND(hwnd);
//}
//
//UINT UIWidgetsDesktopGetDpiForMonitor(HMONITOR monitor) {
// return uiwidgets::GetDpiForMonitor(monitor);
//}
//
//UIWidgetsDesktopEngineRef UIWidgetsDesktopRunEngine(
// const UIWidgetsDesktopEngineProperties& engine_properties) {
// auto engine = RunUIWidgetsEngine(nullptr, engine_properties);
// return engine.release();
//}
//
//bool UIWidgetsDesktopShutDownEngine(UIWidgetsDesktopEngineRef engine_ref) {
// std::cout << "Shutting down uiwidgets engine process." << std::endl;
// auto result = UIWidgetsEngineShutdown(engine_ref->engine);
// delete engine_ref;
// return (result == kSuccess);
//}
void UIWidgetsDesktopRegistrarEnableInputBlocking(
UIWidgetsDesktopPluginRegistrarRef registrar,
const char* channel) {
registrar->messenger->dispatcher->EnableInputBlockingForChannel(channel);
}
UIWidgetsDesktopMessengerRef UIWidgetsDesktopRegistrarGetMessenger(
UIWidgetsDesktopPluginRegistrarRef registrar) {
return registrar->messenger.get();
}
//UIWidgetsDesktopViewRef UIWidgetsDesktopRegistrarGetView(
// UIWidgetsDesktopPluginRegistrarRef registrar) {
// return registrar->window;
//}
//
bool UIWidgetsDesktopMessengerSendWithReply(UIWidgetsDesktopMessengerRef messenger,
const char* channel,
const uint8_t* message,
const size_t message_size,
const UIWidgetsDesktopBinaryReply reply,
void* user_data) {
UIWidgetsPlatformMessageResponseHandle* response_handle = nullptr;
if (reply != nullptr && user_data != nullptr) {
UIWidgetsEngineResult result = UIWidgetsPlatformMessageCreateResponseHandle(
messenger->engine, reply, user_data, &response_handle);
if (result != kSuccess) {
std::cout << "Failed to create response handle\n";
return false;
}
}
UIWidgetsPlatformMessage platform_message = {
sizeof(UIWidgetsPlatformMessage),
channel,
message,
message_size,
response_handle,
};
UIWidgetsEngineResult message_result =
UIWidgetsEngineSendPlatformMessage(messenger->engine, &platform_message);
if (response_handle != nullptr) {
UIWidgetsPlatformMessageReleaseResponseHandle(messenger->engine,
response_handle);
}
return message_result == kSuccess;
}
bool UIWidgetsDesktopMessengerSend(UIWidgetsDesktopMessengerRef messenger,
const char* channel,
const uint8_t* message,
const size_t message_size) {
return UIWidgetsDesktopMessengerSendWithReply(messenger, channel, message,
message_size, nullptr, nullptr);
}
void UIWidgetsDesktopMessengerSendResponse(
UIWidgetsDesktopMessengerRef messenger,
const UIWidgetsDesktopMessageResponseHandle* handle,
const uint8_t* data,
size_t data_length) {
UIWidgetsEngineSendPlatformMessageResponse(messenger->engine, handle, data,
data_length);
}
void UIWidgetsDesktopMessengerSetCallback(UIWidgetsDesktopMessengerRef messenger,
const char* channel,
UIWidgetsDesktopMessageCallback callback,
void* user_data) {
messenger->dispatcher->SetMessageCallback(channel, callback, user_data);
}

69
engine/src/shell/platform/unity/windows/window_state.h


// Copyright 2013 The UIWidgets 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 UIWIDGETS_SHELL_PLATFORM_WINDOWS_UIWIDGETS_WINDOW_STATE_H_
#define UIWIDGETS_SHELL_PLATFORM_WINDOWS_UIWIDGETS_WINDOW_STATE_H_
#include "shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registrar.h"
#include "shell/platform/common/cpp/incoming_message_dispatcher.h"
#include "shell/platform/embedder/embedder.h"
//#include "shell/platform/unity/windows/key_event_handler.h"
//#include "shell/platform/unity/windows/keyboard_hook_handler.h"
//#include "shell/platform/unity/windows/platform_handler.h"
#include "shell/platform/unity/windows/text_input_plugin.h"
#include "shell/platform/unity/windows/win32_task_runner.h"
namespace uiwidgets {
struct Win32UIWidgetsWindow;
}
// Struct for storing state within an instance of the windows native (HWND or
// CoreWindow) Window.
struct UIWidgetsDesktopViewControllerState {
// The win32 window that owns this state object.
std::unique_ptr<uiwidgets::Win32UIWidgetsWindow> view;
// The state associate with the engine backing the view.
std::unique_ptr<UIWidgetsDesktopEngineState> engine_state;
// The window handle given to API clients.
std::unique_ptr<UIWidgetsDesktopView> view_wrapper;
};
// Opaque reference for the native windows itself. This is separate from the
// controller so that it can be provided to plugins without giving them access
// to all of the controller-based functionality.
struct UIWidgetsDesktopView {
// The window that (indirectly) owns this state object.
uiwidgets::Win32UIWidgetsWindow* window;
};
// Struct for storing state of a UIWidgets engine instance.
struct UIWidgetsDesktopEngineState {
// The handle to the UIWidgets engine instance.
UIWIDGETS_API_SYMBOL(UIWidgetsEngine) engine;
// Task runner for tasks posted from the engine.
std::unique_ptr<uiwidgets::Win32TaskRunner> task_runner;
};
// State associated with the plugin registrar.
struct UIWidgetsDesktopPluginRegistrar {
// The plugin messenger handle given to API clients.
std::unique_ptr<UIWidgetsDesktopMessenger> messenger;
// The handle for the window associated with this registrar.
UIWidgetsDesktopView* window;
};
// State associated with the messenger used to communicate with the engine.
struct UIWidgetsDesktopMessenger {
// The UIWidgets engine this messenger sends outgoing messages to.
UIWIDGETS_API_SYMBOL(UIWidgetsEngine) engine;
// The message dispatcher for handling incoming messages.
uiwidgets::IncomingMessageDispatcher* dispatcher;
};
#endif // UIWIDGETS_SHELL_PLATFORM_WINDOWS_UIWIDGETS_WINDOW_STATE_H_

93
engine/src/shell/platform/common/cpp/client_wrapper/basic_message_channel_unittests.cc


// // Copyright 2013 The UIWidgets Authors. All rights reserved.
// // Use of this source code is governed by a BSD-style license that can be
// // found in the LICENSE file.
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/basic_message_channel.h"
// #include <memory>
// #include <string>
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/binary_messenger.h"
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_message_codec.h"
// #include "gtest/gtest.h"
// namespace uiwidgets {
// namespace {
// class TestBinaryMessenger : public BinaryMessenger {
// public:
// void Send(const std::string& channel,
// const uint8_t* message,
// const size_t message_size) const override {}
// void Send(const std::string& channel,
// const uint8_t* message,
// const size_t message_size,
// BinaryReply reply) const override {}
// void SetMessageHandler(const std::string& channel,
// BinaryMessageHandler handler) override {
// last_message_handler_channel_ = channel;
// last_message_handler_ = handler;
// }
// std::string last_message_handler_channel() {
// return last_message_handler_channel_;
// }
// BinaryMessageHandler last_message_handler() { return last_message_handler_; }
// private:
// std::string last_message_handler_channel_;
// BinaryMessageHandler last_message_handler_;
// };
// } // namespace
// // Tests that SetMessageHandler sets a handler that correctly interacts with
// // the binary messenger.
// TEST(BasicMessageChannelTest, Registration) {
// TestBinaryMessenger messenger;
// const std::string channel_name("some_channel");
// const StandardMessageCodec& codec = StandardMessageCodec::GetInstance();
// BasicMessageChannel channel(&messenger, channel_name, &codec);
// bool callback_called = false;
// const std::string message_value("hello");
// channel.SetMessageHandler(
// [&callback_called, message_value](const auto& message, auto reply) {
// callback_called = true;
// // Ensure that the wrapper recieved a correctly decoded message and a
// // reply.
// EXPECT_EQ(message.StringValue(), message_value);
// EXPECT_NE(reply, nullptr);
// });
// EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
// EXPECT_NE(messenger.last_message_handler(), nullptr);
// // Send a test message to trigger the handler test assertions.
// auto message = codec.EncodeMessage(EncodableValue(message_value));
// messenger.last_message_handler()(
// message->data(), message->size(),
// [](const uint8_t* reply, const size_t reply_size) {});
// EXPECT_EQ(callback_called, true);
// }
// // Tests that SetMessageHandler with a null handler unregisters the handler.
// TEST(BasicMessageChannelTest, Unregistration) {
// TestBinaryMessenger messenger;
// const std::string channel_name("some_channel");
// BasicMessageChannel channel(&messenger, channel_name,
// &uiwidgets::StandardMessageCodec::GetInstance());
// channel.SetMessageHandler([](const auto& message, auto reply) {});
// EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
// EXPECT_NE(messenger.last_message_handler(), nullptr);
// channel.SetMessageHandler(nullptr);
// EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
// EXPECT_EQ(messenger.last_message_handler(), nullptr);
// }
// } // namespace uiwidgets

105
engine/src/shell/platform/common/cpp/client_wrapper/byte_stream_wrappers.h


// Copyright 2013 The UIWidgets 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 UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
// Utility classes for interacting with a buffer of bytes as a stream, for use
// in message channel codecs.
#include <cstdint>
#include <cstring>
#include <iostream>
#include <vector>
namespace uiwidgets {
// Wraps an array of bytes with utility methods for treating it as a readable
// stream.
class ByteBufferStreamReader {
public:
// Createa a reader reading from |bytes|, which must have a length of |size|.
// |bytes| must remain valid for the lifetime of this object.
explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size)
: bytes_(bytes), size_(size) {}
// Reads and returns the next byte from the stream.
uint8_t ReadByte() {
if (location_ >= size_) {
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
return 0;
}
return bytes_[location_++];
}
// Reads the next |length| bytes from the stream into |buffer|. The caller
// is responsible for ensuring that |buffer| is large enough.
void ReadBytes(uint8_t* buffer, size_t length) {
if (location_ + length > size_) {
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
return;
}
std::memcpy(buffer, &bytes_[location_], length);
location_ += length;
}
// Advances the read cursor to the next multiple of |alignment| relative to
// the start of the wrapped byte buffer, unless it is already aligned.
void ReadAlignment(uint8_t alignment) {
uint8_t mod = location_ % alignment;
if (mod) {
location_ += alignment - mod;
}
}
private:
// The buffer to read from.
const uint8_t* bytes_;
// The total size of the buffer.
size_t size_;
// The current read location.
size_t location_ = 0;
};
// Wraps an array of bytes with utility methods for treating it as a writable
// stream.
class ByteBufferStreamWriter {
public:
// Createa a writter that writes into |buffer|.
// |buffer| must remain valid for the lifetime of this object.
explicit ByteBufferStreamWriter(std::vector<uint8_t>* buffer)
: bytes_(buffer) {
assert(buffer);
}
// Writes |byte| to the wrapped buffer.
void WriteByte(uint8_t byte) { bytes_->push_back(byte); }
// Writes the next |length| bytes from |bytes| into the wrapped buffer.
// The caller is responsible for ensuring that |buffer| is large enough.
void WriteBytes(const uint8_t* bytes, size_t length) {
assert(length > 0);
bytes_->insert(bytes_->end(), bytes, bytes + length);
}
// Writes 0s until the next multiple of |alignment| relative to
// the start of the wrapped byte buffer, unless the write positition is
// already aligned.
void WriteAlignment(uint8_t alignment) {
uint8_t mod = bytes_->size() % alignment;
if (mod) {
for (int i = 0; i < alignment - mod; ++i) {
WriteByte(0);
}
}
}
private:
// The buffer to write to.
std::vector<uint8_t>* bytes_;
};
} // namespace uiwidgets
#endif // UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_

330
engine/src/shell/platform/common/cpp/client_wrapper/encodable_value_unittests.cc


// // Copyright 2013 The UIWidgets Authors. All rights reserved.
// // Use of this source code is governed by a BSD-style license that can be
// // found in the LICENSE file.
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/encodable_value.h"
// #include <limits>
// #include "gtest/gtest.h"
// namespace uiwidgets {
// // Verifies that value.type() is |type|, and that of all the Is* methods, only
// // the one that matches the type is true.
// void VerifyType(EncodableValue& value,
// EncodableValue::EncodableValue::Type type) {
// EXPECT_EQ(value.type(), type);
// EXPECT_EQ(value.IsNull(), type == EncodableValue::Type::kNull);
// EXPECT_EQ(value.IsBool(), type == EncodableValue::Type::kBool);
// EXPECT_EQ(value.IsInt(), type == EncodableValue::Type::kInt);
// EXPECT_EQ(value.IsLong(), type == EncodableValue::Type::kLong);
// EXPECT_EQ(value.IsDouble(), type == EncodableValue::Type::kDouble);
// EXPECT_EQ(value.IsString(), type == EncodableValue::Type::kString);
// EXPECT_EQ(value.IsByteList(), type == EncodableValue::Type::kByteList);
// EXPECT_EQ(value.IsIntList(), type == EncodableValue::Type::kIntList);
// EXPECT_EQ(value.IsLongList(), type == EncodableValue::Type::kLongList);
// EXPECT_EQ(value.IsDoubleList(), type == EncodableValue::Type::kDoubleList);
// EXPECT_EQ(value.IsList(), type == EncodableValue::Type::kList);
// EXPECT_EQ(value.IsMap(), type == EncodableValue::Type::kMap);
// }
// TEST(EncodableValueTest, Null) {
// EncodableValue value;
// VerifyType(value, EncodableValue::Type::kNull);
// }
// TEST(EncodableValueTest, Bool) {
// EncodableValue value(false);
// VerifyType(value, EncodableValue::Type::kBool);
// EXPECT_FALSE(value.BoolValue());
// value = true;
// EXPECT_TRUE(value.BoolValue());
// }
// TEST(EncodableValueTest, Int) {
// EncodableValue value(42);
// VerifyType(value, EncodableValue::Type::kInt);
// EXPECT_EQ(value.IntValue(), 42);
// value = std::numeric_limits<int32_t>::max();
// EXPECT_EQ(value.IntValue(), std::numeric_limits<int32_t>::max());
// }
// TEST(EncodableValueTest, LongValueFromInt) {
// EncodableValue value(std::numeric_limits<int32_t>::max());
// EXPECT_EQ(value.LongValue(), std::numeric_limits<int32_t>::max());
// }
// TEST(EncodableValueTest, Long) {
// EncodableValue value(INT64_C(42));
// VerifyType(value, EncodableValue::Type::kLong);
// EXPECT_EQ(value.LongValue(), 42);
// value = std::numeric_limits<int64_t>::max();
// EXPECT_EQ(value.LongValue(), std::numeric_limits<int64_t>::max());
// }
// TEST(EncodableValueTest, Double) {
// EncodableValue value(3.14);
// VerifyType(value, EncodableValue::Type::kDouble);
// EXPECT_EQ(value.DoubleValue(), 3.14);
// value = std::numeric_limits<double>::max();
// EXPECT_EQ(value.DoubleValue(), std::numeric_limits<double>::max());
// }
// TEST(EncodableValueTest, String) {
// std::string hello("Hello, world!");
// EncodableValue value(hello);
// VerifyType(value, EncodableValue::Type::kString);
// EXPECT_EQ(value.StringValue(), hello);
// value = "Goodbye";
// EXPECT_EQ(value.StringValue(), "Goodbye");
// }
// TEST(EncodableValueTest, UInt8List) {
// std::vector<uint8_t> data = {0, 2};
// EncodableValue value(data);
// VerifyType(value, EncodableValue::Type::kByteList);
// std::vector<uint8_t>& list_value = value.ByteListValue();
// list_value.push_back(std::numeric_limits<uint8_t>::max());
// EXPECT_EQ(list_value[0], 0);
// EXPECT_EQ(list_value[1], 2);
// ASSERT_EQ(list_value.size(), 3u);
// EXPECT_EQ(data.size(), 2u);
// EXPECT_EQ(list_value[2], std::numeric_limits<uint8_t>::max());
// }
// TEST(EncodableValueTest, Int32List) {
// std::vector<int32_t> data = {-10, 2};
// EncodableValue value(data);
// VerifyType(value, EncodableValue::Type::kIntList);
// std::vector<int32_t>& list_value = value.IntListValue();
// list_value.push_back(std::numeric_limits<int32_t>::max());
// EXPECT_EQ(list_value[0], -10);
// EXPECT_EQ(list_value[1], 2);
// ASSERT_EQ(list_value.size(), 3u);
// EXPECT_EQ(data.size(), 2u);
// EXPECT_EQ(list_value[2], std::numeric_limits<int32_t>::max());
// }
// TEST(EncodableValueTest, Int64List) {
// std::vector<int64_t> data = {-10, 2};
// EncodableValue value(data);
// VerifyType(value, EncodableValue::Type::kLongList);
// std::vector<int64_t>& list_value = value.LongListValue();
// list_value.push_back(std::numeric_limits<int64_t>::max());
// EXPECT_EQ(list_value[0], -10);
// EXPECT_EQ(list_value[1], 2);
// ASSERT_EQ(list_value.size(), 3u);
// EXPECT_EQ(data.size(), 2u);
// EXPECT_EQ(list_value[2], std::numeric_limits<int64_t>::max());
// }
// TEST(EncodableValueTest, DoubleList) {
// std::vector<double> data = {-10.0, 2.0};
// EncodableValue value(data);
// VerifyType(value, EncodableValue::Type::kDoubleList);
// std::vector<double>& list_value = value.DoubleListValue();
// list_value.push_back(std::numeric_limits<double>::max());
// EXPECT_EQ(list_value[0], -10.0);
// EXPECT_EQ(list_value[1], 2.0);
// ASSERT_EQ(list_value.size(), 3u);
// EXPECT_EQ(data.size(), 2u);
// EXPECT_EQ(list_value[2], std::numeric_limits<double>::max());
// }
// TEST(EncodableValueTest, List) {
// EncodableList encodables = {
// EncodableValue(1),
// EncodableValue(2.0),
// EncodableValue("Three"),
// };
// EncodableValue value(encodables);
// VerifyType(value, EncodableValue::Type::kList);
// EncodableList& list_value = value.ListValue();
// EXPECT_EQ(list_value[0].IntValue(), 1);
// EXPECT_EQ(list_value[1].DoubleValue(), 2.0);
// EXPECT_EQ(list_value[2].StringValue(), "Three");
// // Ensure that it's a modifiable copy of the original array.
// list_value.push_back(EncodableValue(true));
// ASSERT_EQ(list_value.size(), 4u);
// EXPECT_EQ(encodables.size(), 3u);
// EXPECT_EQ(value.ListValue()[3].BoolValue(), true);
// }
// TEST(EncodableValueTest, Map) {
// EncodableMap encodables = {
// {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
// {EncodableValue(1), EncodableValue(INT64_C(10000))},
// {EncodableValue("two"), EncodableValue(7)},
// };
// EncodableValue value(encodables);
// VerifyType(value, EncodableValue::Type::kMap);
// EncodableMap& map_value = value.MapValue();
// EXPECT_EQ(map_value[EncodableValue()].IsIntList(), true);
// EXPECT_EQ(map_value[EncodableValue(1)].LongValue(), INT64_C(10000));
// EXPECT_EQ(map_value[EncodableValue("two")].IntValue(), 7);
// // Ensure that it's a modifiable copy of the original map.
// map_value[EncodableValue(true)] = EncodableValue(false);
// ASSERT_EQ(map_value.size(), 4u);
// EXPECT_EQ(encodables.size(), 3u);
// EXPECT_EQ(map_value[EncodableValue(true)].BoolValue(), false);
// }
// TEST(EncodableValueTest, EmptyTypeConstructor) {
// EXPECT_TRUE(EncodableValue(EncodableValue::Type::kNull).IsNull());
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kBool).BoolValue(), false);
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kInt).IntValue(), 0);
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kLong).LongValue(),
// INT64_C(0));
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kDouble).DoubleValue(), 0.0);
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kString).StringValue().size(),
// 0u);
// EXPECT_EQ(
// EncodableValue(EncodableValue::Type::kByteList).ByteListValue().size(),
// 0u);
// EXPECT_EQ(
// EncodableValue(EncodableValue::Type::kIntList).IntListValue().size(), 0u);
// EXPECT_EQ(
// EncodableValue(EncodableValue::Type::kLongList).LongListValue().size(),
// 0u);
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kDoubleList)
// .DoubleListValue()
// .size(),
// 0u);
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kList).ListValue().size(), 0u);
// EXPECT_EQ(EncodableValue(EncodableValue::Type::kMap).MapValue().size(), 0u);
// }
// // Tests that the < operator meets the requirements of using EncodableValue as
// // a map key.
// TEST(EncodableValueTest, Comparison) {
// EncodableList values = {
// // Null
// EncodableValue(),
// // Bool
// EncodableValue(true),
// EncodableValue(false),
// // Int
// EncodableValue(-7),
// EncodableValue(0),
// EncodableValue(100),
// // Long
// EncodableValue(INT64_C(-7)),
// EncodableValue(INT64_C(0)),
// EncodableValue(INT64_C(100)),
// // Double
// EncodableValue(-7.0),
// EncodableValue(0.0),
// EncodableValue(100.0),
// // String
// EncodableValue("one"),
// EncodableValue("two"),
// // ByteList
// EncodableValue(std::vector<uint8_t>{0, 1}),
// EncodableValue(std::vector<uint8_t>{0, 10}),
// // IntList
// EncodableValue(std::vector<int32_t>{0, 1}),
// EncodableValue(std::vector<int32_t>{0, 100}),
// // LongList
// EncodableValue(std::vector<int64_t>{0, INT64_C(1)}),
// EncodableValue(std::vector<int64_t>{0, INT64_C(100)}),
// // DoubleList
// EncodableValue(std::vector<int64_t>{0, INT64_C(1)}),
// EncodableValue(std::vector<int64_t>{0, INT64_C(100)}),
// // List
// EncodableValue(EncodableList{EncodableValue(), EncodableValue(true)}),
// EncodableValue(EncodableList{EncodableValue(), EncodableValue(1.0)}),
// // Map
// EncodableValue(EncodableMap{{EncodableValue(), EncodableValue(true)},
// {EncodableValue(7), EncodableValue(7.0)}}),
// EncodableValue(
// EncodableMap{{EncodableValue(), EncodableValue(1.0)},
// {EncodableValue("key"), EncodableValue("value")}}),
// };
// for (size_t i = 0; i < values.size(); ++i) {
// const auto& a = values[i];
// for (size_t j = 0; j < values.size(); ++j) {
// const auto& b = values[j];
// if (i == j) {
// // Identical objects should always be equal.
// EXPECT_FALSE(a < b);
// EXPECT_FALSE(b < a);
// } else {
// // All other comparisons should be consistent, but the direction doesn't
// // matter.
// EXPECT_NE(a < b, b < a);
// }
// }
// // Different non-collection objects with the same value should be equal;
// // different collections should always be unequal regardless of contents.
// bool is_collection = a.IsByteList() || a.IsIntList() || a.IsLongList() ||
// a.IsDoubleList() || a.IsList() || a.IsMap();
// EncodableValue copy(a);
// bool is_equal = !(a < copy || copy < a);
// EXPECT_EQ(is_equal, !is_collection);
// }
// }
// // Tests that structures are deep-copied.
// TEST(EncodableValueTest, DeepCopy) {
// EncodableList encodables = {
// EncodableValue(EncodableMap{
// {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
// {EncodableValue(1), EncodableValue(INT64_C(0000))},
// {EncodableValue("two"), EncodableValue(7)},
// }),
// EncodableValue(EncodableList{
// EncodableValue(),
// EncodableValue(),
// EncodableValue(
// EncodableMap{{EncodableValue("a"), EncodableValue("b")}}),
// }),
// };
// EncodableValue value(encodables);
// ASSERT_TRUE(value.IsList());
// // Spot-check innermost collection values.
// EXPECT_EQ(value.ListValue()[0].MapValue()[EncodableValue("two")].IntValue(),
// 7);
// EXPECT_EQ(value.ListValue()[1]
// .ListValue()[2]
// .MapValue()[EncodableValue("a")]
// .StringValue(),
// "b");
// // Modify those values in the original structure.
// encodables[0].MapValue()[EncodableValue("two")] = EncodableValue();
// encodables[1].ListValue()[2].MapValue()[EncodableValue("a")] = 99;
// // Re-check innermost collection values to ensure that they haven't changed.
// EXPECT_EQ(value.ListValue()[0].MapValue()[EncodableValue("two")].IntValue(),
// 7);
// EXPECT_EQ(value.ListValue()[1]
// .ListValue()[2]
// .MapValue()[EncodableValue("a")]
// .StringValue(),
// "b");
// }
// } // namespace uiwidgets

45
engine/src/shell/platform/common/cpp/client_wrapper/engine_method_result.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/uiwidgets/engine_method_result.h"
#include <assert.h>
#include <iostream>
namespace uiwidgets {
namespace internal {
ReplyManager::ReplyManager(BinaryReply reply_handler)
: reply_handler_(std::move(reply_handler)) {
assert(reply_handler_);
}
ReplyManager::~ReplyManager() {
if (reply_handler_) {
// Warn, rather than send a not-implemented response, since the engine may
// no longer be valid at this point.
std::cerr
<< "Warning: Failed to respond to a message. This is a memory leak."
<< std::endl;
}
}
void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
if (!reply_handler_) {
std::cerr
<< "Error: Only one of Success, Error, or NotImplemented can be "
"called,"
<< " and it can be called exactly once. Ignoring duplicate result."
<< std::endl;
return;
}
const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
size_t message_size = data ? data->size() : 0;
reply_handler_(message, message_size);
reply_handler_ = nullptr;
}
} // namespace internal
} // namespace uiwidgets

108
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/basic_message_channel.h


// Copyright 2013 The UIWidgets 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 UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_BASIC_MESSAGE_CHANNEL_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_BASIC_MESSAGE_CHANNEL_H_
#include <iostream>
#include <string>
#include "binary_messenger.h"
#include "message_codec.h"
namespace uiwidgets {
// A message reply callback.
//
// Used for submitting a reply back to a UIWidgets message sender.
template <typename T>
using MessageReply = std::function<void(const T& reply)>;
// A handler for receiving a message from the UIWidgets engine.
//
// Implementations must asynchronously call reply exactly once with the reply
// to the message.
template <typename T>
using MessageHandler =
std::function<void(const T& message, const MessageReply<T>& reply)>;
// A channel for communicating with the UIWidgets engine by sending asynchronous
// messages.
template <typename T>
class BasicMessageChannel {
public:
// Creates an instance that sends and receives method calls on the channel
// named |name|, encoded with |codec| and dispatched via |messenger|.
BasicMessageChannel(BinaryMessenger* messenger,
const std::string& name,
const MessageCodec<T>* codec)
: messenger_(messenger), name_(name), codec_(codec) {}
~BasicMessageChannel() = default;
// Prevent copying.
BasicMessageChannel(BasicMessageChannel const&) = delete;
BasicMessageChannel& operator=(BasicMessageChannel const&) = delete;
// Sends a message to the UIWidgets engine on this channel.
void Send(const T& message) {
std::unique_ptr<std::vector<uint8_t>> raw_message =
codec_->EncodeMessage(message);
messenger_->Send(name_, raw_message->data(), raw_message->size());
}
// Sends a message to the UIWidgets engine on this channel expecting a reply.
void Send(const T& message, BinaryReply reply) {
std::unique_ptr<std::vector<uint8_t>> raw_message =
codec_->EncodeMessage(message);
messenger_->Send(name_, raw_message->data(), raw_message->size(), reply);
}
// Registers a handler that should be called any time a message is
// received on this channel. A null handler will remove any previous handler.
//
// Note that the BasicMessageChannel does not own the handler, and will not
// unregister it on destruction, so the caller is responsible for
// unregistering explicitly if it should no longer be called.
void SetMessageHandler(const MessageHandler<T>& handler) const {
if (!handler) {
messenger_->SetMessageHandler(name_, nullptr);
return;
}
const auto* codec = codec_;
std::string channel_name = name_;
BinaryMessageHandler binary_handler = [handler, codec, channel_name](
const uint8_t* binary_message,
const size_t binary_message_size,
BinaryReply binary_reply) {
// Use this channel's codec to decode the message and build a reply
// handler.
std::unique_ptr<T> message =
codec->DecodeMessage(binary_message, binary_message_size);
if (!message) {
std::cerr << "Unable to decode message on channel " << channel_name
<< std::endl;
binary_reply(nullptr, 0);
return;
}
MessageReply<T> unencoded_reply = [binary_reply,
codec](const T& unencoded_response) {
auto binary_response = codec->EncodeMessage(unencoded_response);
binary_reply(binary_response->data(), binary_response->size());
};
handler(*message, std::move(unencoded_reply));
};
messenger_->SetMessageHandler(name_, std::move(binary_handler));
}
private:
BinaryMessenger* messenger_;
std::string name_;
const MessageCodec<T>* codec_;
};
} // namespace uiwidgets
#endif // UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_BASIC_MESSAGE_CHANNEL_H_

34
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/binary_messenger.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_BINARY_MESSENGER_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_BINARY_MESSENGER_H_
#include <functional>
#include <string>
namespace uiwidgets {
typedef std::function<void(const uint8_t* reply, const size_t reply_size)>
BinaryReply;
typedef std::function<void(const uint8_t* message, const size_t message_size,
BinaryReply reply)>
BinaryMessageHandler;
class BinaryMessenger {
public:
virtual ~BinaryMessenger() = default;
virtual void Send(const std::string& channel, const uint8_t* message,
const size_t message_size) const = 0;
virtual void Send(const std::string& channel, const uint8_t* message,
const size_t message_size, BinaryReply reply) const = 0;
virtual void SetMessageHandler(const std::string& channel,
BinaryMessageHandler handler) = 0;
};
} // namespace uiwidgets
#endif

428
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/encodable_value.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_ENCODABLE_VALUE_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_ENCODABLE_VALUE_H_
#include <assert.h>
#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace uiwidgets {
static_assert(sizeof(double) == 8, "EncodableValue requires a 64-bit double");
class EncodableValue;
using EncodableList = std::vector<EncodableValue>;
using EncodableMap = std::map<EncodableValue, EncodableValue>;
class EncodableValue {
public:
enum class Type {
kNull,
kBool,
kInt,
kLong,
kDouble,
kString,
kByteList,
kIntList,
kLongList,
kDoubleList,
kList,
kMap,
};
EncodableValue() {}
explicit EncodableValue(bool value) : bool_(value), type_(Type::kBool) {}
explicit EncodableValue(int32_t value) : int_(value), type_(Type::kInt) {}
explicit EncodableValue(int64_t value) : long_(value), type_(Type::kLong) {}
explicit EncodableValue(double value)
: double_(value), type_(Type::kDouble) {}
explicit EncodableValue(const char* value)
: string_(new std::string(value)), type_(Type::kString) {}
explicit EncodableValue(const std::string& value)
: string_(new std::string(value)), type_(Type::kString) {}
explicit EncodableValue(std::vector<uint8_t> list)
: byte_list_(new std::vector<uint8_t>(std::move(list))),
type_(Type::kByteList) {}
explicit EncodableValue(std::vector<int32_t> list)
: int_list_(new std::vector<int32_t>(std::move(list))),
type_(Type::kIntList) {}
explicit EncodableValue(std::vector<int64_t> list)
: long_list_(new std::vector<int64_t>(std::move(list))),
type_(Type::kLongList) {}
explicit EncodableValue(std::vector<double> list)
: double_list_(new std::vector<double>(std::move(list))),
type_(Type::kDoubleList) {}
explicit EncodableValue(EncodableList list)
: list_(new EncodableList(std::move(list))), type_(Type::kList) {}
explicit EncodableValue(EncodableMap map)
: map_(new EncodableMap(std::move(map))), type_(Type::kMap) {}
explicit EncodableValue(Type type) : type_(type) {
switch (type_) {
case Type::kNull:
break;
case Type::kBool:
bool_ = false;
break;
case Type::kInt:
int_ = 0;
break;
case Type::kLong:
long_ = 0;
break;
case Type::kDouble:
double_ = 0.0;
break;
case Type::kString:
string_ = new std::string();
break;
case Type::kByteList:
byte_list_ = new std::vector<uint8_t>();
break;
case Type::kIntList:
int_list_ = new std::vector<int32_t>();
break;
case Type::kLongList:
long_list_ = new std::vector<int64_t>();
break;
case Type::kDoubleList:
double_list_ = new std::vector<double>();
break;
case Type::kList:
list_ = new std::vector<EncodableValue>();
break;
case Type::kMap:
map_ = new std::map<EncodableValue, EncodableValue>();
break;
}
}
~EncodableValue() { DestroyValue(); }
EncodableValue(const EncodableValue& other) {
DestroyValue();
type_ = other.type_;
switch (type_) {
case Type::kNull:
break;
case Type::kBool:
bool_ = other.bool_;
break;
case Type::kInt:
int_ = other.int_;
break;
case Type::kLong:
long_ = other.long_;
break;
case Type::kDouble:
double_ = other.double_;
break;
case Type::kString:
string_ = new std::string(*other.string_);
break;
case Type::kByteList:
byte_list_ = new std::vector<uint8_t>(*other.byte_list_);
break;
case Type::kIntList:
int_list_ = new std::vector<int32_t>(*other.int_list_);
break;
case Type::kLongList:
long_list_ = new std::vector<int64_t>(*other.long_list_);
break;
case Type::kDoubleList:
double_list_ = new std::vector<double>(*other.double_list_);
break;
case Type::kList:
list_ = new std::vector<EncodableValue>(*other.list_);
break;
case Type::kMap:
map_ = new std::map<EncodableValue, EncodableValue>(*other.map_);
break;
}
}
EncodableValue(EncodableValue&& other) noexcept { *this = std::move(other); }
EncodableValue& operator=(const EncodableValue& other) {
if (&other == this) {
return *this;
}
using std::swap;
EncodableValue temp(other);
swap(*this, temp);
return *this;
}
EncodableValue& operator=(EncodableValue&& other) noexcept {
if (&other == this) {
return *this;
}
DestroyValue();
type_ = other.type_;
switch (type_) {
case Type::kNull:
break;
case Type::kBool:
bool_ = other.bool_;
break;
case Type::kInt:
int_ = other.int_;
break;
case Type::kLong:
long_ = other.long_;
break;
case Type::kDouble:
double_ = other.double_;
break;
case Type::kString:
string_ = other.string_;
break;
case Type::kByteList:
byte_list_ = other.byte_list_;
break;
case Type::kIntList:
int_list_ = other.int_list_;
break;
case Type::kLongList:
long_list_ = other.long_list_;
break;
case Type::kDoubleList:
double_list_ = other.double_list_;
break;
case Type::kList:
list_ = other.list_;
break;
case Type::kMap:
map_ = other.map_;
break;
}
other.type_ = Type::kNull;
return *this;
}
template <typename T>
EncodableValue& operator=(const T& value) {
*this = EncodableValue(value);
return *this;
}
bool operator<(const EncodableValue& other) const {
if (type_ != other.type_) {
return type_ < other.type_;
}
switch (type_) {
case Type::kNull:
return false;
case Type::kBool:
return bool_ < other.bool_;
case Type::kInt:
return int_ < other.int_;
case Type::kLong:
return long_ < other.long_;
case Type::kDouble:
return double_ < other.double_;
case Type::kString:
return *string_ < *other.string_;
case Type::kByteList:
case Type::kIntList:
case Type::kLongList:
case Type::kDoubleList:
case Type::kList:
case Type::kMap:
return this < &other;
}
assert(false);
return false;
}
bool BoolValue() const {
assert(IsBool());
return bool_;
}
int32_t IntValue() const {
assert(IsInt());
return int_;
}
int64_t LongValue() const {
assert(IsLong() || IsInt());
if (IsLong()) {
return long_;
}
return int_;
}
double DoubleValue() const {
assert(IsDouble());
return double_;
}
const std::string& StringValue() const {
assert(IsString());
return *string_;
}
const std::vector<uint8_t>& ByteListValue() const {
assert(IsByteList());
return *byte_list_;
}
std::vector<uint8_t>& ByteListValue() {
assert(IsByteList());
return *byte_list_;
}
const std::vector<int32_t>& IntListValue() const {
assert(IsIntList());
return *int_list_;
}
std::vector<int32_t>& IntListValue() {
assert(IsIntList());
return *int_list_;
}
const std::vector<int64_t>& LongListValue() const {
assert(IsLongList());
return *long_list_;
}
std::vector<int64_t>& LongListValue() {
assert(IsLongList());
return *long_list_;
}
const std::vector<double>& DoubleListValue() const {
assert(IsDoubleList());
return *double_list_;
}
std::vector<double>& DoubleListValue() {
assert(IsDoubleList());
return *double_list_;
}
const EncodableList& ListValue() const {
assert(IsList());
return *list_;
}
EncodableList& ListValue() {
assert(IsList());
return *list_;
}
const EncodableMap& MapValue() const {
assert(IsMap());
return *map_;
}
EncodableMap& MapValue() {
assert(IsMap());
return *map_;
}
bool IsNull() const { return type_ == Type::kNull; }
bool IsBool() const { return type_ == Type::kBool; }
bool IsInt() const { return type_ == Type::kInt; }
bool IsLong() const { return type_ == Type::kLong; }
bool IsDouble() const { return type_ == Type::kDouble; }
bool IsString() const { return type_ == Type::kString; }
bool IsByteList() const { return type_ == Type::kByteList; }
bool IsIntList() const { return type_ == Type::kIntList; }
bool IsLongList() const { return type_ == Type::kLongList; }
bool IsDoubleList() const { return type_ == Type::kDoubleList; }
bool IsList() const { return type_ == Type::kList; }
bool IsMap() const { return type_ == Type::kMap; }
Type type() const { return type_; }
private:
void DestroyValue() {
switch (type_) {
case Type::kNull:
case Type::kBool:
case Type::kInt:
case Type::kLong:
case Type::kDouble:
break;
case Type::kString:
delete string_;
break;
case Type::kByteList:
delete byte_list_;
break;
case Type::kIntList:
delete int_list_;
break;
case Type::kLongList:
delete long_list_;
break;
case Type::kDoubleList:
delete double_list_;
break;
case Type::kList:
delete list_;
break;
case Type::kMap:
delete map_;
break;
}
type_ = Type::kNull;
}
union {
bool bool_;
int32_t int_;
int64_t long_;
double double_;
std::string* string_;
std::vector<uint8_t>* byte_list_;
std::vector<int32_t>* int_list_;
std::vector<int64_t>* long_list_;
std::vector<double>* double_list_;
std::vector<EncodableValue>* list_;
std::map<EncodableValue, EncodableValue>* map_;
};
Type type_ = Type::kNull;
};
} // namespace uiwidgets
#endif

70
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/engine_method_result.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_ENGINE_METHOD_RESULT_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_ENGINE_METHOD_RESULT_H_
#include <memory>
#include <string>
#include <vector>
#include "binary_messenger.h"
#include "method_codec.h"
#include "method_result.h"
namespace uiwidgets {
namespace internal {
class ReplyManager {
public:
ReplyManager(BinaryReply reply_handler_);
~ReplyManager();
ReplyManager(ReplyManager const&) = delete;
ReplyManager& operator=(ReplyManager const&) = delete;
void SendResponseData(const std::vector<uint8_t>* data);
private:
BinaryReply reply_handler_;
};
} // namespace internal
template <typename T>
class EngineMethodResult : public MethodResult<T> {
public:
EngineMethodResult(BinaryReply reply_handler, const MethodCodec<T>* codec)
: reply_manager_(
std::make_unique<internal::ReplyManager>(std::move(reply_handler))),
codec_(codec) {}
~EngineMethodResult() = default;
protected:
void SuccessInternal(const T* result) override {
std::unique_ptr<std::vector<uint8_t>> data =
codec_->EncodeSuccessEnvelope(result);
reply_manager_->SendResponseData(data.get());
}
void ErrorInternal(const std::string& error_code,
const std::string& error_message,
const T* error_details) override {
std::unique_ptr<std::vector<uint8_t>> data =
codec_->EncodeErrorEnvelope(error_code, error_message, error_details);
reply_manager_->SendResponseData(data.get());
}
void NotImplementedInternal() override {
reply_manager_->SendResponseData(nullptr);
}
private:
std::unique_ptr<internal::ReplyManager> reply_manager_;
const MethodCodec<T>* codec_;
};
} // namespace uiwidgets
#endif

32
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_message_codec.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_JSON_MESSAGE_CODEC_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_JSON_MESSAGE_CODEC_H_
#include "json_type.h"
#include "message_codec.h"
namespace uiwidgets {
class JsonMessageCodec : public MessageCodec<JsonValueType> {
public:
static const JsonMessageCodec& GetInstance();
~JsonMessageCodec() = default;
JsonMessageCodec(JsonMessageCodec const&) = delete;
JsonMessageCodec& operator=(JsonMessageCodec const&) = delete;
protected:
JsonMessageCodec() = default;
std::unique_ptr<JsonValueType> DecodeMessageInternal(
const uint8_t* binary_message, const size_t message_size) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeMessageInternal(
const JsonValueType& message) const override;
};
} // namespace uiwidgets
#endif

40
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_method_codec.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_JSON_METHOD_CODEC_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_JSON_METHOD_CODEC_H_
#include "json_type.h"
#include "method_call.h"
#include "method_codec.h"
namespace uiwidgets {
class JsonMethodCodec : public MethodCodec<JsonValueType> {
public:
static const JsonMethodCodec& GetInstance();
~JsonMethodCodec() = default;
JsonMethodCodec(JsonMethodCodec const&) = delete;
JsonMethodCodec& operator=(JsonMethodCodec const&) = delete;
protected:
JsonMethodCodec() = default;
std::unique_ptr<MethodCall<JsonValueType>> DecodeMethodCallInternal(
const uint8_t* message, const size_t message_size) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeMethodCallInternal(
const MethodCall<JsonValueType>& method_call) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelopeInternal(
const JsonValueType* result) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelopeInternal(
const std::string& error_code, const std::string& error_message,
const JsonValueType* error_details) const override;
};
} // namespace uiwidgets
#endif

16
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/json_type.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_JSON_TYPE_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_JSON_TYPE_H_
//#ifdef USE_RAPID_JSON
#include <rapidjson/document.h>
using JsonValueType = rapidjson::Document;
#/*else
#include <json/json.h>
using JsonValueType = Json::Value;
#endif*/
#endif

48
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/message_codec.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_MESSAGE_CODEC_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_MESSAGE_CODEC_H_
#include <memory>
#include <string>
#include <vector>
namespace uiwidgets {
template <typename T>
class MessageCodec {
public:
MessageCodec() = default;
virtual ~MessageCodec() = default;
MessageCodec(MessageCodec<T> const&) = delete;
MessageCodec& operator=(MessageCodec<T> const&) = delete;
std::unique_ptr<T> DecodeMessage(const uint8_t* binary_message,
const size_t message_size) const {
return std::move(DecodeMessageInternal(binary_message, message_size));
}
std::unique_ptr<T> DecodeMessage(
const std::vector<uint8_t>& binary_message) const {
size_t size = binary_message.size();
const uint8_t* data = size > 0 ? &binary_message[0] : nullptr;
return std::move(DecodeMessageInternal(data, size));
}
std::unique_ptr<std::vector<uint8_t>> EncodeMessage(const T& message) const {
return std::move(EncodeMessageInternal(message));
}
protected:
virtual std::unique_ptr<T> DecodeMessageInternal(
const uint8_t* binary_message, const size_t message_size) const = 0;
virtual std::unique_ptr<std::vector<uint8_t>> EncodeMessageInternal(
const T& message) const = 0;
};
} // namespace uiwidgets
#endif

33
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_call.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_TYPED_METHOD_CALL_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_TYPED_METHOD_CALL_H_
#include <memory>
#include <string>
namespace uiwidgets {
template <typename T>
class MethodCall {
public:
MethodCall(const std::string& method_name, std::unique_ptr<T> arguments)
: method_name_(method_name), arguments_(std::move(arguments)) {}
virtual ~MethodCall() = default;
MethodCall(MethodCall<T> const&) = delete;
MethodCall& operator=(MethodCall<T> const&) = delete;
const std::string& method_name() const { return method_name_; }
const T* arguments() const { return arguments_.get(); }
private:
std::string method_name_;
std::unique_ptr<T> arguments_;
};
} // namespace uiwidgets
#endif

82
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_channel.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_METHOD_CHANNEL_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_METHOD_CHANNEL_H_
#include <iostream>
#include <string>
#include "binary_messenger.h"
#include "engine_method_result.h"
#include "method_call.h"
#include "method_codec.h"
#include "method_result.h"
namespace uiwidgets {
template <typename T>
using MethodCallHandler = std::function<void(
const MethodCall<T>& call, std::unique_ptr<MethodResult<T>> result)>;
template <typename T>
class MethodChannel {
public:
MethodChannel(BinaryMessenger* messenger, const std::string& name,
const MethodCodec<T>* codec)
: messenger_(messenger), name_(name), codec_(codec) {}
~MethodChannel() = default;
MethodChannel(MethodChannel const&) = delete;
MethodChannel& operator=(MethodChannel const&) = delete;
void InvokeMethod(const std::string& method, std::unique_ptr<T> arguments) {
MethodCall<T> method_call(method, std::move(arguments));
std::unique_ptr<std::vector<uint8_t>> message =
codec_->EncodeMethodCall(method_call);
messenger_->Send(name_, message->data(), message->size(), nullptr);
}
void InvokeMethod(const std::string& method, std::unique_ptr<T> arguments,
uiwidgets::BinaryReply reply) {
MethodCall<T> method_call(method, std::move(arguments));
std::unique_ptr<std::vector<uint8_t>> message =
codec_->EncodeMethodCall(method_call);
messenger_->Send(name_, message->data(), message->size(), reply);
}
void SetMethodCallHandler(MethodCallHandler<T> handler) const {
if (!handler) {
messenger_->SetMessageHandler(name_, nullptr);
return;
}
const auto* codec = codec_;
std::string channel_name = name_;
BinaryMessageHandler binary_handler = [handler, codec, channel_name](
const uint8_t* message,
const size_t message_size,
BinaryReply reply) {
auto result =
std::make_unique<EngineMethodResult<T>>(std::move(reply), codec);
std::unique_ptr<MethodCall<T>> method_call =
codec->DecodeMethodCall(message, message_size);
if (!method_call) {
std::cerr << "Unable to construct method call from message on channel "
<< channel_name << std::endl;
result->NotImplemented();
return;
}
handler(*method_call, std::move(result));
};
messenger_->SetMessageHandler(name_, std::move(binary_handler));
}
private:
BinaryMessenger* messenger_;
std::string name_;
const MethodCodec<T>* codec_;
};
} // namespace uiwidgets
#endif

70
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_codec.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_METHOD_CODEC_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_METHOD_CODEC_H_
#include <memory>
#include <string>
#include <vector>
#include "method_call.h"
namespace uiwidgets {
template <typename T>
class MethodCodec {
public:
MethodCodec() = default;
virtual ~MethodCodec() = default;
MethodCodec(MethodCodec<T> const&) = delete;
MethodCodec& operator=(MethodCodec<T> const&) = delete;
std::unique_ptr<MethodCall<T>> DecodeMethodCall(
const uint8_t* message, const size_t message_size) const {
return std::move(DecodeMethodCallInternal(message, message_size));
}
std::unique_ptr<MethodCall<T>> DecodeMethodCall(
const std::vector<uint8_t>& message) const {
size_t size = message.size();
const uint8_t* data = size > 0 ? &message[0] : nullptr;
return std::move(DecodeMethodCallInternal(data, size));
}
std::unique_ptr<std::vector<uint8_t>> EncodeMethodCall(
const MethodCall<T>& method_call) const {
return std::move(EncodeMethodCallInternal(method_call));
}
std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelope(
const T* result = nullptr) const {
return std::move(EncodeSuccessEnvelopeInternal(result));
}
std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelope(
const std::string& error_code, const std::string& error_message = "",
const T* error_details = nullptr) const {
return std::move(
EncodeErrorEnvelopeInternal(error_code, error_message, error_details));
}
protected:
virtual std::unique_ptr<MethodCall<T>> DecodeMethodCallInternal(
const uint8_t* message, const size_t message_size) const = 0;
virtual std::unique_ptr<std::vector<uint8_t>> EncodeMethodCallInternal(
const MethodCall<T>& method_call) const = 0;
virtual std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelopeInternal(
const T* result) const = 0;
virtual std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelopeInternal(
const std::string& error_code, const std::string& error_message,
const T* error_details) const = 0;
};
} // namespace uiwidgets
#endif

42
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_result.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_METHOD_RESULT_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_METHOD_RESULT_H_
#include <string>
namespace uiwidgets {
template <typename T>
class MethodResult {
public:
MethodResult() = default;
virtual ~MethodResult() = default;
MethodResult(MethodResult const&) = delete;
MethodResult& operator=(MethodResult const&) = delete;
void Success(const T* result = nullptr) { SuccessInternal(result); }
void Error(const std::string& error_code,
const std::string& error_message = "",
const T* error_details = nullptr) {
ErrorInternal(error_code, error_message, error_details);
}
void NotImplemented() { NotImplementedInternal(); }
protected:
virtual void SuccessInternal(const T* result) = 0;
virtual void ErrorInternal(const std::string& error_code,
const std::string& error_message,
const T* error_details) = 0;
virtual void NotImplementedInternal() = 0;
};
} // namespace uiwidgets
#endif

48
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registrar.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_PLUGIN_REGISTRAR_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_PLUGIN_REGISTRAR_H_
#include "shell/platform/common/cpp/public/uiwidgets_plugin_registrar.h"
#include <memory>
#include <set>
#include <string>
#include "binary_messenger.h"
namespace uiwidgets {
class Plugin;
class PluginRegistrar {
public:
explicit PluginRegistrar(UIWidgetsDesktopPluginRegistrarRef core_registrar);
virtual ~PluginRegistrar();
PluginRegistrar(PluginRegistrar const&) = delete;
PluginRegistrar& operator=(PluginRegistrar const&) = delete;
BinaryMessenger* messenger() { return messenger_.get(); }
void AddPlugin(std::unique_ptr<Plugin> plugin);
void EnableInputBlockingForChannel(const std::string& channel);
private:
UIWidgetsDesktopPluginRegistrarRef registrar_;
std::unique_ptr<BinaryMessenger> messenger_;
std::set<std::unique_ptr<Plugin>> plugins_;
};
class Plugin {
public:
virtual ~Plugin() = default;
};
} // namespace uiwidgets
#endif

26
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registry.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_PLUGIN_REGISTRY_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_PLUGIN_REGISTRY_H_
#include "shell/platform/common/cpp/public/uiwidgets_plugin_registrar.h"
#include <string>
namespace uiwidgets {
class PluginRegistry {
public:
PluginRegistry() = default;
virtual ~PluginRegistry() = default;
PluginRegistry(PluginRegistry const&) = delete;
PluginRegistry& operator=(PluginRegistry const&) = delete;
virtual UIWidgetsDesktopPluginRegistrarRef GetRegistrarForPlugin(
const std::string& plugin_name) = 0;
};
} // namespace uiwidgets
#endif

32
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_message_codec.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_STANDARD_MESSAGE_CODEC_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_STANDARD_MESSAGE_CODEC_H_
#include "encodable_value.h"
#include "message_codec.h"
namespace uiwidgets {
class StandardMessageCodec : public MessageCodec<EncodableValue> {
public:
static const StandardMessageCodec& GetInstance();
~StandardMessageCodec();
StandardMessageCodec(StandardMessageCodec const&) = delete;
StandardMessageCodec& operator=(StandardMessageCodec const&) = delete;
protected:
StandardMessageCodec();
std::unique_ptr<EncodableValue> DecodeMessageInternal(
const uint8_t* binary_message, const size_t message_size) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeMessageInternal(
const EncodableValue& message) const override;
};
} // namespace uiwidgets
#endif

40
engine/src/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_method_codec.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_STANDARD_METHOD_CODEC_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_UIWIDGETS_STANDARD_METHOD_CODEC_H_
#include "encodable_value.h"
#include "method_call.h"
#include "method_codec.h"
namespace uiwidgets {
class StandardMethodCodec : public MethodCodec<EncodableValue> {
public:
static const StandardMethodCodec& GetInstance();
~StandardMethodCodec() = default;
StandardMethodCodec(StandardMethodCodec const&) = delete;
StandardMethodCodec& operator=(StandardMethodCodec const&) = delete;
protected:
StandardMethodCodec() = default;
std::unique_ptr<MethodCall<EncodableValue>> DecodeMethodCallInternal(
const uint8_t* message, const size_t message_size) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeMethodCallInternal(
const MethodCall<EncodableValue>& method_call) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelopeInternal(
const EncodableValue* result) const override;
std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelopeInternal(
const std::string& error_code, const std::string& error_message,
const EncodableValue* error_details) const override;
};
} // namespace uiwidgets
#endif

70
engine/src/shell/platform/common/cpp/client_wrapper/json_message_codec.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//#define USE_RAPID_JSON
#include "include/uiwidgets/json_message_codec.h"
#include <iostream>
#include <string>
//#ifdef USE_RAPID_JSON
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
//#endif
namespace uiwidgets {
// static
const JsonMessageCodec& JsonMessageCodec::GetInstance() {
static JsonMessageCodec sInstance;
return sInstance;
}
std::unique_ptr<std::vector<uint8_t>> JsonMessageCodec::EncodeMessageInternal(
const JsonValueType& message) const {
//#ifdef USE_RAPID_JSON
// TODO: Look into alternate writers that would avoid the buffer copy.
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
message.Accept(writer);
const char* buffer_start = buffer.GetString();
return std::make_unique<std::vector<uint8_t>>(
buffer_start, buffer_start + buffer.GetSize());
//#else
// Json::StreamWriterBuilder writer_builder;
// std::string serialization = Json::writeString(writer_builder, message);
// return std::make_unique<std::vector<uint8_t>>(serialization.begin(),
// serialization.end());
//#endif
}
std::unique_ptr<JsonValueType> JsonMessageCodec::DecodeMessageInternal(
const uint8_t* binary_message,
const size_t message_size) const {
auto raw_message = reinterpret_cast<const char*>(binary_message);
auto json_message = std::make_unique<JsonValueType>();
std::string parse_errors;
bool parsing_successful = false;
//#ifdef USE_RAPID_JSON
rapidjson::ParseResult result =
json_message->Parse(raw_message, message_size);
parsing_successful = result == rapidjson::ParseErrorCode::kParseErrorNone;
if (!parsing_successful) {
parse_errors = rapidjson::GetParseError_En(result.Code());
}
//#else
// Json::CharReaderBuilder reader_builder;
// std::unique_ptr<Json::CharReader> parser(reader_builder.newCharReader());
// parsing_successful = parser->parse(raw_message, raw_message + message_size,
// json_message.get(), &parse_errors);
//#endif
if (!parsing_successful) {
std::cerr << "Unable to parse JSON message:" << std::endl
<< parse_errors << std::endl;
return nullptr;
}
return json_message;
}
} // namespace uiwidgets

140
engine/src/shell/platform/common/cpp/client_wrapper/json_method_codec.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/uiwidgets/json_method_codec.h"
#include "include/uiwidgets/json_message_codec.h"
namespace uiwidgets {
namespace {
// Keys used in MethodCall encoding.
constexpr char kMessageMethodKey[] = "method";
constexpr char kMessageArgumentsKey[] = "args";
} // namespace
// static
const JsonMethodCodec& JsonMethodCodec::GetInstance() {
static JsonMethodCodec sInstance;
return sInstance;
}
std::unique_ptr<MethodCall<JsonValueType>>
JsonMethodCodec::DecodeMethodCallInternal(const uint8_t* message,
const size_t message_size) const {
std::unique_ptr<JsonValueType> json_message =
JsonMessageCodec::GetInstance().DecodeMessage(message, message_size);
if (!json_message) {
return nullptr;
}
//#if USE_RAPID_JSON
auto method_name_iter = json_message->FindMember(kMessageMethodKey);
if (method_name_iter == json_message->MemberEnd()) {
return nullptr;
}
if (!method_name_iter->value.IsString()) {
return nullptr;
}
std::string method_name(method_name_iter->value.GetString());
auto arguments_iter = json_message->FindMember(kMessageArgumentsKey);
std::unique_ptr<rapidjson::Document> arguments;
if (arguments_iter != json_message->MemberEnd()) {
// Pull the arguments subtree up to the root of json_message. This is
// destructive to json_message, but the full value is no longer needed, and
// this avoids a subtree copy.
// Note: The static_cast is for compatibility with RapidJSON 1.1; master
// already allows swapping a Document with a Value directly. Once there is
// a new RapidJSON release (at which point clients can be expected to have
// that change in the version they depend on) remove the cast.
static_cast<rapidjson::Value*>(json_message.get())
->Swap(arguments_iter->value);
// Swap it into |arguments|. This moves the allocator ownership, so that
// the data won't be deleted when json_message goes out of scope.
arguments = std::make_unique<rapidjson::Document>();
arguments->Swap(*json_message);
}
return std::make_unique<MethodCall<rapidjson::Document>>(
method_name, std::move(arguments));
//#else
// Json::Value method = (*json_message)[kMessageMethodKey];
// if (method.isNull()) {
// return nullptr;
// }
// return std::make_unique<MethodCall<Json::Value>>(
// method.asString(),
// std::make_unique<Json::Value>((*json_message)[kMessageArgumentsKey]));
//#endif
}
std::unique_ptr<std::vector<uint8_t>> JsonMethodCodec::EncodeMethodCallInternal(
const MethodCall<JsonValueType>& method_call) const {
//#if USE_RAPID_JSON
// TODO: Consider revisiting the codec APIs to avoid the need to copy
// everything when doing encoding (e.g., by having a version that takes
// owership of the object to encode, so that it can be moved instead).
rapidjson::Document message(rapidjson::kObjectType);
auto& allocator = message.GetAllocator();
rapidjson::Value name(method_call.method_name(), allocator);
rapidjson::Value arguments;
if (method_call.arguments()) {
arguments.CopyFrom(*method_call.arguments(), allocator);
}
message.AddMember(kMessageMethodKey, name, allocator);
message.AddMember(kMessageArgumentsKey, arguments, allocator);
//#else
// Json::Value message(Json::objectValue);
// message[kMessageMethodKey] = method_call.method_name();
// const Json::Value* arguments = method_call.arguments();
// message[kMessageArgumentsKey] = arguments ? *arguments : Json::Value();
//#endif
return JsonMessageCodec::GetInstance().EncodeMessage(message);
}
std::unique_ptr<std::vector<uint8_t>>
JsonMethodCodec::EncodeSuccessEnvelopeInternal(
const JsonValueType* result) const {
//#if USE_RAPID_JSON
rapidjson::Document envelope;
envelope.SetArray();
rapidjson::Value result_value;
if (result) {
result_value.CopyFrom(*result, envelope.GetAllocator());
}
envelope.PushBack(result_value, envelope.GetAllocator());
//#else
// Json::Value envelope(Json::arrayValue);
// envelope.append(result == nullptr ? Json::Value() : *result);
//#endif
return JsonMessageCodec::GetInstance().EncodeMessage(envelope);
}
std::unique_ptr<std::vector<uint8_t>>
JsonMethodCodec::EncodeErrorEnvelopeInternal(
const std::string& error_code,
const std::string& error_message,
const JsonValueType* error_details) const {
//#if USE_RAPID_JSON
rapidjson::Document envelope(rapidjson::kArrayType);
auto& allocator = envelope.GetAllocator();
envelope.PushBack(rapidjson::Value(error_code, allocator), allocator);
envelope.PushBack(rapidjson::Value(error_message, allocator), allocator);
rapidjson::Value details_value;
if (error_details) {
details_value.CopyFrom(*error_details, allocator);
}
envelope.PushBack(details_value, allocator);
//#else
// Json::Value envelope(Json::arrayValue);
// envelope.append(error_code);
// envelope.append(error_message.empty() ? Json::Value() : error_message);
// envelope.append(error_details == nullptr ? Json::Value() : *error_details);
//#endif
return JsonMessageCodec::GetInstance().EncodeMessage(envelope);
}
} // namespace uiwidgets

23
engine/src/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc


// // Copyright 2013 The UIWidgets Authors. All rights reserved.
// // Use of this source code is governed by a BSD-style license that can be
// // found in the LICENSE file.
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_call.h"
// #include <memory>
// #include <string>
// #include "gtest/gtest.h"
// namespace uiwidgets {
// TEST(MethodCallTest, Basic) {
// const std::string method_name("method_name");
// const int argument = 42;
// MethodCall<int> method_call(method_name, std::make_unique<int>(argument));
// EXPECT_EQ(method_call.method_name(), method_name);
// ASSERT_NE(method_call.arguments(), nullptr);
// EXPECT_EQ(*method_call.arguments(), 42);
// }
// } // namespace uiwidgets

94
engine/src/shell/platform/common/cpp/client_wrapper/method_channel_unittests.cc


//// Copyright 2013 The UIWidgets Authors. All rights reserved.
//// Use of this source code is governed by a BSD-style license that can be
//// found in the LICENSE file.
//
//#include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/method_channel.h"
//
//#include <memory>
//#include <string>
//
//#include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/binary_messenger.h"
//#include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_method_codec.h"
//#include "gtest/gtest.h"
//
//namespace uiwidgets {
//
//namespace {
//
//class TestBinaryMessenger : public BinaryMessenger {
// public:
// void Send(const std::string& channel,
// const uint8_t* message,
// const size_t message_size) const override {}
//
// void Send(const std::string& channel,
// const uint8_t* message,
// const size_t message_size,
// BinaryReply reply) const override {}
//
// void SetMessageHandler(const std::string& channel,
// BinaryMessageHandler handler) override {
// last_message_handler_channel_ = channel;
// last_message_handler_ = handler;
// }
//
// std::string last_message_handler_channel() {
// return last_message_handler_channel_;
// }
//
// BinaryMessageHandler last_message_handler() { return last_message_handler_; }
//
// private:
// std::string last_message_handler_channel_;
// BinaryMessageHandler last_message_handler_;
//};
//
//} // namespace
//
//// Tests that SetMethodCallHandler sets a handler that correctly interacts with
//// the binary messenger.
//TEST(MethodChannelTest, Registration) {
// TestBinaryMessenger messenger;
// const std::string channel_name("some_channel");
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// MethodChannel channel(&messenger, channel_name, &codec);
//
// bool callback_called = false;
// const std::string method_name("hello");
// channel.SetMethodCallHandler(
// [&callback_called, method_name](const auto& call, auto result) {
// callback_called = true;
// // Ensure that the wrapper recieved a correctly decoded call and a
// // result.
// EXPECT_EQ(call.method_name(), method_name);
// EXPECT_NE(result, nullptr);
// });
// EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
// EXPECT_NE(messenger.last_message_handler(), nullptr);
// // Send a test message to trigger the handler test assertions.
// MethodCall<EncodableValue> call(method_name, nullptr);
// auto message = codec.EncodeMethodCall(call);
//
// messenger.last_message_handler()(
// message->data(), message->size(),
// [](const uint8_t* reply, const size_t reply_size) {});
// EXPECT_EQ(callback_called, true);
//}
//
//// Tests that SetMethodCallHandler with a null handler unregisters the handler.
//TEST(MethodChannelTest, Unregistration) {
// TestBinaryMessenger messenger;
// const std::string channel_name("some_channel");
// MethodChannel channel(&messenger, channel_name,
// &uiwidgets::StandardMethodCodec::GetInstance());
//
// channel.SetMethodCallHandler([](const auto& call, auto result) {});
// EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
// EXPECT_NE(messenger.last_message_handler(), nullptr);
//
// channel.SetMethodCallHandler(nullptr);
// EXPECT_EQ(messenger.last_message_handler_channel(), channel_name);
// EXPECT_EQ(messenger.last_message_handler(), nullptr);
//}
//
//} // namespace uiwidgets

160
engine/src/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/uiwidgets/plugin_registrar.h"
#include <iostream>
#include <map>
#include "include/uiwidgets/engine_method_result.h"
#include "include/uiwidgets/method_channel.h"
namespace uiwidgets {
namespace {
// Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
// with a BinaryReply that will send a response on |message|'s response handle.
//
// This serves as an adaptor between the function-pointer-based message callback
// interface provided by the C API and the std::function-based message handler
// interface of BinaryMessenger.
void ForwardToHandler(UIWidgetsDesktopMessengerRef messenger,
const UIWidgetsDesktopMessage* message,
void* user_data) {
auto* response_handle = message->response_handle;
BinaryReply reply_handler = [messenger, response_handle](
const uint8_t* reply,
const size_t reply_size) mutable {
if (!response_handle) {
std::cerr << "Error: Response can be set only once. Ignoring "
"duplicate response."
<< std::endl;
return;
}
UIWidgetsDesktopMessengerSendResponse(messenger, response_handle, reply,
reply_size);
// The engine frees the response handle once
// UIWidgetsDesktopSendMessageResponse is called.
response_handle = nullptr;
};
const BinaryMessageHandler& message_handler =
*static_cast<BinaryMessageHandler*>(user_data);
message_handler(message->message, message->message_size,
std::move(reply_handler));
}
} // namespace
// Wrapper around a UIWidgetsDesktopMessengerRef that implements the
// BinaryMessenger API.
class BinaryMessengerImpl : public BinaryMessenger {
public:
explicit BinaryMessengerImpl(UIWidgetsDesktopMessengerRef core_messenger)
: messenger_(core_messenger) {}
virtual ~BinaryMessengerImpl() = default;
// Prevent copying.
BinaryMessengerImpl(BinaryMessengerImpl const&) = delete;
BinaryMessengerImpl& operator=(BinaryMessengerImpl const&) = delete;
// |uiwidgets::BinaryMessenger|
void Send(const std::string& channel,
const uint8_t* message,
const size_t message_size) const override;
// |uiwidgets::BinaryMessenger|
void Send(const std::string& channel,
const uint8_t* message,
const size_t message_size,
BinaryReply reply) const override;
// |uiwidgets::BinaryMessenger|
void SetMessageHandler(const std::string& channel,
BinaryMessageHandler handler) override;
private:
// Handle for interacting with the C API.
UIWidgetsDesktopMessengerRef messenger_;
// A map from channel names to the BinaryMessageHandler that should be called
// for incoming messages on that channel.
std::map<std::string, BinaryMessageHandler> handlers_;
};
void BinaryMessengerImpl::Send(const std::string& channel,
const uint8_t* message,
const size_t message_size) const {
UIWidgetsDesktopMessengerSend(messenger_, channel.c_str(), message,
message_size);
}
void BinaryMessengerImpl::Send(const std::string& channel,
const uint8_t* message,
const size_t message_size,
BinaryReply reply) const {
if (reply == nullptr) {
UIWidgetsDesktopMessengerSend(messenger_, channel.c_str(), message,
message_size);
return;
}
struct Captures {
BinaryReply reply;
};
auto captures = new Captures();
captures->reply = reply;
auto message_reply = [](const uint8_t* data, size_t data_size,
void* user_data) {
auto captures = reinterpret_cast<Captures*>(user_data);
captures->reply(data, data_size);
delete captures;
};
bool result = UIWidgetsDesktopMessengerSendWithReply(
messenger_, channel.c_str(), message, message_size, message_reply,
captures);
if (!result) {
delete captures;
}
}
void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
BinaryMessageHandler handler) {
if (!handler) {
handlers_.erase(channel);
UIWidgetsDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr,
nullptr);
return;
}
// Save the handler, to keep it alive.
handlers_[channel] = std::move(handler);
BinaryMessageHandler* message_handler = &handlers_[channel];
// Set an adaptor callback that will invoke the handler.
UIWidgetsDesktopMessengerSetCallback(messenger_, channel.c_str(),
ForwardToHandler, message_handler);
}
// PluginRegistrar:
PluginRegistrar::PluginRegistrar(UIWidgetsDesktopPluginRegistrarRef registrar)
: registrar_(registrar) {
auto core_messenger = UIWidgetsDesktopRegistrarGetMessenger(registrar_);
messenger_ = std::make_unique<BinaryMessengerImpl>(core_messenger);
}
PluginRegistrar::~PluginRegistrar() {}
void PluginRegistrar::AddPlugin(std::unique_ptr<Plugin> plugin) {
plugins_.insert(std::move(plugin));
}
void PluginRegistrar::EnableInputBlockingForChannel(
const std::string& channel) {
UIWidgetsDesktopRegistrarEnableInputBlocking(registrar_, channel.c_str());
}
} // namespace uiwidgets

95
engine/src/shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc


// // Copyright 2013 The UIWidgets Authors. All rights reserved.
// // Use of this source code is governed by a BSD-style license that can be
// // found in the LICENSE file.
// #include <memory>
// #include <vector>
// #include "shell/platform/common/cpp/client_wrapper/include/uiwidgets/plugin_registrar.h"
// #include "shell/platform/common/cpp/client_wrapper/testing/stub_uiwidgets_api.h"
// #include "gtest/gtest.h"
// namespace uiwidgets {
// namespace {
// // Stub implementation to validate calls to the API.
// class TestApi : public testing::StubUIWidgetsApi {
// public:
// // |uiwidgets::testing::StubUIWidgetsApi|
// bool MessengerSend(const char* channel,
// const uint8_t* message,
// const size_t message_size) override {
// last_data_sent_ = message;
// return message_engine_result;
// }
// bool MessengerSendWithReply(const char* channel,
// const uint8_t* message,
// const size_t message_size,
// const UIWidgetsDesktopBinaryReply reply,
// void* user_data) override {
// last_data_sent_ = message;
// return message_engine_result;
// }
// // Called for UIWidgetsDesktopMessengerSetCallback.
// void MessengerSetCallback(const char* channel,
// UIWidgetsDesktopMessageCallback callback,
// void* user_data) override {
// last_callback_set_ = callback;
// }
// const uint8_t* last_data_sent() { return last_data_sent_; }
// UIWidgetsDesktopMessageCallback last_callback_set() {
// return last_callback_set_;
// }
// private:
// const uint8_t* last_data_sent_ = nullptr;
// UIWidgetsDesktopMessageCallback last_callback_set_ = nullptr;
// };
// } // namespace
// // Tests that the registrar returns a messenger that passes Send through to the
// // C API.
// TEST(MethodCallTest, MessengerSend) {
// testing::ScopedStubUIWidgetsApi scoped_api_stub(std::make_unique<TestApi>());
// auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
// auto dummy_registrar_handle =
// reinterpret_cast<UIWidgetsDesktopPluginRegistrarRef>(1);
// PluginRegistrar registrar(dummy_registrar_handle);
// BinaryMessenger* messenger = registrar.messenger();
// std::vector<uint8_t> message = {1, 2, 3, 4};
// messenger->Send("some_channel", &message[0], message.size());
// EXPECT_EQ(test_api->last_data_sent(), &message[0]);
// }
// // Tests that the registrar returns a messenger that passes callback
// // registration and unregistration through to the C API.
// TEST(MethodCallTest, MessengerSetMessageHandler) {
// testing::ScopedStubUIWidgetsApi scoped_api_stub(std::make_unique<TestApi>());
// auto test_api = static_cast<TestApi*>(scoped_api_stub.stub());
// auto dummy_registrar_handle =
// reinterpret_cast<UIWidgetsDesktopPluginRegistrarRef>(1);
// PluginRegistrar registrar(dummy_registrar_handle);
// BinaryMessenger* messenger = registrar.messenger();
// const std::string channel_name("foo");
// // Register.
// BinaryMessageHandler binary_handler = [](const uint8_t* message,
// const size_t message_size,
// BinaryReply reply) {};
// messenger->SetMessageHandler(channel_name, std::move(binary_handler));
// EXPECT_NE(test_api->last_callback_set(), nullptr);
// // Unregister.
// messenger->SetMessageHandler(channel_name, nullptr);
// EXPECT_EQ(test_api->last_callback_set(), nullptr);
// }
// } // namespace uiwidgets

383
engine/src/shell/platform/common/cpp/client_wrapper/standard_codec.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file contains what would normally be standard_codec_serializer.cc,
// standard_message_codec.cc, and standard_method_codec.cc. They are grouped
// together to simplify use of the client wrapper, since the common case is
// that any client that needs one of these files needs all three.
#include "include/uiwidgets/standard_message_codec.h"
#include "include/uiwidgets/standard_method_codec.h"
#include "standard_codec_serializer.h"
#include <assert.h>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#include <vector>
namespace uiwidgets {
// ===== standard_codec_serializer.h =====
namespace {
// The order/values here must match the constants in message_codecs.dart.
enum class EncodedType {
kNull = 0,
kTrue,
kFalse,
kInt32,
kInt64,
kLargeInt, // No longer used. If encountered, treat as kString.
kFloat64,
kString,
kUInt8List,
kInt32List,
kInt64List,
kFloat64List,
kList,
kMap,
};
// Returns the encoded type that should be written when serializing |value|.
EncodedType EncodedTypeForValue(const EncodableValue& value) {
switch (value.type()) {
case EncodableValue::Type::kNull:
return EncodedType::kNull;
case EncodableValue::Type::kBool:
return value.BoolValue() ? EncodedType::kTrue : EncodedType::kFalse;
case EncodableValue::Type::kInt:
return EncodedType::kInt32;
case EncodableValue::Type::kLong:
return EncodedType::kInt64;
case EncodableValue::Type::kDouble:
return EncodedType::kFloat64;
case EncodableValue::Type::kString:
return EncodedType::kString;
case EncodableValue::Type::kByteList:
return EncodedType::kUInt8List;
case EncodableValue::Type::kIntList:
return EncodedType::kInt32List;
case EncodableValue::Type::kLongList:
return EncodedType::kInt64List;
case EncodableValue::Type::kDoubleList:
return EncodedType::kFloat64List;
case EncodableValue::Type::kList:
return EncodedType::kList;
case EncodableValue::Type::kMap:
return EncodedType::kMap;
}
assert(false);
return EncodedType::kNull;
}
} // namespace
StandardCodecSerializer::StandardCodecSerializer() = default;
StandardCodecSerializer::~StandardCodecSerializer() = default;
EncodableValue StandardCodecSerializer::ReadValue(
ByteBufferStreamReader* stream) const {
EncodedType type = static_cast<EncodedType>(stream->ReadByte());
;
switch (type) {
case EncodedType::kNull:
return EncodableValue();
case EncodedType::kTrue:
return EncodableValue(true);
case EncodedType::kFalse:
return EncodableValue(false);
case EncodedType::kInt32: {
int32_t int_value = 0;
stream->ReadBytes(reinterpret_cast<uint8_t*>(&int_value), 4);
return EncodableValue(int_value);
}
case EncodedType::kInt64: {
int64_t long_value = 0;
stream->ReadBytes(reinterpret_cast<uint8_t*>(&long_value), 8);
return EncodableValue(long_value);
}
case EncodedType::kFloat64: {
double double_value = 0;
stream->ReadAlignment(8);
stream->ReadBytes(reinterpret_cast<uint8_t*>(&double_value), 8);
return EncodableValue(double_value);
}
case EncodedType::kLargeInt:
case EncodedType::kString: {
size_t size = ReadSize(stream);
std::string string_value;
string_value.resize(size);
stream->ReadBytes(reinterpret_cast<uint8_t*>(&string_value[0]), size);
return EncodableValue(string_value);
}
case EncodedType::kUInt8List:
return ReadVector<uint8_t>(stream);
case EncodedType::kInt32List:
return ReadVector<int32_t>(stream);
case EncodedType::kInt64List:
return ReadVector<int64_t>(stream);
case EncodedType::kFloat64List:
return ReadVector<double>(stream);
case EncodedType::kList: {
size_t length = ReadSize(stream);
EncodableList list_value;
list_value.reserve(length);
for (size_t i = 0; i < length; ++i) {
list_value.push_back(ReadValue(stream));
}
return EncodableValue(list_value);
}
case EncodedType::kMap: {
size_t length = ReadSize(stream);
EncodableMap map_value;
for (size_t i = 0; i < length; ++i) {
EncodableValue key = ReadValue(stream);
EncodableValue value = ReadValue(stream);
map_value.emplace(std::move(key), std::move(value));
}
return EncodableValue(map_value);
}
}
std::cerr << "Unknown type in StandardCodecSerializer::ReadValue: "
<< static_cast<int>(type) << std::endl;
return EncodableValue();
}
void StandardCodecSerializer::WriteValue(const EncodableValue& value,
ByteBufferStreamWriter* stream) const {
stream->WriteByte(static_cast<uint8_t>(EncodedTypeForValue(value)));
switch (value.type()) {
case EncodableValue::Type::kNull:
case EncodableValue::Type::kBool:
// Null and bool are encoded directly in the type.
break;
case EncodableValue::Type::kInt: {
int32_t int_value = value.IntValue();
stream->WriteBytes(reinterpret_cast<const uint8_t*>(&int_value), 4);
break;
}
case EncodableValue::Type::kLong: {
int64_t long_value = value.LongValue();
stream->WriteBytes(reinterpret_cast<const uint8_t*>(&long_value), 8);
break;
}
case EncodableValue::Type::kDouble: {
stream->WriteAlignment(8);
double double_value = value.DoubleValue();
stream->WriteBytes(reinterpret_cast<const uint8_t*>(&double_value), 8);
break;
}
case EncodableValue::Type::kString: {
const auto& string_value = value.StringValue();
size_t size = string_value.size();
WriteSize(size, stream);
if (size > 0) {
stream->WriteBytes(
reinterpret_cast<const uint8_t*>(string_value.data()), size);
}
break;
}
case EncodableValue::Type::kByteList:
WriteVector(value.ByteListValue(), stream);
break;
case EncodableValue::Type::kIntList:
WriteVector(value.IntListValue(), stream);
break;
case EncodableValue::Type::kLongList:
WriteVector(value.LongListValue(), stream);
break;
case EncodableValue::Type::kDoubleList:
WriteVector(value.DoubleListValue(), stream);
break;
case EncodableValue::Type::kList:
WriteSize(value.ListValue().size(), stream);
for (const auto& item : value.ListValue()) {
WriteValue(item, stream);
}
break;
case EncodableValue::Type::kMap:
WriteSize(value.MapValue().size(), stream);
for (const auto& pair : value.MapValue()) {
WriteValue(pair.first, stream);
WriteValue(pair.second, stream);
}
break;
}
}
size_t StandardCodecSerializer::ReadSize(ByteBufferStreamReader* stream) const {
uint8_t byte = stream->ReadByte();
if (byte < 254) {
return byte;
} else if (byte == 254) {
uint16_t value;
stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 2);
return value;
} else {
uint32_t value;
stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 4);
return value;
}
}
void StandardCodecSerializer::WriteSize(size_t size,
ByteBufferStreamWriter* stream) const {
if (size < 254) {
stream->WriteByte(static_cast<uint8_t>(size));
} else if (size <= 0xffff) {
stream->WriteByte(254);
uint16_t value = static_cast<uint16_t>(size);
stream->WriteBytes(reinterpret_cast<uint8_t*>(&value), 2);
} else {
stream->WriteByte(255);
uint32_t value = static_cast<uint32_t>(size);
stream->WriteBytes(reinterpret_cast<uint8_t*>(&value), 4);
}
}
template <typename T>
EncodableValue StandardCodecSerializer::ReadVector(
ByteBufferStreamReader* stream) const {
size_t count = ReadSize(stream);
std::vector<T> vector;
vector.resize(count);
uint8_t type_size = static_cast<uint8_t>(sizeof(T));
if (type_size > 1) {
stream->ReadAlignment(type_size);
}
stream->ReadBytes(reinterpret_cast<uint8_t*>(vector.data()),
count * type_size);
return EncodableValue(vector);
}
template <typename T>
void StandardCodecSerializer::WriteVector(
const std::vector<T> vector,
ByteBufferStreamWriter* stream) const {
size_t count = vector.size();
WriteSize(count, stream);
if (count == 0) {
return;
}
uint8_t type_size = static_cast<uint8_t>(sizeof(T));
if (type_size > 1) {
stream->WriteAlignment(type_size);
}
stream->WriteBytes(reinterpret_cast<const uint8_t*>(vector.data()),
count * type_size);
}
// ===== standard_message_codec.h =====
// static
const StandardMessageCodec& StandardMessageCodec::GetInstance() {
static StandardMessageCodec sInstance;
return sInstance;
}
StandardMessageCodec::StandardMessageCodec() = default;
StandardMessageCodec::~StandardMessageCodec() = default;
std::unique_ptr<EncodableValue> StandardMessageCodec::DecodeMessageInternal(
const uint8_t* binary_message,
const size_t message_size) const {
StandardCodecSerializer serializer;
ByteBufferStreamReader stream(binary_message, message_size);
return std::make_unique<EncodableValue>(serializer.ReadValue(&stream));
}
std::unique_ptr<std::vector<uint8_t>>
StandardMessageCodec::EncodeMessageInternal(
const EncodableValue& message) const {
StandardCodecSerializer serializer;
auto encoded = std::make_unique<std::vector<uint8_t>>();
ByteBufferStreamWriter stream(encoded.get());
serializer.WriteValue(message, &stream);
return encoded;
}
// ===== standard_method_codec.h =====
// static
const StandardMethodCodec& StandardMethodCodec::GetInstance() {
static StandardMethodCodec sInstance;
return sInstance;
}
std::unique_ptr<MethodCall<EncodableValue>>
StandardMethodCodec::DecodeMethodCallInternal(const uint8_t* message,
const size_t message_size) const {
StandardCodecSerializer serializer;
ByteBufferStreamReader stream(message, message_size);
EncodableValue method_name = serializer.ReadValue(&stream);
if (!method_name.IsString()) {
std::cerr << "Invalid method call; method name is not a string."
<< std::endl;
return nullptr;
}
auto arguments =
std::make_unique<EncodableValue>(serializer.ReadValue(&stream));
return std::make_unique<MethodCall<EncodableValue>>(method_name.StringValue(),
std::move(arguments));
}
std::unique_ptr<std::vector<uint8_t>>
StandardMethodCodec::EncodeMethodCallInternal(
const MethodCall<EncodableValue>& method_call) const {
StandardCodecSerializer serializer;
auto encoded = std::make_unique<std::vector<uint8_t>>();
ByteBufferStreamWriter stream(encoded.get());
serializer.WriteValue(EncodableValue(method_call.method_name()), &stream);
if (method_call.arguments()) {
serializer.WriteValue(*method_call.arguments(), &stream);
} else {
serializer.WriteValue(EncodableValue(), &stream);
}
return encoded;
}
std::unique_ptr<std::vector<uint8_t>>
StandardMethodCodec::EncodeSuccessEnvelopeInternal(
const EncodableValue* result) const {
StandardCodecSerializer serializer;
auto encoded = std::make_unique<std::vector<uint8_t>>();
ByteBufferStreamWriter stream(encoded.get());
stream.WriteByte(0);
if (result) {
serializer.WriteValue(*result, &stream);
} else {
serializer.WriteValue(EncodableValue(), &stream);
}
return encoded;
}
std::unique_ptr<std::vector<uint8_t>>
StandardMethodCodec::EncodeErrorEnvelopeInternal(
const std::string& error_code,
const std::string& error_message,
const EncodableValue* error_details) const {
StandardCodecSerializer serializer;
auto encoded = std::make_unique<std::vector<uint8_t>>();
ByteBufferStreamWriter stream(encoded.get());
stream.WriteByte(1);
serializer.WriteValue(EncodableValue(error_code), &stream);
if (error_message.empty()) {
serializer.WriteValue(EncodableValue(), &stream);
} else {
serializer.WriteValue(EncodableValue(error_message), &stream);
}
if (error_details) {
serializer.WriteValue(*error_details, &stream);
} else {
serializer.WriteValue(EncodableValue(), &stream);
}
return encoded;
}
} // namespace uiwidgets

54
engine/src/shell/platform/common/cpp/client_wrapper/standard_codec_serializer.h


// Copyright 2013 The UIWidgets 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 UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_ENCODABLE_VALUE_SERIALIZER_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_ENCODABLE_VALUE_SERIALIZER_H_
#include "byte_stream_wrappers.h"
#include "include/uiwidgets/encodable_value.h"
namespace uiwidgets {
// Encapsulates the logic for encoding/decoding EncodableValues to/from the
// standard codec binary representation.
class StandardCodecSerializer {
public:
StandardCodecSerializer();
~StandardCodecSerializer();
// Prevent copying.
StandardCodecSerializer(StandardCodecSerializer const&) = delete;
StandardCodecSerializer& operator=(StandardCodecSerializer const&) = delete;
// Reads and returns the next value from |stream|.
EncodableValue ReadValue(ByteBufferStreamReader* stream) const;
// Writes the encoding of |value| to |stream|.
void WriteValue(const EncodableValue& value,
ByteBufferStreamWriter* stream) const;
protected:
// Reads the variable-length size from the current position in |stream|.
size_t ReadSize(ByteBufferStreamReader* stream) const;
// Writes the variable-length size encoding to |stream|.
void WriteSize(size_t size, ByteBufferStreamWriter* stream) const;
// Reads a fixed-type list whose values are of type T from the current
// position in |stream|, and returns it as the corresponding EncodableValue.
// |T| must correspond to one of the support list value types of
// EncodableValue.
template <typename T>
EncodableValue ReadVector(ByteBufferStreamReader* stream) const;
// Writes |vector| to |stream| as a fixed-type list. |T| must correspond to
// one of the support list value types of EncodableValue.
template <typename T>
void WriteVector(const std::vector<T> vector,
ByteBufferStreamWriter* stream) const;
};
} // namespace uiwidgets
#endif // UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_ENCODABLE_VALUE_SERIALIZER_H_

173
engine/src/shell/platform/common/cpp/client_wrapper/standard_message_codec_unittests.cc


// // Copyright 2013 The UIWidgets Authors. All rights reserved.
// // Use of this source code is governed by a BSD-style license that can be
// // found in the LICENSE file.
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_message_codec.h"
// #include <map>
// #include <vector>
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/testing/encodable_value_utils.h"
// #include "gtest/gtest.h"
// namespace uiwidgets {
// // Validates round-trip encoding and decoding of |value|, and checks that the
// // encoded value matches |expected_encoding|.
// static void CheckEncodeDecode(const EncodableValue& value,
// const std::vector<uint8_t>& expected_encoding) {
// const StandardMessageCodec& codec = StandardMessageCodec::GetInstance();
// auto encoded = codec.EncodeMessage(value);
// ASSERT_TRUE(encoded);
// EXPECT_EQ(*encoded, expected_encoding);
// auto decoded = codec.DecodeMessage(*encoded);
// EXPECT_TRUE(testing::EncodableValuesAreEqual(value, *decoded));
// }
// // Validates round-trip encoding and decoding of |value|, and checks that the
// // encoded value has the given prefix and length.
// //
// // This should be used only for Map, where asserting the order of the elements
// // in a test is undesirable.
// static void CheckEncodeDecodeWithEncodePrefix(
// const EncodableValue& value,
// const std::vector<uint8_t>& expected_encoding_prefix,
// size_t expected_encoding_length) {
// EXPECT_TRUE(value.IsMap());
// const StandardMessageCodec& codec = StandardMessageCodec::GetInstance();
// auto encoded = codec.EncodeMessage(value);
// ASSERT_TRUE(encoded);
// EXPECT_EQ(encoded->size(), expected_encoding_length);
// ASSERT_GT(encoded->size(), expected_encoding_prefix.size());
// EXPECT_TRUE(std::equal(
// encoded->begin(), encoded->begin() + expected_encoding_prefix.size(),
// expected_encoding_prefix.begin(), expected_encoding_prefix.end()));
// auto decoded = codec.DecodeMessage(*encoded);
// EXPECT_TRUE(testing::EncodableValuesAreEqual(value, *decoded));
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeNull) {
// std::vector<uint8_t> bytes = {0x00};
// CheckEncodeDecode(EncodableValue(), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeTrue) {
// std::vector<uint8_t> bytes = {0x01};
// CheckEncodeDecode(EncodableValue(true), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeFalse) {
// std::vector<uint8_t> bytes = {0x02};
// CheckEncodeDecode(EncodableValue(false), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeInt32) {
// std::vector<uint8_t> bytes = {0x03, 0x78, 0x56, 0x34, 0x12};
// CheckEncodeDecode(EncodableValue(0x12345678), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeInt64) {
// std::vector<uint8_t> bytes = {0x04, 0xef, 0xcd, 0xab, 0x90,
// 0x78, 0x56, 0x34, 0x12};
// CheckEncodeDecode(EncodableValue(INT64_C(0x1234567890abcdef)), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeDouble) {
// std::vector<uint8_t> bytes = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40};
// CheckEncodeDecode(EncodableValue(3.14159265358979311599796346854), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeString) {
// std::vector<uint8_t> bytes = {0x07, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
// 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
// CheckEncodeDecode(EncodableValue(u8"hello world"), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
// std::vector<uint8_t> bytes = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
// CheckEncodeDecode(EncodableValue(u8"h\u263Aw"), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeStringWithNonBMPCodePoint) {
// std::vector<uint8_t> bytes = {0x07, 0x06, 0x68, 0xf0, 0x9f, 0x98, 0x82, 0x77};
// CheckEncodeDecode(EncodableValue(u8"h\U0001F602w"), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeEmptyString) {
// std::vector<uint8_t> bytes = {0x07, 0x00};
// CheckEncodeDecode(EncodableValue(u8""), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeList) {
// std::vector<uint8_t> bytes = {
// 0x0c, 0x05, 0x00, 0x07, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x06,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x85, 0xeb, 0x51, 0xb8, 0x1e,
// 0x09, 0x40, 0x03, 0x2f, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x03, 0x2a,
// 0x00, 0x00, 0x00, 0x07, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64,
// };
// EncodableValue value(EncodableList{
// EncodableValue(),
// EncodableValue("hello"),
// EncodableValue(3.14),
// EncodableValue(47),
// EncodableValue(EncodableList{
// EncodableValue(42),
// EncodableValue("nested"),
// }),
// });
// CheckEncodeDecode(value, bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeEmptyList) {
// std::vector<uint8_t> bytes = {0x0c, 0x00};
// CheckEncodeDecode(EncodableValue(EncodableList{}), bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeMap) {
// std::vector<uint8_t> bytes_prefix = {0x0d, 0x04};
// EncodableValue value(EncodableMap{
// {EncodableValue("a"), EncodableValue(3.14)},
// {EncodableValue("b"), EncodableValue(47)},
// {EncodableValue(), EncodableValue()},
// {EncodableValue(3.14), EncodableValue(EncodableList{
// EncodableValue("nested"),
// })},
// });
// CheckEncodeDecodeWithEncodePrefix(value, bytes_prefix, 48);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeByteArray) {
// std::vector<uint8_t> bytes = {0x08, 0x04, 0xba, 0x5e, 0xba, 0x11};
// EncodableValue value(std::vector<uint8_t>{0xba, 0x5e, 0xba, 0x11});
// CheckEncodeDecode(value, bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeInt32Array) {
// std::vector<uint8_t> bytes = {0x09, 0x03, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12,
// 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};
// EncodableValue value(std::vector<int32_t>{0x12345678, -1, 0});
// CheckEncodeDecode(value, bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeInt64Array) {
// std::vector<uint8_t> bytes = {0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12,
// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
// EncodableValue value(std::vector<int64_t>{0x1234567890abcdef, -1});
// CheckEncodeDecode(value, bytes);
// }
// TEST(StandardMessageCodec, CanEncodeAndDecodeFloat64Array) {
// std::vector<uint8_t> bytes = {0x0b, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8f, 0x40};
// EncodableValue value(
// std::vector<double>{3.14159265358979311599796346854, 1000.0});
// CheckEncodeDecode(value, bytes);
// }
// } // namespace uiwidgets

105
engine/src/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc


// // Copyright 2013 The UIWidgets Authors. All rights reserved.
// // Use of this source code is governed by a BSD-style license that can be
// // found in the LICENSE file.
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/include/uiwidgets/standard_method_codec.h"
// #include "uiwidgets/shell/platform/common/cpp/client_wrapper/testing/encodable_value_utils.h"
// #include "gtest/gtest.h"
// namespace uiwidgets {
// namespace {
// // Returns true if the given method calls have the same method name, and their
// // arguments have equivalent values.
// bool MethodCallsAreEqual(const MethodCall<EncodableValue>& a,
// const MethodCall<EncodableValue>& b) {
// if (a.method_name() != b.method_name()) {
// return false;
// }
// // Treat nullptr and Null as equivalent.
// if ((!a.arguments() || a.arguments()->IsNull()) &&
// (!b.arguments() || b.arguments()->IsNull())) {
// return true;
// }
// return testing::EncodableValuesAreEqual(*a.arguments(), *b.arguments());
// }
// } // namespace
// TEST(StandardMethodCodec, HandlesMethodCallsWithNullArguments) {
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// MethodCall<EncodableValue> call("hello", nullptr);
// auto encoded = codec.EncodeMethodCall(call);
// ASSERT_NE(encoded.get(), nullptr);
// std::unique_ptr<MethodCall<EncodableValue>> decoded =
// codec.DecodeMethodCall(*encoded);
// ASSERT_NE(decoded.get(), nullptr);
// EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
// }
// TEST(StandardMethodCodec, HandlesMethodCallsWithArgument) {
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// MethodCall<EncodableValue> call(
// "hello", std::make_unique<EncodableValue>(EncodableList{
// EncodableValue(42),
// EncodableValue("world"),
// }));
// auto encoded = codec.EncodeMethodCall(call);
// ASSERT_NE(encoded.get(), nullptr);
// std::unique_ptr<MethodCall<EncodableValue>> decoded =
// codec.DecodeMethodCall(*encoded);
// ASSERT_NE(decoded.get(), nullptr);
// EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
// }
// TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithNullResult) {
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// auto encoded = codec.EncodeSuccessEnvelope();
// ASSERT_NE(encoded.get(), nullptr);
// std::vector<uint8_t> bytes = {0x00, 0x00};
// EXPECT_EQ(*encoded, bytes);
// // TODO: Add round-trip check once decoding replies is implemented.
// }
// TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithResult) {
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// EncodableValue result(42);
// auto encoded = codec.EncodeSuccessEnvelope(&result);
// ASSERT_NE(encoded.get(), nullptr);
// std::vector<uint8_t> bytes = {0x00, 0x03, 0x2a, 0x00, 0x00, 0x00};
// EXPECT_EQ(*encoded, bytes);
// // TODO: Add round-trip check once decoding replies is implemented.
// }
// TEST(StandardMethodCodec, HandlesErrorEnvelopesWithNulls) {
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// auto encoded = codec.EncodeErrorEnvelope("errorCode");
// ASSERT_NE(encoded.get(), nullptr);
// std::vector<uint8_t> bytes = {0x01, 0x07, 0x09, 0x65, 0x72, 0x72, 0x6f,
// 0x72, 0x43, 0x6f, 0x64, 0x65, 0x00, 0x00};
// EXPECT_EQ(*encoded, bytes);
// // TODO: Add round-trip check once decoding replies is implemented.
// }
// TEST(StandardMethodCodec, HandlesErrorEnvelopesWithDetails) {
// const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
// EncodableValue details(EncodableList{
// EncodableValue("a"),
// EncodableValue(42),
// });
// auto encoded =
// codec.EncodeErrorEnvelope("errorCode", "something failed", &details);
// ASSERT_NE(encoded.get(), nullptr);
// std::vector<uint8_t> bytes = {
// 0x01, 0x07, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f,
// 0x64, 0x65, 0x07, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68,
// 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64,
// 0x0c, 0x02, 0x07, 0x01, 0x61, 0x03, 0x2a, 0x00, 0x00, 0x00,
// };
// EXPECT_EQ(*encoded, bytes);
// // TODO: Add round-trip check once decoding replies is implemented.
// }
// } // namespace uiwidgets

58
engine/src/shell/platform/common/cpp/incoming_message_dispatcher.cc


// Copyright 2013 The UIWidgets Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shell/platform/common/cpp/incoming_message_dispatcher.h"
namespace uiwidgets {
IncomingMessageDispatcher::IncomingMessageDispatcher(
UIWidgetsDesktopMessengerRef messenger)
: messenger_(messenger) {}
IncomingMessageDispatcher::~IncomingMessageDispatcher() = default;
/// @note Procedure doesn't copy all closures.
void IncomingMessageDispatcher::HandleMessage(
const UIWidgetsDesktopMessage& message,
const std::function<void(void)>& input_block_cb,
const std::function<void(void)>& input_unblock_cb) {
std::string channel(message.channel);
// Find the handler for the channel; if there isn't one, report the failure.
if (callbacks_.find(channel) == callbacks_.end()) {
UIWidgetsDesktopMessengerSendResponse(messenger_, message.response_handle,
nullptr, 0);
return;
}
auto& callback_info = callbacks_[channel];
UIWidgetsDesktopMessageCallback message_callback = callback_info.first;
// Process the call, handling input blocking if requested.
bool block_input = input_blocking_channels_.count(channel) > 0;
if (block_input) {
input_block_cb();
}
message_callback(messenger_, &message, callback_info.second);
if (block_input) {
input_unblock_cb();
}
}
void IncomingMessageDispatcher::SetMessageCallback(
const std::string& channel,
UIWidgetsDesktopMessageCallback callback,
void* user_data) {
if (!callback) {
callbacks_.erase(channel);
return;
}
callbacks_[channel] = std::make_pair(callback, user_data);
}
void IncomingMessageDispatcher::EnableInputBlockingForChannel(
const std::string& channel) {
input_blocking_channels_.insert(channel);
}
} // namespace uiwidgets

78
engine/src/shell/platform/common/cpp/incoming_message_dispatcher.h


// Copyright 2013 The UIWidgets 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 UIWIDGETS_SHELL_PLATFORM_CPP_INCOMING_MESSAGE_DISPATCHER_H_
#define UIWIDGETS_SHELL_PLATFORM_CPP_INCOMING_MESSAGE_DISPATCHER_H_
#include <functional>
#include <map>
#include <set>
#include <string>
#include <utility>
#include "shell/platform/common/cpp/public/uiwidgets_messenger.h"
namespace uiwidgets {
// Manages per-channel registration of callbacks for handling messages from the
// UIWidgets engine, and dispatching incoming messages to those handlers.
class IncomingMessageDispatcher {
public:
// Creates a new IncomingMessageDispatcher. |messenger| must remain valid as
// long as this object exists.
explicit IncomingMessageDispatcher(UIWidgetsDesktopMessengerRef messenger);
virtual ~IncomingMessageDispatcher();
// Prevent copying.
IncomingMessageDispatcher(IncomingMessageDispatcher const&) = delete;
IncomingMessageDispatcher& operator=(IncomingMessageDispatcher const&) =
delete;
// Routes |message| to to the registered handler for its channel, if any.
//
// If input blocking has been enabled on that channel, wraps the call to the
// handler with calls to the given callbacks to block and then unblock input.
//
// If no handler is registered for the message's channel, sends a
// NotImplemented response to the engine.
void HandleMessage(
const UIWidgetsDesktopMessage& message,
const std::function<void(void)>& input_block_cb = [] {},
const std::function<void(void)>& input_unblock_cb = [] {});
// Registers a message callback for incoming messages from the UIWidgets
// side on the specified channel. |callback| will be called with the message
// and |user_data| any time a message arrives on that channel.
//
// Replaces any existing callback. Pass a null callback to unregister the
// existing callback.
void SetMessageCallback(const std::string& channel,
UIWidgetsDesktopMessageCallback callback,
void* user_data);
// Enables input blocking on the given channel name.
//
// If set, then the parent window should disable input callbacks
// while waiting for the handler for messages on that channel to run.
void EnableInputBlockingForChannel(const std::string& channel);
private:
// Handle for interacting with the C messaging API.
UIWidgetsDesktopMessengerRef messenger_;
// A map from channel names to the UIWidgetsDesktopMessageCallback that should
// be called for incoming messages on that channel, along with the void* user
// data to pass to it.
std::map<std::string, std::pair<UIWidgetsDesktopMessageCallback, void*>>
callbacks_;
// Channel names for which input blocking should be enabled during the call to
// that channel's handler.
std::set<std::string> input_blocking_channels_;
};
} // namespace uiwidgets
#endif // UIWIDGETS_SHELL_PLATFORM_CPP_INCOMING_MESSAGE_DISPATCHER_H_

24
engine/src/shell/platform/common/cpp/public/uiwidgets_export.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_PUBLIC_UIWIDGETS_EXPORT_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_PUBLIC_UIWIDGETS_EXPORT_H_
#ifdef UIWIDGETS_DESKTOP_LIBRARY
#ifdef _WIN32
#define UIWIDGETS_EXPORT __declspec(dllexport)
#else
#define UIWIDGETS_EXPORT __attribute__((visibility("default")))
#endif
#else
#ifdef _WIN32
#define UIWIDGETS_EXPORT __declspec(dllimport)
#else
#define UIWIDGETS_EXPORT
#endif
#endif
#endif

61
engine/src/shell/platform/common/cpp/public/uiwidgets_messenger.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_PUBLIC_UIWIDGETS_MESSENGER_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_PUBLIC_UIWIDGETS_MESSENGER_H_
#include <stddef.h>
#include <stdint.h>
#include "uiwidgets_export.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct UIWidgetsDesktopMessenger* UIWidgetsDesktopMessengerRef;
typedef struct _UIWidgetsPlatformMessageResponseHandle
UIWidgetsDesktopMessageResponseHandle;
typedef void (*UIWidgetsDesktopBinaryReply)(const uint8_t* data, size_t data_size,
void* user_data);
typedef struct {
size_t struct_size;
const char* channel;
const uint8_t* message;
size_t message_size;
const UIWidgetsDesktopMessageResponseHandle* response_handle;
} UIWidgetsDesktopMessage;
typedef void (*UIWidgetsDesktopMessageCallback)(
UIWidgetsDesktopMessengerRef /* messenger */,
const UIWidgetsDesktopMessage* /* message*/, void* /* user data */);
UIWIDGETS_EXPORT bool UIWidgetsDesktopMessengerSend(
UIWidgetsDesktopMessengerRef messenger, const char* channel,
const uint8_t* message, const size_t message_size);
UIWIDGETS_EXPORT bool UIWidgetsDesktopMessengerSendWithReply(
UIWidgetsDesktopMessengerRef messenger, const char* channel,
const uint8_t* message, const size_t message_size,
const UIWidgetsDesktopBinaryReply reply, void* user_data);
UIWIDGETS_EXPORT void UIWidgetsDesktopMessengerSendResponse(
UIWidgetsDesktopMessengerRef messenger,
const UIWidgetsDesktopMessageResponseHandle* handle, const uint8_t* data,
size_t data_length);
UIWIDGETS_EXPORT void UIWidgetsDesktopMessengerSetCallback(
UIWidgetsDesktopMessengerRef messenger, const char* channel,
UIWidgetsDesktopMessageCallback callback, void* user_data);
#if defined(__cplusplus)
}
#endif
#endif

28
engine/src/shell/platform/common/cpp/public/uiwidgets_plugin_registrar.h


#ifndef UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_PUBLIC_UIWIDGETS_PLUGIN_REGISTRAR_H_
#define UIWIDGETS_SHELL_PLATFORM_COMMON_CPP_PUBLIC_UIWIDGETS_PLUGIN_REGISTRAR_H_
#include <stddef.h>
#include <stdint.h>
#include "uiwidgets_export.h"
#include "uiwidgets_messenger.h"
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct UIWidgetsDesktopPluginRegistrar* UIWidgetsDesktopPluginRegistrarRef;
UIWIDGETS_EXPORT UIWidgetsDesktopMessengerRef
UIWidgetsDesktopRegistrarGetMessenger(UIWidgetsDesktopPluginRegistrarRef registrar);
UIWIDGETS_EXPORT void UIWidgetsDesktopRegistrarEnableInputBlocking(
UIWidgetsDesktopPluginRegistrarRef registrar, const char* channel);
#if defined(__cplusplus)
}
#endif
#endif

132
engine/src/shell/platform/unity/windows/public/uiwidgets_windows.h


// Copyright 2013 The UIWidgets 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 UIWIDGETS_SHELL_PLATFORM_WINDOWS_PUBLIC_UIWIDGETS_H_
#define UIWIDGETS_SHELL_PLATFORM_WINDOWS_PUBLIC_UIWIDGETS_H_
#include <stddef.h>
#include <stdint.h>
#include "shell/platform/common/cpp/public/uiwidgets_export.h"
#include "shell/platform/common/cpp/public/uiwidgets_messenger.h"
#include "shell/platform/common/cpp/public/uiwidgets_plugin_registrar.h"
#include "Windows.h"
#if defined(__cplusplus)
extern "C" {
#endif
// Opaque reference to a UIWidgets window controller.
typedef struct UIWidgetsDesktopViewControllerState*
UIWidgetsDesktopViewControllerRef;
// Opaque reference to a UIWidgets window.
typedef struct UIWidgetsDesktopView* UIWidgetsDesktopViewRef;
// Opaque reference to a UIWidgets engine instance.
typedef struct UIWidgetsDesktopEngineState* UIWidgetsDesktopEngineRef;
// Properties for configuring a UIWidgets engine instance.
typedef struct {
// The path to the uiwidgets_assets folder for the application to be run.
// This can either be an absolute path or a path relative to the directory
// containing the executable.
const wchar_t* assets_path;
// The path to the icudtl.dat file for the version of UIWidgets you are using.
// This can either be an absolute path or a path relative to the directory
// containing the executable.
const wchar_t* icu_data_path;
// The switches to pass to the UIWidgets engine.
//
// See: https://github.com/uiwidgets/engine/blob/master/shell/common/switches.h
// for details. Not all arguments will apply to desktop.
const char** switches;
// The number of elements in |switches|.
size_t switches_count;
} UIWidgetsDesktopEngineProperties;
// Creates a View with the given dimensions running a UIWidgets Application.
//
// This will set up and run an associated UIWidgets engine using the settings in
// |engine_properties|.
//
// Returns a null pointer in the event of an error.
UIWIDGETS_EXPORT UIWidgetsDesktopViewControllerRef
UIWidgetsDesktopCreateViewController(
int width,
int height,
const UIWidgetsDesktopEngineProperties& engine_properties);
// DEPRECATED. Will be removed soon; switch to the version above.
UIWIDGETS_EXPORT UIWidgetsDesktopViewControllerRef
UIWidgetsDesktopCreateViewControllerLegacy(int initial_width,
int initial_height,
const char* assets_path,
const char* icu_data_path,
const char** arguments,
size_t argument_count);
// Shuts down the engine instance associated with |controller|, and cleans up
// associated state.
//
// |controller| is no longer valid after this call.
UIWIDGETS_EXPORT void UIWidgetsDesktopDestroyViewController(
UIWidgetsDesktopViewControllerRef controller);
// Returns the plugin registrar handle for the plugin with the given name.
//
// The name must be unique across the application.
UIWIDGETS_EXPORT UIWidgetsDesktopPluginRegistrarRef
UIWidgetsDesktopGetPluginRegistrar(UIWidgetsDesktopViewControllerRef controller,
const char* plugin_name);
// Returns the view managed by the given controller.
UIWIDGETS_EXPORT UIWidgetsDesktopViewRef
UIWidgetsDesktopGetView(UIWidgetsDesktopViewControllerRef controller);
// Processes any pending events in the UIWidgets engine, and returns the
// number of nanoseconds until the next scheduled event (or max, if none).
//
// This should be called on every run of the application-level runloop, and
// a wait for native events in the runloop should never be longer than the
// last return value from this function.
UIWIDGETS_EXPORT uint64_t
UIWidgetsDesktopProcessMessages(UIWidgetsDesktopViewControllerRef controller);
// Return backing HWND for manipulation in host application.
UIWIDGETS_EXPORT HWND UIWidgetsDesktopViewGetHWND(UIWidgetsDesktopViewRef view);
// Gets the DPI for a given |hwnd|, depending on the supported APIs per
// windows version and DPI awareness mode. If nullptr is passed, returns the DPI
// of the primary monitor.
UIWIDGETS_EXPORT UINT UIWidgetsDesktopGetDpiForHWND(HWND hwnd);
// Gets the DPI for a given |monitor|. If the API is not available, a default
// DPI of 96 is returned.
UIWIDGETS_EXPORT UINT UIWidgetsDesktopGetDpiForMonitor(HMONITOR monitor);
// Runs an instance of a headless UIWidgets engine.
//
// Returns a null pointer in the event of an error.
UIWIDGETS_EXPORT UIWidgetsDesktopEngineRef UIWidgetsDesktopRunEngine(
const UIWidgetsDesktopEngineProperties& engine_properties);
// Shuts down the given engine instance. Returns true if the shutdown was
// successful. |engine_ref| is no longer valid after this call.
UIWIDGETS_EXPORT bool UIWidgetsDesktopShutDownEngine(
UIWidgetsDesktopEngineRef engine_ref);
// Returns the view associated with this registrar's engine instance
// This is a Windows-specific extension to uiwidgets_plugin_registrar.h.
UIWIDGETS_EXPORT UIWidgetsDesktopViewRef
UIWidgetsDesktopRegistrarGetView(UIWidgetsDesktopPluginRegistrarRef registrar);
#if defined(__cplusplus)
} // extern "C"
#endif
#endif // UIWIDGETS_SHELL_PLATFORM_WINDOWS_PUBLIC_UIWIDGETS_WINDOWS_H_
正在加载...
取消
保存