提交 b8c1fe7e 编写于 作者: J John McCutchan 提交者: GitHub

Fix Android keyboard in hot mode (#2944)

上级 26f89708
......@@ -404,7 +404,8 @@ public class FlutterView extends SurfaceView
Pair<SkyEngine.Proxy, InterfaceRequest<SkyEngine>> engine =
SkyEngine.MANAGER.getInterfaceRequest(core);
mSkyEngine = engine.first;
mNativePlatformView = nativeAttach(engine.second.passHandle().releaseNativeHandle());
mNativePlatformView =
nativeAttach(engine.second.passHandle().releaseNativeHandle(), this);
}
private void preRun() {
......@@ -472,13 +473,36 @@ public class FlutterView extends SurfaceView
postRun();
}
public void runFromFile(String main, String packageRoot) {
preRun();
mSkyEngine.runFromFile(main, packageRoot, "");
postRun();
public void runFromSource(final String main,
final String packages,
final String assetsDirectory) {
Runnable runnable = new Runnable() {
public void run() {
preRun();
mSkyEngine.runFromFile(main,
packages,
assetsDirectory);
postRun();
synchronized (this) {
notify();
}
}
};
try {
synchronized (runnable) {
// Post to the Android UI thread and wait for the response.
post(runnable);
runnable.wait();
}
} catch (InterruptedException e) {
Log.e(TAG, "Thread got interrupted waiting for " +
"RunFromSourceRunnable to finish", e);
}
}
private static native long nativeAttach(int inputObserverHandle);
private static native long nativeAttach(int skyEngineHandle,
FlutterView view);
private static native int nativeGetObservatoryPort();
private static native void nativeDetach(long nativePlatformViewAndroid);
private static native void nativeSurfaceCreated(long nativePlatformViewAndroid,
......
......@@ -136,18 +136,9 @@ public class SkyActivity extends Activity {
public boolean loadIntent(Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_RUN.equals(action)) {
String file = intent.getStringExtra("file");
String packageRoot = intent.getStringExtra("packages");
String route = intent.getStringExtra("route");
// TODO(johnmccutchan): Remove the need for the runFromFile
// intent by launching an empty application at startup and
// reloading from within that.
if ((file != null) && (packageRoot != null)) {
mView.runFromFile(file, packageRoot);
} else {
mView.runFromBundle(intent.getDataString(),
intent.getStringExtra("snapshot"));
}
mView.runFromBundle(intent.getDataString(),
intent.getStringExtra("snapshot"));
if (route != null)
mView.pushRoute(route);
return true;
......
......@@ -11,6 +11,7 @@
#include <utility>
#include "base/android/jni_android.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/trace_event/trace_event.h"
......@@ -343,10 +344,17 @@ class AndroidGLContext {
FTL_DISALLOW_COPY_AND_ASSIGN(AndroidGLContext);
};
static jlong Attach(JNIEnv* env, jclass clazz, jint skyEngineHandle) {
static jlong Attach(JNIEnv* env,
jclass clazz,
jint skyEngineHandle,
jobject flutterView) {
PlatformViewAndroid* view = new PlatformViewAndroid();
view->ConnectToEngine(mojo::InterfaceRequest<SkyEngine>(
mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(skyEngineHandle))));
// Create a weak reference to the flutterView Java object so that we can make
// calls into it later.
view->set_flutter_view(JavaObjectWeakGlobalRef(env, flutterView));
return reinterpret_cast<jlong>(view);
}
......@@ -359,7 +367,8 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
}
PlatformViewAndroid::PlatformViewAndroid() : weak_factory_(this) {
PlatformViewAndroid::PlatformViewAndroid()
: weak_factory_(this) {
// If this is the first PlatformView, then intiialize EGL and set up
// the resource context.
if (g_display == EGL_NO_DISPLAY)
......@@ -435,5 +444,49 @@ void PlatformViewAndroid::Resize(const SkISize& size) {
context_->Resize(size);
}
void PlatformViewAndroid::RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) {
FTL_CHECK(base::android::IsVMInitialized());
JNIEnv* env = base::android::AttachCurrentThread();
FTL_CHECK(env);
{
base::android::ScopedJavaLocalRef<jobject> local_flutter_view =
flutter_view_.get(env);
if (local_flutter_view.is_null()) {
// Collected.
return;
}
// Grab the class of the flutter view.
jclass flutter_view_class = env->GetObjectClass(local_flutter_view.obj());
FTL_CHECK(flutter_view_class);
// Grab the runFromSource method id.
jmethodID run_from_source_method_id = env->GetMethodID(
flutter_view_class,
"runFromSource",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
FTL_CHECK(run_from_source_method_id);
// Invoke runFromSource on the Android UI thread.
jstring java_main = env->NewStringUTF(main.c_str());
FTL_CHECK(java_main);
jstring java_packages = env->NewStringUTF(packages.c_str());
FTL_CHECK(java_packages);
jstring java_assets_directory = env->NewStringUTF(assets_directory.c_str());
FTL_CHECK(java_assets_directory);
env->CallVoidMethod(local_flutter_view.obj(),
run_from_source_method_id,
java_main,
java_packages,
java_assets_directory);
}
// Detaching from the VM deletes any stray local references.
base::android::DetachFromVM();
}
} // namespace shell
} // namespace sky
......@@ -6,6 +6,7 @@
#define SKY_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "lib/ftl/memory/weak_ptr.h"
#include "flutter/sky/shell/platform_view.h"
......@@ -52,9 +53,18 @@ class PlatformViewAndroid : public PlatformView {
// sky::shell::PlatformView override
virtual void Resize(const SkISize& size);
virtual void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory);
void set_flutter_view(const JavaObjectWeakGlobalRef& flutter_view) {
flutter_view_ = flutter_view;
}
private:
std::unique_ptr<AndroidGLContext> context_;
ftl::WeakPtrFactory<PlatformViewAndroid> weak_factory_;
JavaObjectWeakGlobalRef flutter_view_;
FTL_DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroid);
};
......
......@@ -35,6 +35,10 @@ class PlatformViewIOS : public PlatformView {
bool SwapBuffers() override;
void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) override;
private:
std::unique_ptr<IOSGLContext> context_;
ftl::WeakPtrFactory<PlatformViewIOS> weak_factory_;
......
......@@ -296,5 +296,13 @@ bool PlatformViewIOS::SwapBuffers() {
return context_ != nullptr ? context_->PresentRenderBuffer() : false;
}
void PlatformViewIOS::RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) {
// TODO(johnmccutchan): Call to the iOS UI thread so that services work
// properly like we do in PlatformViewAndroid.
engine().RunFromSource(main, packages, assets_directory);
}
} // namespace shell
} // namespace sky
......@@ -31,6 +31,10 @@ class PlatformViewMac : public PlatformView {
bool SwapBuffers() override;
void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) override;
private:
base::scoped_nsobject<NSOpenGLView> opengl_view_;
base::scoped_nsobject<NSOpenGLContext> resource_loading_context_;
......
......@@ -74,5 +74,13 @@ bool PlatformViewMac::IsValid() const {
return true;
}
void PlatformViewMac::RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) {
// TODO(johnmccutchan): Call to the Mac UI thread so that services work
// properly like we do in PlatformViewAndroid.
engine().RunFromSource(main, packages, assets_directory);
}
} // namespace shell
} // namespace sky
......@@ -69,6 +69,10 @@ class PlatformView {
Engine& engine() { return *engine_; }
virtual void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) = 0;
protected:
Config config_;
SurfaceConfig surface_config_;
......
......@@ -75,17 +75,6 @@ static bool ErrorUnknownView(const char** json_object, const char* view_id) {
return false;
}
static bool ErrorIsolateSpawn(const char** json_object, const char* view_id) {
const intptr_t kInvalidParams = -32602;
std::stringstream response;
response << "{\"code\":" << std::to_string(kInvalidParams) << ",";
response << "\"message\":\"Invalid params\",";
response << "\"data\": {\"details\": \"view " << view_id;
response << " did not spawn an isolate\"}}";
*json_object = strdup(response.str().c_str());
return false;
}
static void AppendIsolateRef(std::stringstream* stream,
int64_t main_port,
const std::string name) {
......@@ -99,8 +88,12 @@ static void AppendFlutterView(std::stringstream* stream,
int64_t isolate_id,
const std::string isolate_name) {
*stream << "{\"type\":\"FlutterView\", \"id\": \"" << kViewIdPrefx << "0x"
<< std::hex << view_id << std::dec << "\"," << "\"isolate\":";
AppendIsolateRef(stream, isolate_id, isolate_name);
<< std::hex << view_id << std::dec;
if (isolate_id != ILLEGAL_PORT) {
// Append the isolate (if it exists).
*stream << "\"," << "\"isolate\":";
AppendIsolateRef(stream, isolate_id, isolate_name);
}
*stream << "}";
}
......@@ -168,9 +161,6 @@ bool PlatformViewServiceProtocol::RunInView(const char* method,
if (!view_existed) {
// If the view did not exist this request has definitely failed.
return ErrorUnknownView(json_object, view_id);
} else if (main_port == ILLEGAL_PORT) {
// We did not create an isolate.
return ErrorIsolateSpawn(json_object, view_id);
} else {
// The view existed and the isolate was created. Success.
std::stringstream response;
......
......@@ -309,7 +309,7 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
PlatformView* view = it->get();
if (reinterpret_cast<uintptr_t>(view) == view_id) {
*view_existed = true;
view->engine().RunFromSource(main, packages, assets_directory);
view->RunFromSource(main, packages, assets_directory);
*dart_isolate_id = view->engine().GetUIIsolateMainPort();
*isolate_name = view->engine().GetUIIsolateName();
break;
......
......@@ -33,5 +33,10 @@ bool PlatformViewTest::SwapBuffers() {
return false;
}
void PlatformViewTest::RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) {
}
} // namespace shell
} // namespace sky
......@@ -30,6 +30,10 @@ class PlatformViewTest : public PlatformView {
bool SwapBuffers() override;
void RunFromSource(const std::string& main,
const std::string& packages,
const std::string& assets_directory) override;
private:
ftl::WeakPtrFactory<PlatformViewTest> weak_factory_;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册