Skip to content

Commit f5808b9

Browse files
authored
Merge pull request #3 from DisDis/clang_fixes
fix RPI flutter
2 parents 359d4b7 + 2b00f63 commit f5808b9

37 files changed

+3116
-676
lines changed

CMakeLists.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ include_directories(
1414
${CMAKE_SYSROOT}/opt/vc/include
1515
${CMAKE_SYSROOT}/opt/vc/include/interface/vcos/pthreads
1616
${CMAKE_SYSROOT}/opt/vc/include/interface/vmcs_host/linux
17+
${CMAKE_CURRENT_SOURCE_DIR}/../../../engine-prefix/src/engine/src/third_party/rapidjson/include
18+
${CMAKE_CURRENT_SOURCE_DIR}/flutter/cpp_client_wrapper/include/flutter
1719
${ENGINE_INCLUDE_DIR})
1820

1921
link_directories(
@@ -25,20 +27,25 @@ add_definitions(
2527
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
2628
-DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST
2729
-fPIC -DPIC
30+
-DUSE_RAPID_JSON
31+
-DGLFW_INCLUDE_ES2
2832
-DUSE_VCHIQ_ARM -DHAVE_LIBOPENMAX=2
2933
-DUSE_EXTERNAL_OMX -DOMX -DOMX_SKIP64BIT)
3034

3135
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -U_FORTIFY_SOURCE -Wall -g -ftree-vectorize -pipe")
3236

3337

3438
set(cxx_sources
35-
flutter/flutter_application.cc
3639
flutter/main.cc
37-
flutter/pi_display.cc
3840
flutter/utils.cc
41+
flutter/cpp_client_wrapper/engine_method_result.cc
42+
flutter/cpp_client_wrapper/flutter_window_controller.cc
43+
flutter/cpp_client_wrapper/json_message_codec.cc
44+
flutter/cpp_client_wrapper/plugin_registrar.cc
45+
flutter/cpp_client_wrapper/standard_codec.cc
3946
)
4047

4148
add_executable(flutter ${cxx_sources})
42-
target_link_libraries(flutter ts brcmGLESv2 brcmEGL bcm_host flutter_engine pthread dl)
49+
target_link_libraries(flutter ts brcmGLESv2 brcmEGL bcm_host flutter_engine pthread dl flutter_linux)
4350

4451
install(TARGETS flutter RUNTIME DESTINATION bin)

flutter/cpp_client_wrapper/README

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
This code is intended to be built into plugins and applications to provide
2+
higher-level, C++ abstractions for interacting with the Flutter library.
3+
4+
Over time, the goal is to move more of this code into the library in a way that
5+
provides a usable ABI (e.g., does not use standard libary in the interfaces).
6+
7+
Note that this wrapper is still in early stages. Expect significant churn in
8+
both the APIs and the structure of the wrapper (e.g., the exact set of files
9+
that need to be built).
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
6+
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
7+
8+
// Utility classes for interacting with a buffer of bytes as a stream, for use
9+
// in message channel codecs.
10+
11+
#include <cstdint>
12+
#include <cstring>
13+
#include <iostream>
14+
#include <vector>
15+
16+
namespace flutter {
17+
18+
// Wraps an array of bytes with utility methods for treating it as a readable
19+
// stream.
20+
class ByteBufferStreamReader {
21+
public:
22+
// Createa a reader reading from |bytes|, which must have a length of |size|.
23+
// |bytes| must remain valid for the lifetime of this object.
24+
explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size)
25+
: bytes_(bytes), size_(size) {}
26+
27+
// Reads and returns the next byte from the stream.
28+
uint8_t ReadByte() {
29+
if (location_ >= size_) {
30+
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
31+
return 0;
32+
}
33+
return bytes_[location_++];
34+
}
35+
36+
// Reads the next |length| bytes from the stream into |buffer|. The caller
37+
// is responsible for ensuring that |buffer| is large enough.
38+
void ReadBytes(uint8_t* buffer, size_t length) {
39+
if (location_ + length > size_) {
40+
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
41+
return;
42+
}
43+
std::memcpy(buffer, &bytes_[location_], length);
44+
location_ += length;
45+
}
46+
47+
// Advances the read cursor to the next multiple of |alignment| relative to
48+
// the start of the wrapped byte buffer, unless it is already aligned.
49+
void ReadAlignment(uint8_t alignment) {
50+
uint8_t mod = location_ % alignment;
51+
if (mod) {
52+
location_ += alignment - mod;
53+
}
54+
}
55+
56+
private:
57+
// The buffer to read from.
58+
const uint8_t* bytes_;
59+
// The total size of the buffer.
60+
size_t size_;
61+
// The current read location.
62+
size_t location_ = 0;
63+
};
64+
65+
// Wraps an array of bytes with utility methods for treating it as a writable
66+
// stream.
67+
class ByteBufferStreamWriter {
68+
public:
69+
// Createa a writter that writes into |buffer|.
70+
// |buffer| must remain valid for the lifetime of this object.
71+
explicit ByteBufferStreamWriter(std::vector<uint8_t>* buffer)
72+
: bytes_(buffer) {
73+
assert(buffer);
74+
}
75+
76+
// Writes |byte| to the wrapped buffer.
77+
void WriteByte(uint8_t byte) { bytes_->push_back(byte); }
78+
79+
// Writes the next |length| bytes from |bytes| into the wrapped buffer.
80+
// The caller is responsible for ensuring that |buffer| is large enough.
81+
void WriteBytes(const uint8_t* bytes, size_t length) {
82+
assert(length > 0);
83+
bytes_->insert(bytes_->end(), bytes, bytes + length);
84+
}
85+
86+
// Writes 0s until the next multiple of |alignment| relative to
87+
// the start of the wrapped byte buffer, unless the write positition is
88+
// already aligned.
89+
void WriteAlignment(uint8_t alignment) {
90+
uint8_t mod = bytes_->size() % alignment;
91+
if (mod) {
92+
for (int i = 0; i < alignment - mod; ++i) {
93+
WriteByte(0);
94+
}
95+
}
96+
}
97+
98+
private:
99+
// The buffer to write to.
100+
std::vector<uint8_t>* bytes_;
101+
};
102+
103+
} // namespace flutter
104+
105+
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "include/flutter/engine_method_result.h"
6+
7+
#include <assert.h>
8+
#include <iostream>
9+
10+
namespace flutter {
11+
namespace internal {
12+
13+
ReplyManager::ReplyManager(BinaryReply reply_handler)
14+
: reply_handler_(std::move(reply_handler)) {
15+
assert(reply_handler_);
16+
}
17+
18+
ReplyManager::~ReplyManager() {
19+
if (reply_handler_) {
20+
// Warn, rather than send a not-implemented response, since the engine may
21+
// no longer be valid at this point.
22+
std::cerr
23+
<< "Warning: Failed to respond to a message. This is a memory leak."
24+
<< std::endl;
25+
}
26+
}
27+
28+
void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
29+
if (!reply_handler_) {
30+
std::cerr
31+
<< "Error: Only one of Success, Error, or NotImplemented can be "
32+
"called,"
33+
<< " and it can be called exactly once. Ignoring duplicate result."
34+
<< std::endl;
35+
return;
36+
}
37+
38+
const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
39+
size_t message_size = data ? data->size() : 0;
40+
reply_handler_(message, message_size);
41+
reply_handler_ = nullptr;
42+
}
43+
44+
} // namespace internal
45+
} // namespace flutter
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "include/flutter/flutter_window_controller.h"
6+
7+
#include <algorithm>
8+
#include <iostream>
9+
10+
namespace flutter {
11+
12+
FlutterWindowController::FlutterWindowController(
13+
const std::string& icu_data_path)
14+
: icu_data_path_(icu_data_path) {
15+
init_succeeded_ = FlutterDesktopInit();
16+
}
17+
18+
FlutterWindowController::~FlutterWindowController() {
19+
if (controller_) {
20+
FlutterDesktopDestroyWindow(controller_);
21+
}
22+
if (init_succeeded_) {
23+
FlutterDesktopTerminate();
24+
}
25+
}
26+
27+
bool FlutterWindowController::CreateWindow(
28+
int width,
29+
int height,
30+
const std::string& title,
31+
const std::string& assets_path,
32+
const std::vector<std::string>& arguments) {
33+
if (!init_succeeded_) {
34+
std::cerr << "Could not create window; FlutterDesktopInit failed."
35+
<< std::endl;
36+
return false;
37+
}
38+
39+
if (controller_) {
40+
std::cerr << "Only one Flutter window can exist at a time." << std::endl;
41+
return false;
42+
}
43+
44+
std::vector<const char*> engine_arguments;
45+
std::transform(
46+
arguments.begin(), arguments.end(), std::back_inserter(engine_arguments),
47+
[](const std::string& arg) -> const char* { return arg.c_str(); });
48+
size_t arg_count = engine_arguments.size();
49+
50+
controller_ = FlutterDesktopCreateWindow(
51+
width, height, title.c_str(), assets_path.c_str(), icu_data_path_.c_str(),
52+
arg_count > 0 ? &engine_arguments[0] : nullptr, arg_count);
53+
if (!controller_) {
54+
std::cerr << "Failed to create window." << std::endl;
55+
return false;
56+
}
57+
window_ =
58+
std::make_unique<FlutterWindow>(FlutterDesktopGetWindow(controller_));
59+
return true;
60+
}
61+
62+
FlutterDesktopPluginRegistrarRef FlutterWindowController::GetRegistrarForPlugin(
63+
const std::string& plugin_name) {
64+
if (!controller_) {
65+
std::cerr << "Cannot get plugin registrar without a window; call "
66+
"CreateWindow first."
67+
<< std::endl;
68+
return nullptr;
69+
}
70+
return FlutterDesktopGetPluginRegistrar(controller_, plugin_name.c_str());
71+
}
72+
73+
void FlutterWindowController::RunEventLoop() {
74+
if (controller_) {
75+
FlutterDesktopRunWindowLoop(controller_);
76+
}
77+
window_ = nullptr;
78+
controller_ = nullptr;
79+
}
80+
81+
} // namespace flutter
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_
6+
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_
7+
8+
#include <iostream>
9+
#include <string>
10+
11+
#include "binary_messenger.h"
12+
#include "message_codec.h"
13+
14+
namespace flutter {
15+
16+
// A message reply callback.
17+
//
18+
// Used for submitting a reply back to a Flutter message sender.
19+
template <typename T>
20+
using MessageReply = std::function<void(const T& reply)>;
21+
22+
// A handler for receiving a message from the Flutter engine.
23+
//
24+
// Implementations must asynchronously call reply exactly once with the reply
25+
// to the message.
26+
template <typename T>
27+
using MessageHandler =
28+
std::function<void(const T& message, MessageReply<T> reply)>;
29+
30+
// A channel for communicating with the Flutter engine by sending asynchronous
31+
// messages.
32+
template <typename T>
33+
class BasicMessageChannel {
34+
public:
35+
// Creates an instance that sends and receives method calls on the channel
36+
// named |name|, encoded with |codec| and dispatched via |messenger|.
37+
BasicMessageChannel(BinaryMessenger* messenger,
38+
const std::string& name,
39+
const MessageCodec<T>* codec)
40+
: messenger_(messenger), name_(name), codec_(codec) {}
41+
42+
~BasicMessageChannel() = default;
43+
44+
// Prevent copying.
45+
BasicMessageChannel(BasicMessageChannel const&) = delete;
46+
BasicMessageChannel& operator=(BasicMessageChannel const&) = delete;
47+
48+
// Sends a message to the Flutter engine on this channel.
49+
void Send(const T& message) {
50+
std::unique_ptr<std::vector<uint8_t>> raw_message =
51+
codec_->EncodeMessage(message);
52+
messenger_->Send(name_, raw_message->data(), raw_message->size());
53+
}
54+
55+
// TODO: Add support for a version of Send expecting a reply once
56+
// https://github.com/flutter/flutter/issues/18852 is fixed.
57+
58+
// Registers a handler that should be called any time a message is
59+
// received on this channel.
60+
void SetMessageHandler(MessageHandler<T> handler) const {
61+
const auto* codec = codec_;
62+
std::string channel_name = name_;
63+
BinaryMessageHandler binary_handler = [handler, codec, channel_name](
64+
const uint8_t* binary_message,
65+
const size_t binary_message_size,
66+
BinaryReply binary_reply) {
67+
// Use this channel's codec to decode the message and build a reply
68+
// handler.
69+
std::unique_ptr<T> message =
70+
codec->DecodeMessage(binary_message, binary_message_size);
71+
if (!message) {
72+
std::cerr << "Unable to decode message on channel " << channel_name
73+
<< std::endl;
74+
binary_reply(nullptr, 0);
75+
return;
76+
}
77+
78+
MessageReply<T> unencoded_reply = [binary_reply,
79+
codec](const T& unencoded_response) {
80+
auto binary_response = codec->EncodeMessage(unencoded_response);
81+
binary_reply(binary_response->data(), binary_response->size());
82+
};
83+
handler(*message, std::move(unencoded_reply));
84+
};
85+
messenger_->SetMessageHandler(name_, std::move(binary_handler));
86+
}
87+
88+
private:
89+
BinaryMessenger* messenger_;
90+
std::string name_;
91+
const MessageCodec<T>* codec_;
92+
};
93+
94+
} // namespace flutter
95+
96+
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_

0 commit comments

Comments
 (0)