// 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 "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"

#include <algorithm>
#include <iostream>
#include <vector>

#include "flutter/shell/platform/common/app_lifecycle_state.h"
#include "flutter/shell/platform/common/engine_switches.h"
#include "flutter/shell/platform/embedder/embedder.h"

#import "flutter/shell/platform/darwin/common/framework/Source/FlutterBinaryMessengerRelay.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterAppDelegate_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h"

@class FlutterEngineRegistrar;

NSString* const kFlutterPlatformChannel = @"flutter/platform";
NSString* const kFlutterSettingsChannel = @"flutter/settings";
NSString* const kFlutterLifecycleChannel = @"flutter/lifecycle";

/**
 * Constructs and returns a FlutterLocale struct corresponding to |locale|, which must outlive
 * the returned struct.
 */
static FlutterLocale FlutterLocaleFromNSLocale(NSLocale* locale) {
  FlutterLocale flutterLocale = {};
  flutterLocale.struct_size = sizeof(FlutterLocale);
  flutterLocale.language_code = [[locale objectForKey:NSLocaleLanguageCode] UTF8String];
  flutterLocale.country_code = [[locale objectForKey:NSLocaleCountryCode] UTF8String];
  flutterLocale.script_code = [[locale objectForKey:NSLocaleScriptCode] UTF8String];
  flutterLocale.variant_code = [[locale objectForKey:NSLocaleVariantCode] UTF8String];
  return flutterLocale;
}

/// The private notification for voice over.
static NSString* const kEnhancedUserInterfaceNotification =
    @"NSApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification";
static NSString* const kEnhancedUserInterfaceKey = @"AXEnhancedUserInterface";

/// Clipboard plain text format.
constexpr char kTextPlainFormat[] = "text/plain";

#pragma mark -

// Records an active handler of the messenger (FlutterEngine) that listens to
// platform messages on a given channel.
@interface FlutterEngineHandlerInfo : NSObject

- (instancetype)initWithConnection:(NSNumber*)connection
                           handler:(FlutterBinaryMessageHandler)handler;

@property(nonatomic, readonly) FlutterBinaryMessageHandler handler;
@property(nonatomic, readonly) NSNumber* connection;

@end

@implementation FlutterEngineHandlerInfo
- (instancetype)initWithConnection:(NSNumber*)connection
                           handler:(FlutterBinaryMessageHandler)handler {
  self = [super init];
  NSAssert(self, @"Super init cannot be nil");
  _connection = connection;
  _handler = handler;
  return self;
}
@end

#pragma mark -

/**
 * Private interface declaration for FlutterEngine.
 */
@interface FlutterEngine () <FlutterBinaryMessenger>

/**
 * A mutable array that holds one bool value that determines if responses to platform messages are
 * clear to execute. This value should be read or written only inside of a synchronized block and
 * will return `NO` after the FlutterEngine has been dealloc'd.
 */
@property(nonatomic, strong) NSMutableArray<NSNumber*>* isResponseValid;

/**
 * All delegates added via plugin calls to addApplicationDelegate.
 */
@property(nonatomic, strong) NSPointerArray* pluginAppDelegates;

/**
 * All registrars returned from registrarForPlugin:
 */
@property(nonatomic, readonly)
    NSMutableDictionary<NSString*, FlutterEngineRegistrar*>* pluginRegistrars;

- (nullable FlutterViewController*)viewControllerForId:(FlutterViewId)viewId;

/**
 * An internal method that adds the view controller with the given ID.
 *
 * This method assigns the controller with the ID, puts the controller into the
 * map, and does assertions related to the implicit view ID.
 */
- (void)registerViewController:(FlutterViewController*)controller forId:(FlutterViewId)viewId;

/**
 * An internal method that removes the view controller with the given ID.
 *
 * This method clears the ID of the controller, removes the controller from the
 * map. This is an no-op if the view ID is not associated with any view
 * controllers.
 */
- (void)deregisterViewControllerForId:(FlutterViewId)viewId;

/**
 * Shuts down the engine if view requirement is not met, and headless execution
 * is not allowed.
 */
- (void)shutDownIfNeeded;

/**
 * Sends the list of user-preferred locales to the Flutter engine.
 */
- (void)sendUserLocales;

/**
 * Handles a platform message from the engine.
 */
