• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "flutter/lib/ui/window/platform_message_response_dart.h"
6 
7 #include <utility>
8 
9 #include "flutter/common/task_runners.h"
10 #include "flutter/fml/make_copyable.h"
11 #include "flutter/lib/ui/window/window.h"
12 
13 namespace flutter {
14 
15 namespace {
16 
17 // Avoid copying the contents of messages beyond a certain size.
18 const int kMessageCopyThreshold = 1000;
19 
MessageDataFinalizer(void * isolate_callback_data,Dart_WeakPersistentHandle handle,void * peer)20 void MessageDataFinalizer(void* isolate_callback_data,
21                           Dart_WeakPersistentHandle handle,
22                           void* peer) {
23   std::vector<uint8_t>* data = reinterpret_cast<std::vector<uint8_t>*>(peer);
24   delete data;
25 }
26 
WrapByteData(std::vector<uint8_t> data)27 Dart_Handle WrapByteData(std::vector<uint8_t> data) {
28   if (data.size() < kMessageCopyThreshold) {
29     return ToByteData(data);
30   } else {
31     std::vector<uint8_t>* heap_data = new std::vector<uint8_t>(std::move(data));
32     return Dart_NewExternalTypedDataWithFinalizer(
33         Dart_TypedData_kByteData, heap_data->data(), heap_data->size(),
34         heap_data, heap_data->size(), MessageDataFinalizer);
35   }
36 }
37 
WrapByteData(std::unique_ptr<fml::Mapping> mapping)38 Dart_Handle WrapByteData(std::unique_ptr<fml::Mapping> mapping) {
39   std::vector<uint8_t> data(mapping->GetSize());
40   memcpy(data.data(), mapping->GetMapping(), mapping->GetSize());
41   return WrapByteData(std::move(data));
42 }
43 
44 }  // anonymous namespace
45 
PlatformMessageResponseDart(tonic::DartPersistentValue callback,fml::RefPtr<fml::TaskRunner> ui_task_runner)46 PlatformMessageResponseDart::PlatformMessageResponseDart(
47     tonic::DartPersistentValue callback,
48     fml::RefPtr<fml::TaskRunner> ui_task_runner)
49     : callback_(std::move(callback)),
50       ui_task_runner_(std::move(ui_task_runner)) {}
51 
~PlatformMessageResponseDart()52 PlatformMessageResponseDart::~PlatformMessageResponseDart() {
53   if (!callback_.is_empty()) {
54     ui_task_runner_->PostTask(fml::MakeCopyable(
55         [callback = std::move(callback_)]() mutable { callback.Clear(); }));
56   }
57 }
58 
Complete(std::unique_ptr<fml::Mapping> data)59 void PlatformMessageResponseDart::Complete(std::unique_ptr<fml::Mapping> data) {
60   if (callback_.is_empty())
61     return;
62   FML_DCHECK(!is_complete_);
63   is_complete_ = true;
64   ui_task_runner_->PostTask(fml::MakeCopyable(
65       [callback = std::move(callback_), data = std::move(data)]() mutable {
66         std::shared_ptr<tonic::DartState> dart_state =
67             callback.dart_state().lock();
68         if (!dart_state)
69           return;
70         tonic::DartState::Scope scope(dart_state);
71 
72         Dart_Handle byte_buffer = WrapByteData(std::move(data));
73         tonic::DartInvoke(callback.Release(), {byte_buffer});
74       }));
75 }
76 
CompleteEmpty()77 void PlatformMessageResponseDart::CompleteEmpty() {
78   if (callback_.is_empty())
79     return;
80   FML_DCHECK(!is_complete_);
81   is_complete_ = true;
82   ui_task_runner_->PostTask(
83       fml::MakeCopyable([callback = std::move(callback_)]() mutable {
84         std::shared_ptr<tonic::DartState> dart_state =
85             callback.dart_state().lock();
86         if (!dart_state)
87           return;
88         tonic::DartState::Scope scope(dart_state);
89         tonic::DartInvoke(callback.Release(), {Dart_Null()});
90       }));
91 }
92 
93 }  // namespace flutter
94