Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4aa0ace
Background execution implementation for iOS
bkonyi Jun 14, 2018
59f4c05
Updated licenses + removed extra line of code
bkonyi Jun 15, 2018
2f3e0d8
Addressed some comments
bkonyi Jun 20, 2018
ddbd5f3
Added tests for PluginUtilities and updated function params.
bkonyi Jun 20, 2018
b15e35c
Updated documentation for getClosureByName
bkonyi Jun 20, 2018
9806222
Updated docs for plugins.dart and changed ArgumentErrors to asserts
bkonyi Jun 25, 2018
3341e83
Removed unused method and s/`null`/null/g
bkonyi Jun 25, 2018
8373f88
Updated callback lookup/passing to use handles instead of human readable
bkonyi Jul 10, 2018
f4d23c2
Added CallbackHandle wrapper for handles returned from
bkonyi Jul 11, 2018
87d3d80
Updated licenses
bkonyi Jul 11, 2018
14e7aca
Fixed analyzer complaints
bkonyi Jul 11, 2018
af25c66
Merge branch 'master' into headless_plugin
bkonyi Jul 11, 2018
2ff7690
Update licenses_flutter
bkonyi Jul 11, 2018
48261fd
Update licenses_flutter
bkonyi Jul 11, 2018
abcabee
Updated docs for plugins.dart
bkonyi Jul 11, 2018
2ec1ef4
Added caching in PluginUtilities
bkonyi Jul 11, 2018
8cc4394
Fix analyzer issues
bkonyi Jul 12, 2018
81492d6
Addressed comments
bkonyi Jul 12, 2018
514df89
Update analysis_options.yaml
bkonyi Jul 12, 2018
c6a955d
Added private factory to make analyzer happy
bkonyi Jul 12, 2018
2ba3d6b
Updated background execution implementation for Android (#5640)
bkonyi Aug 3, 2018
8e9fe0f
Merge branch 'master' into headless_plugin_merge
bkonyi Aug 3, 2018
3c9adb9
Merge branch 'headless_plugin_merge'
bkonyi Aug 4, 2018
2c010c2
Merge branch 'master' into headless_plugin
bkonyi Aug 4, 2018
16236f2
Fixed merge errors and formatting
bkonyi Aug 6, 2018
f0daa8e
More formatting
bkonyi Aug 6, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,10 @@ java_library("flutter_shell_java") {
"io/flutter/util/PathUtils.java",
"io/flutter/util/Preconditions.java",
"io/flutter/view/AccessibilityBridge.java",
"io/flutter/view/FlutterCallbackInformation.java",
"io/flutter/view/FlutterMain.java",
"io/flutter/view/FlutterNativeView.java",
"io/flutter/view/FlutterRunArguments.java",
"io/flutter/view/FlutterView.java",
"io/flutter/view/ResourceCleaner.java",
"io/flutter/view/ResourceExtractor.java",
Expand Down
78 changes: 55 additions & 23 deletions shell/platform/android/android_shell_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,51 @@ namespace shell {

AndroidShellHolder::AndroidShellHolder(
blink::Settings settings,
fml::jni::JavaObjectWeakGlobalRef java_object)
fml::jni::JavaObjectWeakGlobalRef java_object,
bool is_background_view)
: settings_(std::move(settings)), java_object_(java_object) {
static size_t shell_count = 1;
auto thread_label = std::to_string(shell_count++);

FML_CHECK(pthread_key_create(&thread_destruct_key_, ThreadDestructCallback) ==
0);

thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
ThreadHost::Type::IO};
if (is_background_view) {
thread_host_ = {thread_label, ThreadHost::Type::UI};
} else {
thread_host_ = {thread_label, ThreadHost::Type::UI | ThreadHost::Type::GPU |
ThreadHost::Type::IO};
}

// Detach from JNI when the UI and GPU threads exit.
auto jni_exit_task([key = thread_destruct_key_]() {
FML_CHECK(pthread_setspecific(key, reinterpret_cast<void*>(1)) == 0);
});
thread_host_.ui_thread->GetTaskRunner()->PostTask(jni_exit_task);
thread_host_.gpu_thread->GetTaskRunner()->PostTask(jni_exit_task);
if (!is_background_view) {
thread_host_.gpu_thread->GetTaskRunner()->PostTask(jni_exit_task);
}

fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
Shell::CreateCallback<PlatformView> on_create_platform_view =
[java_object, &weak_platform_view](Shell& shell) {
auto platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object, // java object handle for JNI interop
shell.GetSettings()
.enable_software_rendering // use software rendering
);
[is_background_view, java_object, &weak_platform_view](Shell& shell) {
std::unique_ptr<PlatformViewAndroid> platform_view_android;
if (is_background_view) {
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object // java object handle for JNI interop
);

} else {
platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object, // java object handle for JNI interop
shell.GetSettings()
.enable_software_rendering // use software rendering
);
}
weak_platform_view = platform_view_android->GetWeakPtr();
return platform_view_android;
};
Expand All @@ -62,13 +79,26 @@ AndroidShellHolder::AndroidShellHolder(
// The current thread will be used as the platform thread. Ensure that the
// message loop is initialized.
fml::MessageLoop::EnsureInitializedForCurrentThread();

blink::TaskRunners task_runners(
thread_label, // label
fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform
thread_host_.gpu_thread->GetTaskRunner(), // gpu
thread_host_.ui_thread->GetTaskRunner(), // ui
thread_host_.io_thread->GetTaskRunner() // io
fml::RefPtr<fml::TaskRunner> gpu_runner;
fml::RefPtr<fml::TaskRunner> ui_runner;
fml::RefPtr<fml::TaskRunner> io_runner;
fml::RefPtr<fml::TaskRunner> platform_runner =
fml::MessageLoop::GetCurrent().GetTaskRunner();
if (is_background_view) {
auto single_task_runner = thread_host_.ui_thread->GetTaskRunner();
gpu_runner = single_task_runner;
ui_runner = single_task_runner;
io_runner = single_task_runner;
} else {
gpu_runner = thread_host_.gpu_thread->GetTaskRunner();
ui_runner = thread_host_.ui_thread->GetTaskRunner();
io_runner = thread_host_.io_thread->GetTaskRunner();
}
blink::TaskRunners task_runners(thread_label, // label
platform_runner, // platform
gpu_runner, // gpu
ui_runner, // ui
io_runner // io
);

shell_ =
Expand Down Expand Up @@ -131,10 +161,12 @@ void AndroidShellHolder::Launch(RunConfiguration config) {
fml::MakeCopyable([engine = shell_->GetEngine(), //
config = std::move(config) //
]() mutable {
if (engine) {
if (!engine->Run(std::move(config))) {
FML_LOG(ERROR) << "Could not launch engine in configuration.";
}
FML_LOG(INFO) << "Attempting to launch engine configuration...";
if (!engine || !engine->Run(std::move(config))) {
FML_LOG(ERROR) << "Could not launch engine in configuration.";
} else {
FML_LOG(INFO) << "Isolate for engine configuration successfully "
"started and run.";
}
}));
}
Expand Down
3 changes: 2 additions & 1 deletion shell/platform/android/android_shell_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ namespace shell {
class AndroidShellHolder {
public:
AndroidShellHolder(blink::Settings settings,
fml::jni::JavaObjectWeakGlobalRef java_object);
fml::jni::JavaObjectWeakGlobalRef java_object,
bool is_background_view);

~AndroidShellHolder();

Expand Down
24 changes: 10 additions & 14 deletions shell/platform/android/io/flutter/app/FlutterActivityDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.flutter.util.Preconditions;
import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterNativeView;
import io.flutter.view.FlutterRunArguments;
import io.flutter.view.FlutterView;

import java.util.ArrayList;
Expand Down Expand Up @@ -162,19 +163,16 @@ public void onCreate(Bundle savedInstanceState) {
}
}

// When an activity is created for the first time, we direct the
// FlutterView to re-use a pre-existing Isolate rather than create a new
// one. This is so that an Isolate coming in from the ViewFactory is
// used.
final boolean reuseIsolate = true;

if (loadIntent(activity.getIntent(), reuseIsolate)) {
if (loadIntent(activity.getIntent())) {
return;
}
if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
String appBundlePath = FlutterMain.findAppBundlePath(activity.getApplicationContext());
if (appBundlePath != null) {
flutterView.runFromBundle(appBundlePath, null, "main", reuseIsolate);
FlutterRunArguments arguments = new FlutterRunArguments();
arguments.bundlePath = appBundlePath;
arguments.entrypoint = "main";
flutterView.runFromBundle(arguments);
}
}
}
Expand Down Expand Up @@ -325,11 +323,6 @@ private static String[] getArgsFromIntent(Intent intent) {
}

private boolean loadIntent(Intent intent) {
final boolean reuseIsolate = false;
return loadIntent(intent, reuseIsolate);
}

private boolean loadIntent(Intent intent, boolean reuseIsolate) {
String action = intent.getAction();
if (Intent.ACTION_RUN.equals(action)) {
String route = intent.getStringExtra("route");
Expand All @@ -343,7 +336,10 @@ private boolean loadIntent(Intent intent, boolean reuseIsolate) {
flutterView.setInitialRoute(route);
}
if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
flutterView.runFromBundle(appBundlePath, null, "main", reuseIsolate);
FlutterRunArguments args = new FlutterRunArguments();
args.bundlePath = appBundlePath;
args.entrypoint = "main";
flutterView.runFromBundle(args);
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.view;

/**
* A class representing information for a callback registered using
* `PluginUtilities` from `dart:ui`.
*/
public final class FlutterCallbackInformation {
final public String callbackName;
final public String callbackClassName;
final public String callbackLibraryPath;

/**
* Get callback information for a given handle.
* @param handle the handle for the callback, generated by
* `PluginUtilities.getCallbackHandle` in `dart:ui`.
* @return an instance of FlutterCallbackInformation for the provided handle.
*/
public static FlutterCallbackInformation lookupCallbackInformation(long handle) {
return nativeLookupCallbackInformation(handle);
}

private FlutterCallbackInformation(String callbackName,
String callbackClassName, String callbackLibraryPath) {
this.callbackName = callbackName;
this.callbackClassName = callbackClassName;
this.callbackLibraryPath = callbackLibraryPath;
}

private static native FlutterCallbackInformation nativeLookupCallbackInformation(long handle);
}
Loading