- (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message;

/**
 * Invoked right before the engine is restarted.
 *
 * This should reset states to as if the application has just started.  It
 * usually indicates a hot restart (Shift-R in Flutter CLI.)
 */
- (void)engineCallbackOnPreEngineRestart;

/**
 * Requests that the task be posted back the to the Flutter engine at the target time. The target
 * time is in the clock used by the Flutter engine.
 */
- (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)targetTime;

/**
 * Loads the AOT snapshots and instructions from the elf bundle (app_elf_snapshot.so) into _aotData,
 * if it is present in the assets directory.
 */
- (void)loadAOTData:(NSString*)assetsDir;

/**
 * Creates a platform view channel and sets up the method handler.
 */
- (void)setUpPlatformViewChannel;

/**
 * Creates an accessibility channel and sets up the message handler.
 */
- (void)setUpAccessibilityChannel;

/**
 * Handles messages received from the Flutter engine on the _*Channel channels.
 */
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;

@end

#pragma mark -

@implementation FlutterEngineTerminationHandler {
  __weak FlutterEngine* _engine;
  FlutterTerminationCallback _terminator;
}

- (instancetype)initWithEngine:(FlutterEngine*)engine
                    terminator:(FlutterTerminationCallback)terminator {
  self = [super init];
  _acceptingRequests = NO;
  _engine = engine;
  _terminator = terminator ? terminator : ^(id sender) {
    // Default to actually terminating the application. The terminator exists to
    // allow tests to override it so that an actual exit doesn't occur.
    [[NSApplication sharedApplication] terminate:sender];
  };
  id<NSApplicationDelegate> appDelegate = [[NSApplication sharedApplication] delegate];
  if ([appDelegate respondsToSelector:@selector(setTerminationHandler:)]) {
    FlutterAppDelegate* flutterAppDelegate = reinterpret_cast<FlutterAppDelegate*>(appDelegate);
    flutterAppDelegate.terminationHandler = self;
  }
  return self;
}

// This is called by the method call handler in the engine when the application
// requests termination itself.
- (void)handleRequestAppExitMethodCall:(NSDictionary<NSString*, id>*)arguments
                                result:(FlutterResult)result {
  NSString* type = arguments[@"type"];
  // Ignore the "exitCode" value in the arguments because AppKit doesn't have
  // any good way to set the process exit code other than calling exit(), and
  // that bypasses all of the native applicationShouldExit shutdown events,
  // etc., which we don't want to skip.

  FlutterAppExitType exitType =
      [type isEqualTo:@"cancelable"] ? kFlutterAppExitTypeCancelable : kFlutterAppExitTypeRequired;

  [self requestApplicationTermination:[NSApplication sharedApplication]
                             exitType:exitType
                               result:result];
}

// This is called by the FlutterAppDelegate whenever any termination request is
// received.
- (void)requestApplicationTermination:(id)sender
                             exitType:(FlutterAppExitType)type
                               result:(nullable FlutterResult)result {
  _shouldTerminate = YES;
  if (![self acceptingRequests]) {
    // Until the Dart application has signaled that it is ready to handle
    // termination requests, the app will just terminate when asked.
    type = kFlutterAppExitTypeRequired;
  }
  switch (type) {
    case kFlutterAppExitTypeCancelable: {
      FlutterJSONMethodCodec* codec = [FlutterJSONMethodCodec sharedInstance];
      FlutterMethodCall* methodCall =
          [FlutterMethodCall methodCallWithMethodName:@"System.requestAppExit" arguments:nil];
      [_engine sendOnChannel:kFlutterPlatformChannel
                     message:[codec encodeMethodCall:methodCall]
                 binaryReply:^(NSData* _Nullable reply) {
                   NSAssert(_terminator, @"terminator shouldn't be nil");
                   id decoded_reply = [codec decodeEnvelope:reply];
                   if ([decoded_reply isKindOfClass:[FlutterError class]]) {
                     FlutterError* error = (FlutterError*)decoded_reply;
                     NSLog(@"Method call returned error[%@]: %@ %@", [error code], [error message],
                           [error details]);
                     _terminator(sender);
                     return;
                   }
                   if (![decoded_reply isKindOfClass:[NSDictionary class]]) {
                     NSLog(@"Call to System.requestAppExit returned an unexpected object: %@",
                           decoded_reply);
                     _terminator(sender);
                     return;
                   }
                   NSDictionary* replyArgs = (NSDictionary*)decoded_reply;
                   if ([replyArgs[@"response"] isEqual:@"exit"]) {
                     _terminator(sender);
                   } else if ([replyArgs[@"response"] isEqual:@"cancel"]) {
                     _shouldTerminate = NO;
                   }
                   if (result != nil) {
                     result(replyArgs);
                   }
                 }];
      break;
    }
    case kFlutterAppExitTypeRequired:
      NSAssert(_terminator, @"terminator shouldn't be nil");
      _terminator(sender);
      break;
  }
}

@end

#pragma mark -

@implementation FlutterPasteboard

- (NSInteger)clearContents {
  return [[NSPasteboard generalPasteboard] clearContents];
}

- (NSString*)stringForType:(NSPasteboardType)dataType {
  return [[NSPasteboard generalPasteboard] stringForType:dataType];
}

- (BOOL)setString:(nonnull NSString*)string forType:(nonnull NSPasteboardType)dataType {
  return [[NSPasteboard generalPasteboard] setString:string forType:dataType];
}

@end

#pragma mark -

/**
 * `FlutterPluginRegistrar` implementation handling a single plugin.
 */
@interface FlutterEngineRegistrar : NSObject <FlutterPluginRegistrar>
- (instancetype)initWithPlugin:(nonnull NSString*)pluginKey
                 flutterEngine:(nonnull FlutterEngine*)flutterEngine;

- (nullable NSView*)viewForId:(FlutterViewId)viewId;

/**
 * The value published by this plugin, or NSNull if nothing has been published.
 *
 * The unusual NSNull is for the documented behavior of valuePublishedByPlugin:.
 */
@property(nonatomic, readonly, nonnull) NSObject* publishedValue;
@end

@implementation FlutterEngineRegistrar {
  NSString* _pluginKey;
  __weak FlutterEngine* _flutterEngine;
}

@dynamic view;

- (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine*)flutterEngine {
  self = [super init];
  if (self) {
    _pluginKey = [pluginKey copy];
    _flutterEngine = flutterEngine;
    _publishedValue = [NSNull null];
  }
  return self;
}

#pragma mark - FlutterPluginRegistrar

- (id<FlutterBinaryMessenger>)messenger {
  return _flutterEngine.binaryMessenger;
}

- (id<FlutterTextureRegistry>)textures {
  return _flutterEngine.renderer;
}

- (NSView*)view {
  return [self viewForId:kFlutterImplicitViewId];
}

- (NSView*)viewForId:(FlutterViewId)viewId {
  FlutterViewController* controller = [_flutterEngine viewControllerForId:viewId];
  if (controller == nil) {
    return nil;
  }
  if (!controller.viewLoaded) {
    [controller loadView];
  }
  return controller.flutterView;
}

- (void)addMethodCallDelegate:(nonnull id<FlutterPlugin>)delegate
                      channel:(nonnull FlutterMethodChannel*)channel {
  [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    [delegate handleMethodCall:call result:result];
  }];
}

- (void)addApplicationDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
  id<NSApplicationDelegate> appDelegate = [[NSApplication sharedApplication] delegate];
  if ([appDelegate conformsToProtocol:@protocol(FlutterAppLifecycleProvider)]) {
    id<FlutterAppLifecycleProvider> lifeCycleProvider =
        static_cast<id<FlutterAppLifecycleProvider>>(appDelegate);
    [lifeCycleProvider addApplicationLifecycleDelegate:delegate];
    [_flutterEngine.pluginAppDelegates addPointer:(__bridge void*)delegate];
  }
}

- (void)registerViewFactory:(nonnull NSObject<FlutterPlatformViewFactory>*)factory
                     withId:(nonnull NSString*)factoryId {
  [[_flutterEngine platformViewController] registerViewFactory:factory withId:factoryId];
}

- (void)publish:(NSObject*)value {
  _publishedValue = value;
}

- (NSString*)lookupKeyForAsset:(NSString*)asset {
  return [FlutterDartProject lookupKeyForAsset:asset];
}

- (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package {
  return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package];
}

@end

// Callbacks provided to the engine. See the called methods for documentation.
#pragma mark - Static methods provided to engine configuration

static void OnPlatformMessage(const FlutterPlatformMessage* message, FlutterEngine* engine) {
  [engine engineCallbackOnPlatformMessage:message];
}

#pragma mark -

