Chinmay Garde 0d6ff1669c
Shut down and restart the Dart VM as needed. (#7832)
The shell was already designed to cleanly shut down the VM but it couldnt
earlier as |Dart_Initialize| could never be called after a |Dart_Cleanup|. This
meant that shutting down an engine instance could not shut down the VM to save
memory because newly created engines in the process after that point couldn't
restart the VM. There can only be one VM running in a process at a time.

This patch separate the previous DartVM object into one that references a
running instance of the DartVM and a set of immutable dependencies that
components can reference even as the VM is shutting down.

Unit tests have been added to assert that non-overlapping engine launches use
difference VM instances.
2019-02-15 14:16:17 -08:00

180 lines
5.7 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.
#ifndef SHELL_COMMON_ENGINE_H_
#define SHELL_COMMON_ENGINE_H_
#include <memory>
#include <string>
#include "flutter/assets/asset_manager.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/lib/ui/semantics/custom_accessibility_action.h"
#include "flutter/lib/ui/semantics/semantics_node.h"
#include "flutter/lib/ui/snapshot_delegate.h"
#include "flutter/lib/ui/text/font_collection.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/runtime_controller.h"
#include "flutter/runtime/runtime_delegate.h"
#include "flutter/shell/common/animator.h"
#include "flutter/shell/common/io_manager.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/run_configuration.h"
#include "third_party/skia/include/core/SkPicture.h"
namespace shell {
class Engine final : public blink::RuntimeDelegate {
public:
// Used by Engine::Run
enum class RunStatus {
Success, // Successful call to Run()
FailureAlreadyRunning, // Isolate was already running; may not be
// considered a failure by callers
Failure, // Isolate could not be started or other unspecified failure
};
class Delegate {
public:
virtual void OnEngineUpdateSemantics(
blink::SemanticsNodeUpdates update,
blink::CustomAccessibilityActionUpdates actions) = 0;
virtual void OnEngineHandlePlatformMessage(
fml::RefPtr<blink::PlatformMessage> message) = 0;
virtual void OnPreEngineRestart() = 0;
virtual void UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) = 0;
};
Engine(Delegate& delegate,
blink::DartVM& vm,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
blink::TaskRunners task_runners,
blink::Settings settings,
std::unique_ptr<Animator> animator,
fml::WeakPtr<blink::SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<blink::IOManager> io_manager);
~Engine() override;
float GetDisplayRefreshRate() const;
fml::WeakPtr<Engine> GetWeakPtr() const;
FML_WARN_UNUSED_RESULT
RunStatus Run(RunConfiguration configuration);
// Used to "cold reload" a running application where the shell (along with the
// platform view and its rasterizer bindings) remains the same but the root
// isolate is torn down and restarted with the new configuration. Only used in
// the development workflow.
FML_WARN_UNUSED_RESULT
bool Restart(RunConfiguration configuration);
bool UpdateAssetManager(std::shared_ptr<blink::AssetManager> asset_manager);
void BeginFrame(fml::TimePoint frame_time);
void NotifyIdle(int64_t deadline);
Dart_Port GetUIIsolateMainPort();
std::string GetUIIsolateName();
bool UIIsolateHasLivePorts();
tonic::DartErrorHandleType GetUIIsolateLastError();
std::pair<bool, uint32_t> GetUIIsolateReturnCode();
void OnOutputSurfaceCreated();
void OnOutputSurfaceDestroyed();
void SetViewportMetrics(const blink::ViewportMetrics& metrics);
void DispatchPlatformMessage(fml::RefPtr<blink::PlatformMessage> message);
void DispatchPointerDataPacket(const blink::PointerDataPacket& packet,
uint64_t trace_flow_id);
void DispatchSemanticsAction(int id,
blink::SemanticsAction action,
std::vector<uint8_t> args);
void SetSemanticsEnabled(bool enabled);
void SetAccessibilityFeatures(int32_t flags);
void ScheduleFrame(bool regenerate_layer_tree = true) override;
// |blink::RuntimeDelegate|
blink::FontCollection& GetFontCollection() override;
private:
Engine::Delegate& delegate_;
const blink::Settings settings_;
std::unique_ptr<Animator> animator_;
std::unique_ptr<blink::RuntimeController> runtime_controller_;
std::string initial_route_;
blink::ViewportMetrics viewport_metrics_;
std::shared_ptr<blink::AssetManager> asset_manager_;
bool activity_running_;
bool have_surface_;
blink::FontCollection font_collection_;
fml::WeakPtrFactory<Engine> weak_factory_;
// |blink::RuntimeDelegate|
std::string DefaultRouteName() override;
// |blink::RuntimeDelegate|
void Render(std::unique_ptr<flow::LayerTree> layer_tree) override;
// |blink::RuntimeDelegate|
void UpdateSemantics(
blink::SemanticsNodeUpdates update,
blink::CustomAccessibilityActionUpdates actions) override;
// |blink::RuntimeDelegate|
void HandlePlatformMessage(
fml::RefPtr<blink::PlatformMessage> message) override;
// |blink::RuntimeDelegate|
void UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) override;
void StopAnimator();
void StartAnimatorIfPossible();
bool HandleLifecyclePlatformMessage(blink::PlatformMessage* message);
bool HandleNavigationPlatformMessage(
fml::RefPtr<blink::PlatformMessage> message);
bool HandleLocalizationPlatformMessage(blink::PlatformMessage* message);
void HandleSettingsPlatformMessage(blink::PlatformMessage* message);
void HandleAssetPlatformMessage(fml::RefPtr<blink::PlatformMessage> message);
bool GetAssetAsBuffer(const std::string& name, std::vector<uint8_t>* data);
RunStatus PrepareAndLaunchIsolate(RunConfiguration configuration);
FML_DISALLOW_COPY_AND_ASSIGN(Engine);
};
} // namespace shell
#endif // SHELL_COMMON_ENGINE_H_