Skip to content

Commit

Permalink
Initial import of GLFW Linux shell from FDE (#8159)
Browse files Browse the repository at this point in the history
Changes include:
- File structure
- Header guards
- Include paths
- Namespaces
- Integration with the engine's GN build
- Conversion from jsoncpp to rapidjson
- Style and clang-format adjustment to match engine repository
  • Loading branch information
stuartmorgan committed Mar 20, 2019
1 parent 5120045 commit d452dd5
Show file tree
Hide file tree
Showing 48 changed files with 3,878 additions and 2 deletions.
35 changes: 35 additions & 0 deletions ci/licenses_golden/licenses_flutter
Expand Up @@ -544,6 +544,31 @@ FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.h
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/engine_method_result.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/engine_method_result.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_message_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_method_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/json_type.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/message_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_call.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_result.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/json_message_codec.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/json_method_codec.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/incoming_message_dispatcher.cc
FILE: ../../../flutter/shell/platform/common/cpp/incoming_message_dispatcher.h
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_export.h
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_messenger.h
FILE: ../../../flutter/shell/platform/common/cpp/public/flutter_plugin_registrar.h
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.cc
FILE: ../../../flutter/shell/platform/common/cpp/text_input_model.h
FILE: ../../../flutter/shell/platform/darwin/common/buffer_conversions.h
FILE: ../../../flutter/shell/platform/darwin/common/buffer_conversions.mm
FILE: ../../../flutter/shell/platform/darwin/common/command_line.h
Expand Down Expand Up @@ -660,6 +685,16 @@ FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.cc
FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.h
FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.cc
FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.h
FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller.cc
FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller_unittests.cc
FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h
FILE: ../../../flutter/shell/platform/glfw/flutter_glfw.cc
FILE: ../../../flutter/shell/platform/glfw/key_event_handler.cc
FILE: ../../../flutter/shell/platform/glfw/key_event_handler.h
FILE: ../../../flutter/shell/platform/glfw/keyboard_hook_handler.h
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
FILE: ../../../flutter/sky/packages/flutter_services/lib/empty.dart
FILE: ../../../flutter/sky/tools/roll/patches/chromium/android_build.patch
FILE: ../../../flutter/synchronization/pipeline.cc
Expand Down
63 changes: 63 additions & 0 deletions shell/platform/common/cpp/BUILD.gn
@@ -0,0 +1,63 @@
# 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.

config("desktop_library_implementation") {
defines = [ "FLUTTER_DESKTOP_LIBRARY" ]
}

_public_headers = [
"public/flutter_export.h",
"public/flutter_messenger.h",
"public/flutter_plugin_registrar.h",
]

# Any files that are built by clients (client_wrapper code, library headers for
# implementations using this shared code, etc.) include the public headers
# assuming they are in the include path. This configuration should be added to
# any such code that is also built by GN to make the includes work.
config("relative_flutter_library_headers") {
include_dirs = [ "public" ]
}

# The headers are a separate source set since the client wrapper is allowed
# to depend on the public headers, but none of the rest of the code.
source_set("common_cpp_library_headers") {
public = _public_headers

configs += [ ":desktop_library_implementation" ]
}

source_set("common_cpp") {
public = [
"incoming_message_dispatcher.h",
"text_input_model.h",
]

# TODO: Refactor flutter_glfw.cc to move the implementations corresponding
# to the _public_headers above into this target.
sources = [
"incoming_message_dispatcher.cc",
"text_input_model.cc",
]

configs += [ ":desktop_library_implementation" ]

deps = [
":common_cpp_library_headers",
"$flutter_root/shell/platform/common/cpp/client_wrapper:client_wrapper",
"$flutter_root/shell/platform/embedder:embedder",
]

# TODO: Remove once text input model refactor lands, at which point this code
# won't have a JSON dependency.
defines = [ "USE_RAPID_JSON" ]
deps += [ "//third_party/rapidjson" ]
}

copy("publish_headers") {
sources = _public_headers
outputs = [
"$root_out_dir/{{source_file_part}}",
]
}
88 changes: 88 additions & 0 deletions shell/platform/common/cpp/client_wrapper/BUILD.gn
@@ -0,0 +1,88 @@
# 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.

import("publish.gni")

_wrapper_includes = [
"include/flutter/basic_message_channel.h",
"include/flutter/binary_messenger.h",
"include/flutter/engine_method_result.h",
"include/flutter/json_message_codec.h",
"include/flutter/json_method_codec.h",
"include/flutter/json_type.h",
"include/flutter/message_codec.h",
"include/flutter/method_call.h",
"include/flutter/method_channel.h",
"include/flutter/method_codec.h",
"include/flutter/method_result.h",
"include/flutter/plugin_registrar.h",
]

# TODO: Once the wrapper API is more stable, consolidate to as few files as is
# reasonable (without forcing different kinds of clients to take unnecessary
# code) to simplify use.
_wrapper_sources = [
"engine_method_result.cc",
"json_message_codec.cc",
"json_method_codec.cc",
"plugin_registrar.cc",
]

# Client library build for internal use by the shell implementation.
source_set("client_wrapper") {
sources = _wrapper_sources
public = _wrapper_includes

deps = [
"$flutter_root/shell/platform/common/cpp:common_cpp_library_headers",
"//third_party/rapidjson",
]

defines = [ "USE_RAPID_JSON" ]

configs += [
"$flutter_root/shell/platform/common/cpp:desktop_library_implementation",
]

public_configs = [
"$flutter_root/shell/platform/common/cpp:relative_flutter_library_headers",
]
}

# Copies the client wrapper code to the output directory.
publish_client_wrapper("publish_wrapper") {
public = _wrapper_includes
sources = _wrapper_sources + [ "README" ]
}

source_set("client_wrapper_library_stubs") {
sources = [
"testing/stub_flutter_api.cc",
"testing/stub_flutter_api.h",
]

public_deps = [
"$flutter_root/shell/platform/common/cpp:common_cpp_library_headers",
]
}

executable("client_wrapper_unittests") {
testonly = true

# TODO: Add more unit tests.
sources = [
"method_call_unittests.cc",
"plugin_registrar_unittests.cc",
]

deps = [
":client_wrapper",
":client_wrapper_library_stubs",
"$flutter_root/testing",

# TODO: Consider refactoring flutter_root/testing so that there's a testing
# target that doesn't require a Dart runtime to be linked in.
"//third_party/dart/runtime:libdart_jit",
]
}
9 changes: 9 additions & 0 deletions shell/platform/common/cpp/client_wrapper/README
@@ -0,0 +1,9 @@
This code is intended to be built into plugins and applications to provide
higher-level, C++ abstractions for interacting with the Flutter library.

Over time, the goal is to move more of this code into the library in a way that
provides a usable ABI (e.g., does not use standard libary in the interfaces).

Note that this wrapper is still in early stages. Expect significant churn in
both the APIs and the structure of the wrapper (e.g., the exact set of files
that need to be built).
45 changes: 45 additions & 0 deletions shell/platform/common/cpp/client_wrapper/engine_method_result.cc
@@ -0,0 +1,45 @@
// 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 "include/flutter/engine_method_result.h"

#include <assert.h>
#include <iostream>

namespace flutter {
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 flutter
@@ -0,0 +1,98 @@
// 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.

#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_

#include <iostream>
#include <string>

#include "binary_messenger.h"
#include "message_codec.h"

namespace flutter {

// A message reply callback.
//
// Used for submitting a reply back to a Flutter message sender.
template <typename T>
using MessageReply = std::function<void(const T& reply)>;

// A handler for receiving a message from the Flutter 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, MessageReply<T> reply)>;

// A channel for communicating with the Flutter 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|.
//
// TODO: Make codec optional once the standard codec is supported (Issue #67).
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 Flutter 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());
}

// TODO: Add support for a version of Send expecting a reply once
// https://github.com/flutter/flutter/issues/18852 is fixed.

// Registers a handler that should be called any time a message is
// received on this channel.
void SetMessageHandler(MessageHandler<T> handler) const {
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 flutter

#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_

0 comments on commit d452dd5

Please sign in to comment.