@implementation FlutterEngine {
  // The embedding-API-level engine object.
  FLUTTER_API_SYMBOL(FlutterEngine) _engine;

  // The project being run by this engine.
  FlutterDartProject* _project;

  // A mapping of channel names to the registered information for those channels.
  NSMutableDictionary<NSString*, FlutterEngineHandlerInfo*>* _messengerHandlers;

  // A self-incremental integer to assign to newly assigned channels as
  // identification.
  FlutterBinaryMessengerConnection _currentMessengerConnection;

  // Whether the engine can continue running after the view controller is removed.
  BOOL _allowHeadlessExecution;

  // Pointer to the Dart AOT snapshot and instruction data.
  _FlutterEngineAOTData* _aotData;

  // _macOSCompositor is created when the engine is created and its destruction is handled by ARC
  // when the engine is destroyed.
  std::unique_ptr<flutter::FlutterCompositor> _macOSCompositor;

  // The information of all views attached to this engine mapped from IDs.
  //
  // It can't use NSDictionary, because the values need to be weak references.
  NSMapTable* _viewControllers;

  // FlutterCompositor is copied and used in embedder.cc.
  FlutterCompositor _compositor;

  // Method channel for platform view functions. These functions include creating, disposing and
  // mutating a platform view.
  FlutterMethodChannel* _platformViewsChannel;

  // Used to support creation and deletion of platform views and registering platform view
  // factories. Lifecycle is tied to the engine.
  FlutterPlatformViewController* _platformViewController;

  // A message channel for sending user settings to the flutter engine.
  FlutterBasicMessageChannel* _settingsChannel;

  // A message channel for accessibility.
  FlutterBasicMessageChannel* _accessibilityChannel;

  // A method channel for miscellaneous platform functionality.
  FlutterMethodChannel* _platformChannel;

  FlutterThreadSynchronizer* _threadSynchronizer;

  // The next available view ID.
  int _nextViewId;

  // Whether the application is currently the active application.
  BOOL _active;

  // Whether any portion of the application is currently visible.
  BOOL _visible;

  // Proxy to allow plugins, channels to hold a weak reference to the binary messenger (self).
  FlutterBinaryMessengerRelay* _binaryMessenger;
}

- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project {
  return [self initWithName:labelPrefix project:project allowHeadlessExecution:YES];
}

- (instancetype)initWithName:(NSString*)labelPrefix
                     project:(FlutterDartProject*)project
      allowHeadlessExecution:(BOOL)allowHeadlessExecution {
  self = [super init];
  NSAssert(self, @"Super init cannot be nil");
  _pasteboard = [[FlutterPasteboard alloc] init];
  _active = NO;
  _visible = NO;
  _project = project ?: [[FlutterDartProject alloc] init];
  _messengerHandlers = [[NSMutableDictionary alloc] init];
  _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self];
  _pluginAppDelegates = [NSPointerArray weakObjectsPointerArray];
  _pluginRegistrars = [[NSMutableDictionary alloc] init];
  _currentMessengerConnection = 1;
  _allowHeadlessExecution = allowHeadlessExecution;
  _semanticsEnabled = NO;
  _binaryMessenger = [[FlutterBinaryMessengerRelay alloc] initWithParent:self];
  _isResponseValid = [[NSMutableArray alloc] initWithCapacity:1];
  [_isResponseValid addObject:@YES];
  // kFlutterImplicitViewId is reserved for the implicit view.
  _nextViewId = kFlutterImplicitViewId + 1;

  _embedderAPI.struct_size = sizeof(FlutterEngineProcTable);
  FlutterEngineGetProcAddresses(&_embedderAPI);

  _viewControllers = [NSMapTable weakToWeakObjectsMapTable];
  _renderer = [[FlutterRenderer alloc] initWithFlutterEngine:self];

  NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
  [notificationCenter addObserver:self
                         selector:@selector(sendUserLocales)
                             name:NSCurrentLocaleDidChangeNotification
                           object:nil];

  _platformViewController = [[FlutterPlatformViewController alloc] init];
  _threadSynchronizer = [[FlutterThreadSynchronizer alloc] init];
  [self setUpPlatformViewChannel];
  [self setUpAccessibilityChannel];
  [self setUpNotificationCenterListeners];
  id<NSApplicationDelegate> appDelegate = [[NSApplication sharedApplication] delegate];
  if ([appDelegate conformsToProtocol:@protocol(FlutterAppLifecycleProvider)]) {
    _terminationHandler = [[FlutterEngineTerminationHandler alloc] initWithEngine:self
                                                                       terminator:nil];
    id<FlutterAppLifecycleProvider> lifecycleProvider =
        static_cast<id<FlutterAppLifecycleProvider>>(appDelegate);
    [lifecycleProvider addApplicationLifecycleDelegate:self];
  } else {
    _terminationHandler = nil;
  }

  return self;
}

- (void)dealloc {
  id<NSApplicationDelegate> appDelegate = [[NSApplication sharedApplication] delegate];
  if ([appDelegate conformsToProtocol:@protocol(FlutterAppLifecycleProvider)]) {
    id<FlutterAppLifecycleProvider> lifecycleProvider =
        static_cast<id<FlutterAppLifecycleProvider>>(appDelegate);
    [lifecycleProvider removeApplicationLifecycleDelegate:self];

    // Unregister any plugins that registered as app delegates, since they are not guaranteed to
    // live after the engine is destroyed, and their delegation registration is intended to be bound
    // to the engine and its lifetime.
    for (id<FlutterAppLifecycleDelegate> delegate in _pluginAppDelegates) {
      if (delegate) {
        [lifecycleProvider removeApplicationLifecycleDelegate:delegate];
      }
    }
  }
  // Clear any published values, just in case a plugin has created a retain cycle with the
  // registrar.
  for (NSString* pluginName in _pluginRegistrars) {
    [_pluginRegistrars[pluginName] publish:[NSNull null]];
  }
  @synchronized(_isResponseValid) {
    [_isResponseValid removeAllObjects];
    [_isResponseValid addObject:@NO];
  }
  [self shutDownEngine];
  if (_aotData) {
    _embedderAPI.CollectAOTData(_aotData);
  }
}

