Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reland "Updated background execution implementation for Android" #5954

Merged
merged 3 commits into from
Aug 7, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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 ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,8 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/Platfor
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java
FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterCallbackInformation.java
FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterRunArguments.java
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterCallbackCache.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterCallbackCache.mm
Expand Down
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