platform_view.h 8.3 KB
Newer Older
1 2 3 4 5 6 7 8 9
// 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_FUCHSIA_PLATFORM_VIEW_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_PLATFORM_VIEW_H_

#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
10
#include <lib/fidl/cpp/binding.h>
11
#include <lib/fit/function.h>
12
#include <lib/ui/scenic/cpp/id.h>
13

14 15 16
#include <map>
#include <set>

17
#include "flutter/fml/macros.h"
18
#include "flutter/fml/time/time_delta.h"
19
#include "flutter/shell/common/platform_view.h"
20 21 22

#include "accessibility_bridge.h"

23 24
namespace flutter_runner {

25
using OnEnableWireframe = fit::function<void(bool)>;
26
using OnCreateView = fit::function<void(int64_t, bool, bool)>;
27
using OnUpdateView = fit::function<void(int64_t, bool, bool)>;
28
using OnDestroyView = fit::function<void(int64_t)>;
29
using OnCreateSurface = fit::function<std::unique_ptr<flutter::Surface>()>;
30

31 32 33 34 35 36 37 38
// PlatformView is the per-engine component residing on the platform thread that
// is responsible for all platform specific integrations -- particularly
// integration with the platform's accessibility, input, and windowing features.
//
// PlatformView communicates with the Dart code via "platform messages" handled
// in HandlePlatformMessage.  This communication is bidirectional.  Platform
// messages are notably responsible for communication related to input and
// external views / windowing.
39 40
//
// The PlatformView implements SessionListener and gets Session events but it
41 42
// does *not* actually own the Session itself; that is owned by the
// FuchsiaExternalViewEmbedder on the raster thread.
43
class PlatformView final : public flutter::PlatformView,
44
                           public AccessibilityBridge::Delegate,
45
                           private fuchsia::ui::scenic::SessionListener,
46
                           private fuchsia::ui::input::InputMethodEditorClient {
47
 public:
48
  PlatformView(flutter::PlatformView::Delegate& delegate,
49
               std::string debug_label,
50
               fuchsia::ui::views::ViewRef view_ref,
51
               flutter::TaskRunners task_runners,
52
               std::shared_ptr<sys::ServiceDirectory> runner_services,
53 54 55 56
               fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
                   parent_environment_service_provider,
               fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>
                   session_listener_request,
57
               fidl::InterfaceHandle<fuchsia::ui::views::Focuser> focuser,
58
               fit::closure on_session_listener_error_callback,
59
               OnEnableWireframe wireframe_enabled_callback,
60
               OnCreateView on_create_view_callback,
61
               OnUpdateView on_update_view_callback,
62
               OnDestroyView on_destroy_view_callback,
63 64 65
               OnCreateSurface on_create_surface_callback,
               fml::TimeDelta vsync_offset,
               zx_handle_t vsync_event_handle);
66 67 68

  ~PlatformView();

69 70 71 72
  // |flutter::PlatformView|
  // |flutter_runner::AccessibilityBridge::Delegate|
  void SetSemanticsEnabled(bool enabled) override;

D
Dan Field 已提交
73 74 75 76
  // |flutter_runner::AccessibilityBridge::Delegate|
  void DispatchSemanticsAction(int32_t node_id,
                               flutter::SemanticsAction action) override;

77 78 79
  // |PlatformView|
  flutter::PointerDataDispatcherMaker GetDispatcherMaker() override;

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
 private:
  void RegisterPlatformMessageHandlers();

  // |fuchsia::ui::input::InputMethodEditorClient|
  void DidUpdateState(
      fuchsia::ui::input::TextInputState state,
      std::unique_ptr<fuchsia::ui::input::InputEvent> event) override;

  // |fuchsia::ui::input::InputMethodEditorClient|
  void OnAction(fuchsia::ui::input::InputMethodAction action) override;

  // |fuchsia::ui::scenic::SessionListener|
  void OnScenicError(std::string error) override;
  void OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) override;

  void OnChildViewConnected(scenic::ResourceId view_holder_id);
  void OnChildViewDisconnected(scenic::ResourceId view_holder_id);
  void OnChildViewStateChanged(scenic::ResourceId view_holder_id, bool state);

  bool OnHandlePointerEvent(const fuchsia::ui::input::PointerEvent& pointer);

  bool OnHandleKeyboardEvent(const fuchsia::ui::input::KeyboardEvent& keyboard);