- (BOOL)runWithEntrypoint:(NSString*)entrypoint {
  if (self.running) {
    return NO;
  }

  if (!_allowHeadlessExecution && [_viewControllers count] == 0) {
    NSLog(@"Attempted to run an engine with no view controller without headless mode enabled.");
    return NO;
  }

  [self addInternalPlugins];

  // The first argument of argv is required to be the executable name.
  std::vector<const char*> argv = {[self.executableName UTF8String]};
  std::vector<std::string> switches = self.switches;

  // Enable Impeller only if specifically asked for from the project or cmdline arguments.
  if (_project.enableImpeller ||
      std::find(switches.begin(), switches.end(), "--enable-impeller=true") != switches.end()) {
    switches.push_back("--enable-impeller=true");
  }

  std::transform(switches.begin(), switches.end(), std::back_inserter(argv),
                 [](const std::string& arg) -> const char* { return arg.c_str(); });

  std::vector<const char*> dartEntrypointArgs;
  for (NSString* argument in [_project dartEntrypointArguments]) {
    dartEntrypointArgs.push_back([argument UTF8String]);
  }

  FlutterProjectArgs flutterArguments = {};
  flutterArguments.struct_size = sizeof(FlutterProjectArgs);
  flutterArguments.assets_path = _project.assetsPath.UTF8String;
  flutterArguments.icu_data_path = _project.ICUDataPath.UTF8String;
  flutterArguments.command_line_argc = static_cast<int>(argv.size());
  flutterArguments.command_line_argv = argv.empty() ? nullptr : argv.data();
  flutterArguments.platform_message_callback = (FlutterPlatformMessageCallback)OnPlatformMessage;
  flutterArguments.update_semantics_callback2 = [](const FlutterSemanticsUpdate2* update,
                                                   void* user_data) {
    // TODO(dkwingsmt): This callback only supports single-view, therefore it
    // only operates on the implicit view. To support multi-view, we need a
    // way to pass in the ID (probably through FlutterSemanticsUpdate).
    FlutterEngine* engine = (__bridge FlutterEngine*)user_data;
    [[engine viewControllerForId:kFlutterImplicitViewId] updateSemantics:update];
  };
  flutterArguments.custom_dart_entrypoint = entrypoint.UTF8String;
  flutterArguments.shutdown_dart_vm_when_done = true;
  flutterArguments.dart_entrypoint_argc = dartEntrypointArgs.size();
  flutterArguments.dart_entrypoint_argv = dartEntrypointArgs.data();
  flutterArguments.root_isolate_create_callback = _project.rootIsolateCreateCallback;
  flutterArguments.log_message_callback = [](const char* tag, const char* message,
                                             void* user_data) {
    if (tag && tag[0]) {
      std::cout << tag << ": ";
    }
    std::cout << message << std::endl;
  };

  static size_t sTaskRunnerIdentifiers = 0;
  const FlutterTaskRunnerDescription cocoa_task_runner_description = {
      .struct_size = sizeof(FlutterTaskRunnerDescription),
      .user_data = (void*)CFBridgingRetain(self),
      .runs_task_on_current_thread_callback = [](void* user_data) -> bool {
        return [[NSThread currentThread] isMainThread];
      },
      .post_task_callback = [](FlutterTask task, uint64_t target_time_nanos,
                               void* user_data) -> void {
        [((__bridge FlutterEngine*)(user_data)) postMainThreadTask:task
                                           targetTimeInNanoseconds:target_time_nanos];
      },
      .identifier = ++sTaskRunnerIdentifiers,
  };
  const FlutterCustomTaskRunners custom_task_runners = {
      .struct_size = sizeof(FlutterCustomTaskRunners),
      .platform_task_runner = &cocoa_task_runner_description,
  };
  flutterArguments.custom_task_runners = &custom_task_runners;

  [self loadAOTData:_project.assetsPath];
  if (_aotData) {
    flutterArguments.aot_data = _aotData;
  }

  flutterArguments.compositor = [self createFlutterCompositor];

  flutterArguments.on_pre_engine_restart_callback = [](void* user_data) {
    FlutterEngine* engine = (__bridge FlutterEngine*)user_data;
    [engine engineCallbackOnPreEngineRestart];
  };

  FlutterRendererConfig rendererConfig = [_renderer createRendererConfig];
  FlutterEngineResult result = _embedderAPI.Initialize(
      FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine);
  if (result != kSuccess) {
    NSLog(@"Failed to initialize Flutter engine: error %d", result);
    return NO;
  }

  result = _embedderAPI.RunInitialized(_engine);
  if (result != kSuccess) {
    NSLog(@"Failed to run an initialized engine: error %d", result);
    return NO;
  }

  [self sendUserLocales];

  // Update window metric for all view controllers.
  NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator];
  FlutterViewController* nextViewController;
  while ((nextViewController = [viewControllerEnumerator nextObject])) {
    [self updateWindowMetricsForViewController:nextViewController];
  }

  [self updateDisplayConfig];
  // Send the initial user settings such as brightness and text scale factor
  // to the engine.
  [self sendInitialSettings];
  return YES;
}

- (void)loadAOTData:(NSString*)assetsDir {
  if (!_embedderAPI.RunsAOTCompiledDartCode()) {
    return;
  }

  BOOL isDirOut = false;  // required for NSFileManager fileExistsAtPath.
  NSFileManager* fileManager = [NSFileManager defaultManager];

  // This is the location where the test fixture places the snapshot file.
  // For applications built by Flutter tool, this is in "App.framework".
  NSString* elfPath = [NSString pathWithComponents:@[ assetsDir, @"app_elf_snapshot.so" ]];

  if (![fileManager fileExistsAtPath:elfPath isDirectory:&isDirOut]) {
    return;
  }

  FlutterEngineAOTDataSource source = {};
  source.type = kFlutterEngineAOTDataSourceTypeElfPath;
  source.elf_path = [elfPath cStringUsingEncoding:NSUTF8StringEncoding];

  auto result = _embedderAPI.CreateAOTData(&source, &_aotData);
  if (result != kSuccess) {
    NSLog(@"Failed to load AOT data from: %@", elfPath);
  }
}

- (void)registerViewController:(FlutterViewController*)controller forId:(FlutterViewId)viewId {
  NSAssert(controller != nil, @"The controller must not be nil.");
  NSAssert(![controller attached],
           @"The incoming view controller is already attached to an engine.");
  NSAssert([_viewControllers objectForKey:@(viewId)] == nil, @"The requested view ID is occupied.");
  [controller setUpWithEngine:self viewId:viewId threadSynchronizer:_threadSynchronizer];
  NSAssert(controller.viewId == viewId, @"Failed to assign view ID.");
  [_viewControllers setObject:controller forKey:@(viewId)];
}

- (void)deregisterViewControllerForId:(FlutterViewId)viewId {
  FlutterViewController* oldController = [self viewControllerForId:viewId];
  if (oldController != nil) {
    [oldController detachFromEngine];
    [_viewControllers removeObjectForKey:@(viewId)];
  }
}

- (void)shutDownIfNeeded {
  if ([_viewControllers count] == 0 && !_allowHeadlessExecution) {
    [self shutDownEngine];
  }
}

- (FlutterViewController*)viewControllerForId:(FlutterViewId)viewId {
  FlutterViewController* controller = [_viewControllers objectForKey:@(viewId)];
  NSAssert(controller == nil || controller.viewId == viewId,
           @"The stored controller has unexpected view ID.");
  return controller;
}

