Chinmay Garde b111a13d25 Allow embedders to post Dart objects on send ports from the native side. (flutter/engine#14477)
This is a non-breaking addition to the stable Flutter Embedder API and exposes a
subset of the functionality provided by Dart_PostCObject API in a stable and
tested manner to custom embedder implementations.

Send port acquisition can currently be done as described in the unit-test but
there may be opportunities to extend this API in the future to access ports more
easily or create ports from the native side.

The following capabilities of the the Dart_PostCObject API are explicitly NOT
exposed:
* Object arrays: This allows callers to create complex object graphs but only
  using the primitives specified in the native API. I could find no current use
  case for this and would have made the implementation a lot more complex. This
  is something we can add in the future if necessary however.
* Capabilities and ports: Again no use cases and I honestly I didn’t understand
  how to use capabilities. If needed, these can be added at a later point by
  appending to the union.

Fixes https://github.com/flutter/flutter/issues/46624
Fixes b/145982720
2019-12-13 17:28:21 -08:00

103 lines
2.8 KiB
C++

// 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 "testing.h"
#include "flutter/fml/file.h"
namespace flutter {
namespace testing {
std::string GetCurrentTestName() {
return ::testing::UnitTest::GetInstance()->current_test_info()->name();
}
fml::UniqueFD OpenFixturesDirectory() {
auto fixtures_directory =
OpenDirectory(GetFixturesPath(), // path
false, // create
fml::FilePermission::kRead // permission
);
if (!fixtures_directory.is_valid()) {
FML_LOG(ERROR) << "Could not open fixtures directory.";
return {};
}
return fixtures_directory;
}
fml::UniqueFD OpenFixture(std::string fixture_name) {
if (fixture_name.size() == 0) {
FML_LOG(ERROR) << "Invalid fixture name.";
return {};
}
auto fixtures_directory = OpenFixturesDirectory();
auto fixture_fd = fml::OpenFile(fixtures_directory, // base directory
fixture_name.c_str(), // path
false, // create
fml::FilePermission::kRead // permission
);
if (!fixture_fd.is_valid()) {
FML_LOG(ERROR) << "Could not open fixture for path: " << GetFixturesPath()
<< "/" << fixture_name << ".";
return {};
}
return fixture_fd;
}
std::unique_ptr<fml::Mapping> OpenFixtureAsMapping(std::string fixture_name) {
return fml::FileMapping::CreateReadOnly(OpenFixture(fixture_name));
}
bool MemsetPatternSetOrCheck(uint8_t* buffer, size_t size, MemsetPatternOp op) {
if (buffer == nullptr) {
return false;
}
auto pattern = reinterpret_cast<const uint8_t*>("dErP");
constexpr auto pattern_length = 4;
uint8_t* start = buffer;
uint8_t* p = buffer;
while ((start + size) - p >= pattern_length) {
switch (op) {
case MemsetPatternOp::kMemsetPatternOpSetBuffer:
memmove(p, pattern, pattern_length);
break;
case MemsetPatternOp::kMemsetPatternOpCheckBuffer:
if (memcmp(pattern, p, pattern_length) != 0) {
return false;
}
break;
};
p += pattern_length;
}
if ((start + size) - p != 0) {
switch (op) {
case MemsetPatternOp::kMemsetPatternOpSetBuffer:
memmove(p, pattern, (start + size) - p);
break;
case MemsetPatternOp::kMemsetPatternOpCheckBuffer:
if (memcmp(pattern, p, (start + size) - p) != 0) {
return false;
}
break;
}
}
return true;
}
bool MemsetPatternSetOrCheck(std::vector<uint8_t>& buffer, MemsetPatternOp op) {
return MemsetPatternSetOrCheck(buffer.data(), buffer.size(), op);
}
} // namespace testing
} // namespace flutter