  bool OnHandleFocusEvent(const fuchsia::ui::input::FocusEvent& focus);

  // Gets a new input method editor from the input connection. Run when both
  // Scenic has focus and Flutter has requested input with setClient.
  void ActivateIme();

  // Detaches the input method editor connection, ending the edit session and
  // closing the onscreen keyboard. Call when input is no longer desired, either
  // because Scenic says we lost focus or when Flutter no longer has a text
  // field focused.
  void DeactivateIme();

  // |flutter::PlatformView|
  std::unique_ptr<flutter::VsyncWaiter> CreateVSyncWaiter() override;

  // |flutter::PlatformView|
  std::unique_ptr<flutter::Surface> CreateRenderingSurface() override;

  // |flutter::PlatformView|
  void HandlePlatformMessage(
      fml::RefPtr<flutter::PlatformMessage> message) override;

  // |flutter::PlatformView|
  void UpdateSemantics(
      flutter::SemanticsNodeUpdates update,
      flutter::CustomAccessibilityActionUpdates actions) override;

  // Channel handler for kAccessibilityChannel. This is currently not
  // being used, but it is necessary to handle accessibility messages
  // that are sent by Flutter when semantics is enabled.
  void HandleAccessibilityChannelPlatformMessage(
      fml::RefPtr<flutter::PlatformMessage> message);

  // Channel handler for kFlutterPlatformChannel
  void HandleFlutterPlatformChannelPlatformMessage(
      fml::RefPtr<flutter::PlatformMessage> message);

  // Channel handler for kTextInputChannel
  void HandleFlutterTextInputChannelPlatformMessage(
      fml::RefPtr<flutter::PlatformMessage> message);

144 145 146 147
  // Channel handler for kPlatformViewsChannel.
  void HandleFlutterPlatformViewsChannelPlatformMessage(
      fml::RefPtr<flutter::PlatformMessage> message);

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
  const std::string debug_label_;
  // TODO(MI4-2490): remove once ViewRefControl is passed to Scenic and kept
  // alive there
  const fuchsia::ui::views::ViewRef view_ref_;
  fuchsia::ui::views::FocuserPtr focuser_;
  std::unique_ptr<AccessibilityBridge> accessibility_bridge_;

  // Logical size and logical->physical ratio.  These are optional to provide
  // an "unset" state during program startup, before Scenic has sent any
  // metrics-related events to provide initial values for these.
  //
  // The engine internally uses a default size of (0.f 0.f) with a default 1.f
  // ratio, so there is no need to emit events until Scenic has actually sent a
  // valid size and ratio.
  std::optional<std::pair<float, float>> view_logical_size_;
  std::optional<float> view_pixel_ratio_;

  fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_binding_;
  fit::closure session_listener_error_callback_;
  OnEnableWireframe wireframe_enabled_callback_;
  OnCreateView on_create_view_callback_;
  OnUpdateView on_update_view_callback_;
  OnDestroyView on_destroy_view_callback_;
  OnCreateSurface on_create_surface_callback_;

  int current_text_input_client_ = 0;
  fidl::Binding<fuchsia::ui::input::InputMethodEditorClient> ime_client_;
  fuchsia::ui::input::InputMethodEditorPtr ime_;
  fuchsia::ui::input::ImeServicePtr text_sync_service_;

  fuchsia::sys::ServiceProviderPtr parent_environment_service_provider_;

  // last_text_state_ is the last state of the text input as reported by the IME
  // or initialized by Flutter. We set it to null if Flutter doesn't want any
  // input, since then there is no text input state at all.
  std::unique_ptr<fuchsia::ui::input::TextInputState> last_text_state_;

  std::set<int> down_pointers_;
  std::map<
      std::string /* channel */,
      fit::function<void(
          fml::RefPtr<flutter::PlatformMessage> /* message */)> /* handler */>
      platform_message_handlers_;
  // These are the channels that aren't registered and have been notified as
  // such. Notifying via logs multiple times results in log-spam. See:
  // https://github.com/flutter/flutter/issues/55966
  std::set<std::string /* channel */> unregistered_channels_;

  fml::TimeDelta vsync_offset_;
  zx_handle_t vsync_event_handle_ = 0;

199 200 201 202 203 204
  FML_DISALLOW_COPY_AND_ASSIGN(PlatformView);
};

}  // namespace flutter_runner

#endif  // FLUTTER_SHELL_PLATFORM_FUCHSIA_PLATFORM_VIEW_H_