- (void)setViewController:(FlutterViewController*)controller {
  FlutterViewController* currentController =
      [_viewControllers objectForKey:@(kFlutterImplicitViewId)];
  if (currentController == controller) {
    // From nil to nil, or from non-nil to the same controller.
    return;
  }
  if (currentController == nil && controller != nil) {
    // From nil to non-nil.
    NSAssert(controller.engine == nil,
             @"Failed to set view controller to the engine: "
             @"The given FlutterViewController is already attached to an engine %@. "
             @"If you wanted to create an FlutterViewController and set it to an existing engine, "
             @"you should use FlutterViewController#init(engine:, nibName, bundle:) instead.",
             controller.engine);
    [self registerViewController:controller forId:kFlutterImplicitViewId];
  } else if (currentController != nil && controller == nil) {
    NSAssert(currentController.viewId == kFlutterImplicitViewId,
             @"The default controller has an unexpected ID %llu", currentController.viewId);
    // From non-nil to nil.
    [self deregisterViewControllerForId:kFlutterImplicitViewId];
    [self shutDownIfNeeded];
  } else {
    // From non-nil to a different non-nil view controller.
    NSAssert(NO,
             @"Failed to set view controller to the engine: "
             @"The engine already has an implicit view controller %@. "
             @"If you wanted to make the implicit view render in a different window, "
             @"you should attach the current view controller to the window instead.",
             [_viewControllers objectForKey:@(kFlutterImplicitViewId)]);
  }
}

- (FlutterViewController*)viewController {
  return [self viewControllerForId:kFlutterImplicitViewId];
}

- (FlutterCompositor*)createFlutterCompositor {
  _macOSCompositor = std::make_unique<flutter::FlutterCompositor>(
      [[FlutterViewEngineProvider alloc] initWithEngine:self], _platformViewController);

  _compositor = {};
  _compositor.struct_size = sizeof(FlutterCompositor);
  _compositor.user_data = _macOSCompositor.get();

  _compositor.create_backing_store_callback = [](const FlutterBackingStoreConfig* config,  //
                                                 FlutterBackingStore* backing_store_out,   //
                                                 void* user_data                           //
                                              ) {
    return reinterpret_cast<flutter::FlutterCompositor*>(user_data)->CreateBackingStore(
        config, backing_store_out);
  };

  _compositor.collect_backing_store_callback = [](const FlutterBackingStore* backing_store,  //
                                                  void* user_data                            //
                                               ) { return true; };

  _compositor.present_layers_callback = [](const FlutterLayer** layers,  //
                                           size_t layers_count,          //
                                           void* user_data               //
                                        ) {
    // TODO(dkwingsmt): This callback only supports single-view, therefore it
    // only operates on the implicit view. To support multi-view, we need a new
    // callback that also receives a view ID.
    return reinterpret_cast<flutter::FlutterCompositor*>(user_data)->Present(kFlutterImplicitViewId,
                                                                             layers, layers_count);
  };

  _compositor.avoid_backing_store_cache = true;

  return &_compositor;
}

- (id<FlutterBinaryMessenger>)binaryMessenger {
  return _binaryMessenger;
}

#pragma mark - Framework-internal methods

- (void)addViewController:(FlutterViewController*)controller {
  [self registerViewController:controller forId:kFlutterImplicitViewId];
}

- (void)removeViewController:(nonnull FlutterViewController*)viewController {
  NSAssert([viewController attached] && viewController.engine == self,
           @"The given view controller is not associated with this engine.");
  [self deregisterViewControllerForId:viewController.viewId];
  [self shutDownIfNeeded];
}

- (BOOL)running {
  return _engine != nullptr;
}

- (void)updateDisplayConfig:(NSNotification*)notification {
  [self updateDisplayConfig];
}

- (void)updateDisplayConfig {
  if (!_engine) {
    return;
  }

  std::vector<FlutterEngineDisplay> displays;
  for (NSScreen* screen : [NSScreen screens]) {
    CGDirectDisplayID displayID =
        static_cast<CGDirectDisplayID>([screen.deviceDescription[@"NSScreenNumber"] integerValue]);

    FlutterEngineDisplay display;
    display.struct_size = sizeof(display);
    display.display_id = displayID;
    display.single_display = false;
    display.width = static_cast<size_t>(screen.frame.size.width);
    display.height = static_cast<size_t>(screen.frame.size.height);
    display.device_pixel_ratio = screen.backingScaleFactor;

    CVDisplayLinkRef displayLinkRef = nil;
    CVReturn error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLinkRef);

    if (error == 0) {
      CVTime nominal = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLinkRef);
      if (!(nominal.flags & kCVTimeIsIndefinite)) {
        double refreshRate = static_cast<double>(nominal.timeScale) / nominal.timeValue;
        display.refresh_rate = round(refreshRate);
      }
      CVDisplayLinkRelease(displayLinkRef);
    } else {
      display.refresh_rate = 0;
    }

    displays.push_back(display);
  }
  _embedderAPI.NotifyDisplayUpdate(_engine, kFlutterEngineDisplaysUpdateTypeStartup,
                                   displays.data(), displays.size());
}

- (void)onSettingsChanged:(NSNotification*)notification {
  // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/32015.
  NSString* brightness =
      [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
  [_settingsChannel sendMessage:@{
    @"platformBrightness" : [brightness isEqualToString:@"Dark"] ? @"dark" : @"light",
    // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/32006.
    @"textScaleFactor" : @1.0,
    @"alwaysUse24HourFormat" : @false
  }];
}

- (void)sendInitialSettings {
  // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/32015.
  [[NSDistributedNotificationCenter defaultCenter]
      addObserver:self
         selector:@selector(onSettingsChanged:)
             name:@"AppleInterfaceThemeChangedNotification"
           object:nil];
  [self onSettingsChanged:nil];
}

- (FlutterEngineProcTable&)embedderAPI {
  return _embedderAPI;
}

- (nonnull NSString*)executableName {
  return [[[NSProcessInfo processInfo] arguments] firstObject] ?: @"Flutter";
}

- (void)updateWindowMetricsForViewController:(FlutterViewController*)viewController {
  if (viewController.viewId != kFlutterImplicitViewId) {
    // TODO(dkwingsmt): The embedder API only supports single-view for now. As
    // embedder APIs are converted to multi-view, this method should support any
    // views.
    return;
  }
  if (!_engine || !viewController || !viewController.viewLoaded) {
    return;
  }
  NSAssert([self viewControllerForId:viewController.viewId] == viewController,
           @"The provided view controller is not attached to this engine.");
  NSView* view = viewController.flutterView;
  CGRect scaledBounds = [view convertRectToBacking:view.bounds];
  CGSize scaledSize = scaledBounds.size;
  double pixelRatio = view.bounds.size.width == 0 ? 1 : scaledSize.width / view.bounds.size.width;
  auto displayId = [view.window.screen.deviceDescription[@"NSScreenNumber"] integerValue];
  const FlutterWindowMetricsEvent windowMetricsEvent = {
      .struct_size = sizeof(windowMetricsEvent),
      .width = static_cast<size_t>(scaledSize.width),
      .height = static_cast<size_t>(scaledSize.height),
      .pixel_ratio = pixelRatio,
      .left = static_cast<size_t>(scaledBounds.origin.x),
      .top = static_cast<size_t>(scaledBounds.origin.y),
      .display_id = static_cast<uint64_t>(displayId),
  };
  _embedderAPI.SendWindowMetricsEvent(_engine, &windowMetricsEvent);
}

- (void)sendPointerEvent:(const FlutterPointerEvent&)event {
  _embedderAPI.SendPointerEvent(_engine, &event, 1);
}

- (void)sendKeyEvent:(const FlutterKeyEvent&)event
            callback:(FlutterKeyEventCallback)callback
            userData:(void*)userData {
  _embedderAPI.SendKeyEvent(_engine, &event, callback, userData);
}

- (void)setSemanticsEnabled:(BOOL)enabled {
  if (_semanticsEnabled == enabled) {
    return;
  }
  _semanticsEnabled = enabled;

  // Update all view controllers' bridges.
  NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator];
  FlutterViewController* nextViewController;
  while ((nextViewController = [viewControllerEnumerator nextObject])) {
    [nextViewController notifySemanticsEnabledChanged];
  }

  _embedderAPI.UpdateSemanticsEnabled(_engine, _semanticsEnabled);
}

