diff --git a/engine/src/flutter/examples/shell/sensor.sky b/engine/src/flutter/examples/shell/sensor.sky new file mode 100644 index 0000000000..80879a54dd --- /dev/null +++ b/engine/src/flutter/examples/shell/sensor.sky @@ -0,0 +1,38 @@ + +
Shake me.
diff --git a/engine/src/flutter/shell/BUILD.gn b/engine/src/flutter/shell/BUILD.gn index cb52c78263..061cffcafa 100644 --- a/engine/src/flutter/shell/BUILD.gn +++ b/engine/src/flutter/shell/BUILD.gn @@ -41,6 +41,8 @@ shared_library("sky_shell") { "ui/engine.h", "ui/input_event_converter.cc", "ui/input_event_converter.h", + "ui/internals.cc", + "ui/internals.h", "ui_delegate.cc", "ui_delegate.h", ] @@ -49,6 +51,7 @@ shared_library("sky_shell") { "//base", "//base:i18n", "//build/config/sanitizers:deps", + "//dart/runtime/bin:libdart_withcore", "//mojo/android:libsystem_java", "//mojo/common", "//mojo/edk/system", @@ -58,6 +61,7 @@ shared_library("sky_shell") { "//mojo/services/network/public/interfaces", "//skia", "//sky/engine", + "//sky/engine/tonic", "//sky/services/platform", "//sky/services/viewport", "//ui/gfx/geometry", @@ -83,6 +87,8 @@ android_library("java") { "//mojo/public/java:system", "//mojo/services/network/public/interfaces:interfaces_java", "//sky/services/oknet", + "//sky/services/sensors", + "//sky/services/sensors:interfaces_java", "//sky/services/viewport:viewport_java", ] } diff --git a/engine/src/flutter/shell/java_service_provider.cc b/engine/src/flutter/shell/java_service_provider.cc index 8973f2e2c1..4856a1b498 100644 --- a/engine/src/flutter/shell/java_service_provider.cc +++ b/engine/src/flutter/shell/java_service_provider.cc @@ -4,6 +4,7 @@ #include "sky/shell/java_service_provider.h" +#include "base/android/jni_android.h" #include "jni/JavaServiceProvider_jni.h" namespace sky { @@ -16,7 +17,8 @@ bool RegisterJavaServiceProvider(JNIEnv* env) { mojo::ScopedMessagePipeHandle CreateJavaServiceProvider() { JNIEnv* env = base::android::AttachCurrentThread(); return mojo::ScopedMessagePipeHandle( - mojo::MessagePipeHandle(Java_JavaServiceProvider_create(env))); + mojo::MessagePipeHandle(Java_JavaServiceProvider_create( + env, base::android::GetApplicationContext()))); } } // namespace shell diff --git a/engine/src/flutter/shell/org/domokit/sky/shell/JavaServiceProvider.java b/engine/src/flutter/shell/org/domokit/sky/shell/JavaServiceProvider.java index ad1b0b2695..05fefbe16e 100644 --- a/engine/src/flutter/shell/org/domokit/sky/shell/JavaServiceProvider.java +++ b/engine/src/flutter/shell/org/domokit/sky/shell/JavaServiceProvider.java @@ -4,6 +4,8 @@ package org.domokit.sky.shell; +import android.content.Context; + import org.chromium.base.CalledByNative; import org.chromium.base.JNINamespace; import org.chromium.mojo.system.Core; @@ -13,7 +15,9 @@ import org.chromium.mojo.system.Pair; import org.chromium.mojo.system.impl.CoreImpl; import org.chromium.mojom.mojo.NetworkService; import org.chromium.mojom.mojo.ServiceProvider; +import org.chromium.mojom.sensors.SensorService; import org.domokit.oknet.NetworkServiceImpl; +import org.domokit.sensors.SensorServiceImpl; /** * A class to intialize the network. @@ -21,19 +25,22 @@ import org.domokit.oknet.NetworkServiceImpl; @JNINamespace("sky::shell") public class JavaServiceProvider implements ServiceProvider { private Core mCore; + private Context mContext; @SuppressWarnings("unused") @CalledByNative - public static int create() { + public static int create(Context context) { Core core = CoreImpl.getInstance(); Pair messagePipe = core.createMessagePipe(null); - ServiceProvider.MANAGER.bind(new JavaServiceProvider(core), messagePipe.first); + ServiceProvider.MANAGER.bind(new JavaServiceProvider(core, context), messagePipe.first); return messagePipe.second.releaseNativeHandle(); } - public JavaServiceProvider(Core core) { + public JavaServiceProvider(Core core, Context context) { assert core != null; + assert context != null; mCore = core; + mContext = context; } @Override @@ -45,7 +52,10 @@ public class JavaServiceProvider implements ServiceProvider { @Override public void connectToService(String interfaceName, MessagePipeHandle pipe) { if (interfaceName.equals(NetworkService.MANAGER.getName())) { - NetworkService.MANAGER.bind(new NetworkServiceImpl(mCore), pipe); + new NetworkServiceImpl(mContext, mCore, pipe); + return; + } else if (interfaceName.equals(SensorService.MANAGER.getName())) { + new SensorServiceImpl(mContext, mCore, pipe); return; } pipe.close(); diff --git a/engine/src/flutter/shell/org/domokit/sky/shell/SkyApplication.java b/engine/src/flutter/shell/org/domokit/sky/shell/SkyApplication.java index ba53c6d721..0faf0c5d78 100644 --- a/engine/src/flutter/shell/org/domokit/sky/shell/SkyApplication.java +++ b/engine/src/flutter/shell/org/domokit/sky/shell/SkyApplication.java @@ -18,7 +18,7 @@ import org.chromium.base.library_loader.ProcessInitException; * state and initializations. */ public class SkyApplication extends BaseChromiumApplication { - private static final String TAG = "SkyShellApplication"; + private static final String TAG = "SkyApplication"; private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "sky_shell"; private static final String[] SKY_MANDATORY_PAKS = { "icudtl.dat", diff --git a/engine/src/flutter/shell/ui/engine.cc b/engine/src/flutter/shell/ui/engine.cc index 5cc3632ac6..705fc224b8 100644 --- a/engine/src/flutter/shell/ui/engine.cc +++ b/engine/src/flutter/shell/ui/engine.cc @@ -14,6 +14,7 @@ #include "sky/services/platform/platform_impl.h" #include "sky/shell/ui/animator.h" #include "sky/shell/ui/input_event_converter.h" +#include "sky/shell/ui/internals.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -48,10 +49,10 @@ base::WeakPtr Engine::GetWeakPtr() { } void Engine::Init(mojo::ScopedMessagePipeHandle service_provider_handle) { - mojo::ServiceProviderPtr service_provider = + service_provider_ = mojo::MakeProxy(service_provider_handle.Pass()); mojo::NetworkServicePtr network_service; - mojo::ConnectToService(service_provider.get(), &network_service); + mojo::ConnectToService(service_provider_.get(), &network_service); platform_impl_.reset(new PlatformImpl(network_service.Pass())); blink::initialize(platform_impl_.get()); @@ -141,6 +142,11 @@ void Engine::scheduleVisualUpdate() { animator_->RequestFrame(); } +void Engine::didCreateIsolate(blink::WebLocalFrame* frame, + Dart_Isolate isolate) { + Internals::Create(isolate, service_provider_.Pass()); +} + blink::ServiceProvider* Engine::services() { return this; } diff --git a/engine/src/flutter/shell/ui/engine.h b/engine/src/flutter/shell/ui/engine.h index 1e7827cf13..9198ce1ca7 100644 --- a/engine/src/flutter/shell/ui/engine.h +++ b/engine/src/flutter/shell/ui/engine.h @@ -11,6 +11,7 @@ #include "base/single_thread_task_runner.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/core.h" +#include "mojo/public/interfaces/application/service_provider.mojom.h" #include "mojo/services/navigation/public/interfaces/navigation.mojom.h" #include "skia/ext/refptr.h" #include "sky/engine/public/platform/ServiceProvider.h" @@ -65,6 +66,8 @@ class Engine : public UIDelegate, void scheduleVisualUpdate() override; blink::WebScreenInfo screenInfo() override; blink::ServiceProvider* services() override; + void didCreateIsolate(blink::WebLocalFrame* frame, + Dart_Isolate isolate) override; // Services methods: mojo::NavigatorHost* NavigatorHost() override; @@ -77,6 +80,7 @@ class Engine : public UIDelegate, void UpdateWebViewSize(); + mojo::ServiceProviderPtr service_provider_; scoped_ptr platform_impl_; scoped_ptr animator_; blink::WebView* web_view_; diff --git a/engine/src/flutter/shell/ui/internals.cc b/engine/src/flutter/shell/ui/internals.cc new file mode 100644 index 0000000000..b32a81d18f --- /dev/null +++ b/engine/src/flutter/shell/ui/internals.cc @@ -0,0 +1,84 @@ +// Copyright 2014 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. + +#include "sky/engine/config.h" +#include "sky/shell/ui/internals.h" + +#include "mojo/public/cpp/application/connect.h" +#include "mojo/public/cpp/bindings/array.h" +#include "sky/engine/tonic/dart_builtin.h" +#include "sky/engine/tonic/dart_converter.h" +#include "sky/engine/tonic/dart_error.h" +#include "sky/engine/tonic/dart_state.h" + +using namespace blink; + +namespace sky { +namespace shell { +namespace { + +int kInternalsKey = 0; + +Internals* GetInternals() { + DartState* state = DartState::Current(); + return static_cast(state->GetUserData(&kInternalsKey)); +} + +void TakeServicesProvidedByEmbedder(Dart_NativeArguments args) { + Dart_SetIntegerReturnValue( + args, GetInternals()->TakeServicesProvidedByEmbedder().value()); +} + +const DartBuiltin::Natives kNativeFunctions[] = { + {"takeServicesProvidedByEmbedder", TakeServicesProvidedByEmbedder, 0}, +}; + +const DartBuiltin& GetBuiltin() { + static DartBuiltin& builtin = *new DartBuiltin(kNativeFunctions, + arraysize(kNativeFunctions)); + return builtin; +} + +Dart_NativeFunction Resolver(Dart_Handle name, + int argument_count, + bool* auto_setup_scope) { + return GetBuiltin().Resolver(name, argument_count, auto_setup_scope); +} + +const uint8_t* Symbolizer(Dart_NativeFunction native_function) { + return GetBuiltin().Symbolizer(native_function); +} + +const char kLibraryName[] = "dart:sky.internals"; +const char kLibrarySource[] = R"DART( +int takeServicesProvidedByEmbedder() native "takeServicesProvidedByEmbedder"; +)DART"; + +} // namespace + +void Internals::Create(Dart_Isolate isolate, + mojo::ServiceProviderPtr service_provider) { + DartState* state = DartState::From(isolate); + state->SetUserData(&kInternalsKey, new Internals(service_provider.Pass())); + Dart_Handle library = + Dart_LoadLibrary(Dart_NewStringFromCString(kLibraryName), + Dart_NewStringFromCString(kLibrarySource), 0, 0); + CHECK(!LogIfError(library)); + CHECK(!LogIfError(Dart_FinalizeLoading(true))); + CHECK(!LogIfError(Dart_SetNativeResolver(library, Resolver, Symbolizer))); +} + +Internals::Internals(mojo::ServiceProviderPtr service_provider) + : service_provider_(service_provider.Pass()) { +} + +Internals::~Internals() { +} + +mojo::Handle Internals::TakeServicesProvidedByEmbedder() { + return service_provider_.PassMessagePipe().release(); +} + +} // namespace shell +} // namespace sky diff --git a/engine/src/flutter/shell/ui/internals.h b/engine/src/flutter/shell/ui/internals.h new file mode 100644 index 0000000000..c0efac913a --- /dev/null +++ b/engine/src/flutter/shell/ui/internals.h @@ -0,0 +1,35 @@ +// Copyright 2014 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. + +#ifndef SKY_SHELL_UI_INTERNALS_H_ +#define SKY_SHELL_UI_INTERNALS_H_ + +#include "base/supports_user_data.h" +#include "dart/runtime/include/dart_api.h" +#include "mojo/public/interfaces/application/service_provider.mojom.h" + +namespace sky { +namespace shell { + +class Internals : public base::SupportsUserData::Data { + public: + virtual ~Internals(); + + static void Create(Dart_Isolate isolate, + mojo::ServiceProviderPtr service_provider); + + mojo::Handle TakeServicesProvidedByEmbedder(); + + private: + explicit Internals(mojo::ServiceProviderPtr service_provider); + + mojo::ServiceProviderPtr service_provider_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(Internals); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_UI_INTERNALS_H_