- (void)dispatchSemanticsAction:(FlutterSemanticsAction)action
                       toTarget:(uint16_t)target
                       withData:(fml::MallocMapping)data {
  _embedderAPI.DispatchSemanticsAction(_engine, target, action, data.GetMapping(), data.GetSize());
}

- (FlutterPlatformViewController*)platformViewController {
  return _platformViewController;
}

#pragma mark - Private methods

- (void)sendUserLocales {
  if (!self.running) {
    return;
  }

  // Create a list of FlutterLocales corresponding to the preferred languages.
  NSMutableArray<NSLocale*>* locales = [NSMutableArray array];
  std::vector<FlutterLocale> flutterLocales;
  flutterLocales.reserve(locales.count);
  for (NSString* localeID in [NSLocale preferredLanguages]) {
    NSLocale* locale = [[NSLocale alloc] initWithLocaleIdentifier:localeID];
    [locales addObject:locale];
    flutterLocales.push_back(FlutterLocaleFromNSLocale(locale));
  }
  // Convert to a list of pointers, and send to the engine.
  std::vector<const FlutterLocale*> flutterLocaleList;
  flutterLocaleList.reserve(flutterLocales.size());
  std::transform(flutterLocales.begin(), flutterLocales.end(),
                 std::back_inserter(flutterLocaleList),
                 [](const auto& arg) -> const auto* { return &arg; });
  _embedderAPI.UpdateLocales(_engine, flutterLocaleList.data(), flutterLocaleList.size());
}

- (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message {
  NSData* messageData = nil;
  if (message->message_size > 0) {
    messageData = [NSData dataWithBytesNoCopy:(void*)message->message
                                       length:message->message_size
                                 freeWhenDone:NO];
  }
  NSString* channel = @(message->channel);
  __block const FlutterPlatformMessageResponseHandle* responseHandle = message->response_handle;
  __block FlutterEngine* weakSelf = self;
  NSMutableArray* isResponseValid = self.isResponseValid;
  FlutterEngineSendPlatformMessageResponseFnPtr sendPlatformMessageResponse =
      _embedderAPI.SendPlatformMessageResponse;
  FlutterBinaryReply binaryResponseHandler = ^(NSData* response) {
    @synchronized(isResponseValid) {
      if (![isResponseValid[0] boolValue]) {
        // Ignore, engine was killed.
        return;
      }
      if (responseHandle) {
        sendPlatformMessageResponse(weakSelf->_engine, responseHandle,
                                    static_cast<const uint8_t*>(response.bytes), response.length);
        responseHandle = NULL;
      } else {
        NSLog(@"Error: Message responses can be sent only once. Ignoring duplicate response "
               "on channel '%@'.",
              channel);
      }
    }
  };

  FlutterEngineHandlerInfo* handlerInfo = _messengerHandlers[channel];
  if (handlerInfo) {
    handlerInfo.handler(messageData, binaryResponseHandler);
  } else {
    binaryResponseHandler(nil);
  }
}

- (void)engineCallbackOnPreEngineRestart {
  NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator];
  FlutterViewController* nextViewController;
  while ((nextViewController = [viewControllerEnumerator nextObject])) {
    [nextViewController onPreEngineRestart];
  }
}

/**
 * Note: Called from dealloc. Should not use accessors or other methods.
 */
- (void)shutDownEngine {
  if (_engine == nullptr) {
    return;
  }

  [_threadSynchronizer shutdown];
  _threadSynchronizer = nil;

  FlutterEngineResult result = _embedderAPI.Deinitialize(_engine);
  if (result != kSuccess) {
    NSLog(@"Could not de-initialize the Flutter engine: error %d", result);
  }

  // Balancing release for the retain in the task runner dispatch table.
  CFRelease((CFTypeRef)self);

  result = _embedderAPI.Shutdown(_engine);
  if (result != kSuccess) {
    NSLog(@"Failed to shut down Flutter engine: error %d", result);
  }
  _engine = nullptr;
}

- (void)setUpPlatformViewChannel {
  _platformViewsChannel =
      [FlutterMethodChannel methodChannelWithName:@"flutter/platform_views"
                                  binaryMessenger:self.binaryMessenger
                                            codec:[FlutterStandardMethodCodec sharedInstance]];

  __weak FlutterEngine* weakSelf = self;
  [_platformViewsChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    [[weakSelf platformViewController] handleMethodCall:call result:result];
  }];
}

- (void)setUpAccessibilityChannel {
  _accessibilityChannel = [FlutterBasicMessageChannel
      messageChannelWithName:@"flutter/accessibility"
             binaryMessenger:self.binaryMessenger
                       codec:[FlutterStandardMessageCodec sharedInstance]];
  __weak FlutterEngine* weakSelf = self;
  [_accessibilityChannel setMessageHandler:^(id message, FlutterReply reply) {
    [weakSelf handleAccessibilityEvent:message];
  }];
}
- (void)setUpNotificationCenterListeners {
  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
  // macOS fires this private message when VoiceOver turns on or off.
  [center addObserver:self
             selector:@selector(onAccessibilityStatusChanged:)
                 name:kEnhancedUserInterfaceNotification
               object:nil];
  [center addObserver:self
             selector:@selector(applicationWillTerminate:)
                 name:NSApplicationWillTerminateNotification
               object:nil];
  [center addObserver:self
             selector:@selector(windowDidChangeScreen:)
                 name:NSWindowDidChangeScreenNotification
               object:nil];
  [center addObserver:self
             selector:@selector(updateDisplayConfig:)
                 name:NSApplicationDidChangeScreenParametersNotification
               object:nil];
}

- (void)addInternalPlugins {
  __weak FlutterEngine* weakSelf = self;
  [FlutterMouseCursorPlugin registerWithRegistrar:[self registrarForPlugin:@"mousecursor"]];
  [FlutterMenuPlugin registerWithRegistrar:[self registrarForPlugin:@"menu"]];
  _settingsChannel =
      [FlutterBasicMessageChannel messageChannelWithName:kFlutterSettingsChannel
                                         binaryMessenger:self.binaryMessenger
                                                   codec:[FlutterJSONMessageCodec sharedInstance]];
  _platformChannel =
      [FlutterMethodChannel methodChannelWithName:kFlutterPlatformChannel
                                  binaryMessenger:self.binaryMessenger
                                            codec:[FlutterJSONMethodCodec sharedInstance]];
  [_platformChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    [weakSelf handleMethodCall:call result:result];
  }];
}

- (void)applicationWillTerminate:(NSNotification*)notification {
  [self shutDownEngine];
}

- (void)windowDidChangeScreen:(NSNotification*)notification {
  // Update window metric for all view controllers since the display_id has
  // changed.
  NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator];
  FlutterViewController* nextViewController;
  while ((nextViewController = [viewControllerEnumerator nextObject])) {
    [self updateWindowMetricsForViewController:nextViewController];
  }
}

- (void)onAccessibilityStatusChanged:(NSNotification*)notification {
  BOOL enabled = [notification.userInfo[kEnhancedUserInterfaceKey] boolValue];
  NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator];
  FlutterViewController* nextViewController;
  while ((nextViewController = [viewControllerEnumerator nextObject])) {
    [nextViewController onAccessibilityStatusChanged:enabled];
  }

  self.semanticsEnabled = enabled;
}
- (void)handleAccessibilityEvent:(NSDictionary<NSString*, id>*)annotatedEvent {
  NSString* type = annotatedEvent[@"type"];
  if ([type isEqualToString:@"announce"]) {
    NSString* message = annotatedEvent[@"data"][@"message"];
    NSNumber* assertiveness = annotatedEvent[@"data"][@"assertiveness"];
    if (message == nil) {
      return;
    }

    NSAccessibilityPriorityLevel priority = [assertiveness isEqualToNumber:@1]
                                                ? NSAccessibilityPriorityHigh
                                                : NSAccessibilityPriorityMedium;

    [self announceAccessibilityMessage:message withPriority:priority];
  }
}

- (void)announceAccessibilityMessage:(NSString*)message
                        withPriority:(NSAccessibilityPriorityLevel)priority {
  NSAccessibilityPostNotificationWithUserInfo(
      [self viewControllerForId:kFlutterImplicitViewId].flutterView,
      NSAccessibilityAnnouncementRequestedNotification,
      @{NSAccessibilityAnnouncementKey : message, NSAccessibilityPriorityKey : @(priority)});
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([call.method isEqualToString:@"SystemNavigator.pop"]) {
    [[NSApplication sharedApplication] terminate:self];
    result(nil);
  } else if ([call.method isEqualToString:@"SystemSound.play"]) {
    [self playSystemSound:call.arguments];
    result(nil);
  } else if ([call.method isEqualToString:@"Clipboard.getData"]) {
    result([self getClipboardData:call.arguments]);
  } else if ([call.method isEqualToString:@"Clipboard.setData"]) {
    [self setClipboardData:call.arguments];
    result(nil);
  } else if ([call.method isEqualToString:@"Clipboard.hasStrings"]) {
    result(@{@"value" : @([self clipboardHasStrings])});
  } else if ([call.method isEqualToString:@"System.exitApplication"]) {
    if ([self terminationHandler] == nil) {
      // If the termination handler isn't set, then either we haven't
      // initialized it yet, or (more likely) the NSApp delegate isn't a
      // FlutterAppDelegate, so it can't cancel requests to exit. So, in that
      // case, just terminate when requested.
      [NSApp terminate:self];
      result(nil);
    } else {
      [[self terminationHandler] handleRequestAppExitMethodCall:call.arguments result:result];
    }
  } else if ([call.method isEqualToString:@"System.initializationComplete"]) {
    if ([self terminationHandler] != nil) {
      [self terminationHandler].acceptingRequests = YES;
    }
    result(nil);
  } else {
    result(FlutterMethodNotImplemented);
  }
}

- (void)playSystemSound:(NSString*)soundType {
  if ([soundType isEqualToString:@"SystemSoundType.alert"]) {
    NSBeep();
  }
}

- (NSDictionary*)getClipboardData:(NSString*)format {
  if ([format isEqualToString:@(kTextPlainFormat)]) {
    NSString* stringInPasteboard = [self.pasteboard stringForType:NSPasteboardTypeString];
    return stringInPasteboard == nil ? nil : @{@"text" : stringInPasteboard};
  }
  return nil;
}

- (void)setClipboardData:(NSDictionary*)data {
  NSString* text = data[@"text"];
  [self.pasteboard clearContents];
  if (text && ![text isEqual:[NSNull null]]) {
    [self.pasteboard setString:text forType:NSPasteboardTypeString];
  }
}

- (BOOL)clipboardHasStrings {
  return [self.pasteboard stringForType:NSPasteboardTypeString].length > 0;
}

- (std::vector<std::string>)switches {
  return flutter::GetSwitchesFromEnvironment();
}

- (FlutterThreadSynchronizer*)testThreadSynchronizer {
  return _threadSynchronizer;
}

#pragma mark - FlutterAppLifecycleDelegate

- (void)setApplicationState:(flutter::AppLifecycleState)state {
  NSString* nextState =
      [[NSString alloc] initWithCString:flutter::AppLifecycleStateToString(state)];
  [self sendOnChannel:kFlutterLifecycleChannel
              message:[nextState dataUsingEncoding:NSUTF8StringEncoding]];
}

/**
 * Called when the |FlutterAppDelegate| gets the applicationWillBecomeActive
 * notification.
 */
- (void)handleWillBecomeActive:(NSNotification*)notification {
  _active = YES;
  if (!_visible) {
    [self setApplicationState:flutter::AppLifecycleState::kHidden];
  } else {
    [self setApplicationState:flutter::AppLifecycleState::kResumed];
  }
}

/**
 * Called when the |FlutterAppDelegate| gets the applicationWillResignActive
 * notification.
 */
- (void)handleWillResignActive:(NSNotification*)notification {
  _active = NO;
  if (!_visible) {
    [self setApplicationState:flutter::AppLifecycleState::kHidden];
  } else {
    [self setApplicationState:flutter::AppLifecycleState::kInactive];
  }
}

/**
 * Called when the |FlutterAppDelegate| gets the applicationDidUnhide
 * notification.
 */
- (void)handleDidChangeOcclusionState:(NSNotification*)notification {
  NSApplicationOcclusionState occlusionState = [[NSApplication sharedApplication] occlusionState];
  if (occlusionState & NSApplicationOcclusionStateVisible) {
    _visible = YES;
    if (_active) {
      [self setApplicationState:flutter::AppLifecycleState::kResumed];
    } else {
      [self setApplicationState:flutter::AppLifecycleState::kInactive];
    }
  } else {
    _visible = NO;
    [self setApplicationState:flutter::AppLifecycleState::kHidden];
  }
}

#pragma mark - FlutterBinaryMessenger

- (void)sendOnChannel:(nonnull NSString*)channel message:(nullable NSData*)message {
  [self sendOnChannel:channel message:message binaryReply:nil];
}

- (void)sendOnChannel:(NSString*)channel
              message:(NSData* _Nullable)message
          binaryReply:(FlutterBinaryReply _Nullable)callback {
  FlutterPlatformMessageResponseHandle* response_handle = nullptr;
  if (callback) {
    struct Captures {
      FlutterBinaryReply reply;
    };
    auto captures = std::make_unique<Captures>();
    captures->reply = callback;
    auto message_reply = [](const uint8_t* data, size_t data_size, void* user_data) {
      auto captures = reinterpret_cast<Captures*>(user_data);
      NSData* reply_data = nil;
      if (data != nullptr && data_size > 0) {
        reply_data = [NSData dataWithBytes:static_cast<const void*>(data) length:data_size];
      }
      captures->reply(reply_data);
      delete captures;
    };

    FlutterEngineResult create_result = _embedderAPI.PlatformMessageCreateResponseHandle(
        _engine, message_reply, captures.get(), &response_handle);
    if (create_result != kSuccess) {
      NSLog(@"Failed to create a FlutterPlatformMessageResponseHandle (%d)", create_result);
      return;
    }
    captures.release();
  }

  FlutterPlatformMessage platformMessage = {
      .struct_size = sizeof(FlutterPlatformMessage),
      .channel = [channel UTF8String],
      .message = static_cast<const uint8_t*>(message.bytes),
      .message_size = message.length,
      .response_handle = response_handle,
  };

  FlutterEngineResult message_result = _embedderAPI.SendPlatformMessage(_engine, &platformMessage);
  if (message_result != kSuccess) {
    NSLog(@"Failed to send message to Flutter engine on channel '%@' (%d).", channel,
          message_result);
  }

  if (response_handle != nullptr) {
    FlutterEngineResult release_result =
        _embedderAPI.PlatformMessageReleaseResponseHandle(_engine, response_handle);
    if (release_result != kSuccess) {
      NSLog(@"Failed to release the response handle (%d).", release_result);
    };
  }
}

- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(nonnull NSString*)channel
                                          binaryMessageHandler:
                                              (nullable FlutterBinaryMessageHandler)handler {
  _currentMessengerConnection += 1;
  _messengerHandlers[channel] =
      [[FlutterEngineHandlerInfo alloc] initWithConnection:@(_currentMessengerConnection)
                                                   handler:[handler copy]];
  return _currentMessengerConnection;
}

- (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection {
  // Find the _messengerHandlers that has the required connection, and record its
  // channel.
  NSString* foundChannel = nil;
  for (NSString* key in [_messengerHandlers allKeys]) {
    FlutterEngineHandlerInfo* handlerInfo = [_messengerHandlers objectForKey:key];
    if ([handlerInfo.connection isEqual:@(connection)]) {
      foundChannel = key;
      break;
    }
  }
  if (foundChannel) {
    [_messengerHandlers removeObjectForKey:foundChannel];
  }
}

#pragma mark - FlutterPluginRegistry

- (id<FlutterPluginRegistrar>)registrarForPlugin:(NSString*)pluginName {
  id<FlutterPluginRegistrar> registrar = self.pluginRegistrars[pluginName];
  if (!registrar) {
    FlutterEngineRegistrar* registrarImpl =
        [[FlutterEngineRegistrar alloc] initWithPlugin:pluginName flutterEngine:self];
    self.pluginRegistrars[pluginName] = registrarImpl;
    registrar = registrarImpl;
  }
  return registrar;
}

- (nullable NSObject*)valuePublishedByPlugin:(NSString*)pluginName {
  return self.pluginRegistrars[pluginName].publishedValue;
}

#pragma mark - FlutterTextureRegistrar

- (int64_t)registerTexture:(id<FlutterTexture>)texture {
  return [_renderer registerTexture:texture];
}

- (BOOL)registerTextureWithID:(int64_t)textureId {
  return _embedderAPI.RegisterExternalTexture(_engine, textureId) == kSuccess;
}

- (void)textureFrameAvailable:(int64_t)textureID {
  [_renderer textureFrameAvailable:textureID];
}

- (BOOL)markTextureFrameAvailable:(int64_t)textureID {
  return _embedderAPI.MarkExternalTextureFrameAvailable(_engine, textureID) == kSuccess;
}

- (void)unregisterTexture:(int64_t)textureID {
  [_renderer unregisterTexture:textureID];
}

- (BOOL)unregisterTextureWithID:(int64_t)textureID {
  return _embedderAPI.UnregisterExternalTexture(_engine, textureID) == kSuccess;
}

#pragma mark - Task runner integration

- (void)runTaskOnEmbedder:(FlutterTask)task {
  if (_engine) {
    auto result = _embedderAPI.RunTask(_engine, &task);
    if (result != kSuccess) {
      NSLog(@"Could not post a task to the Flutter engine.");
    }
  }
}

- (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)targetTime {
  __weak FlutterEngine* weakSelf = self;
  auto worker = ^{
    [weakSelf runTaskOnEmbedder:task];
  };

  const auto engine_time = _embedderAPI.GetCurrentTime();
  if (targetTime <= engine_time) {
    dispatch_async(dispatch_get_main_queue(), worker);

  } else {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, targetTime - engine_time),
                   dispatch_get_main_queue(), worker);
  }
}

// Getter used by test harness, only exposed through the FlutterEngine(Test) category
- (flutter::FlutterCompositor*)macOSCompositor {
  return _macOSCompositor.get();
}

@end
