mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Connect Sky and Ganesh in SkyShell
This CL contains enough plumbing for Sky to render content to the screen using Ganesh in SkyShell. We're still missing the ability to load data off the network. R=eseidel@chromium.org, ojan@chromium.org Review URL: https://codereview.chromium.org/936883002
This commit is contained in:
parent
3d8ffb7f52
commit
d86eedd1aa
@ -15,8 +15,9 @@ group("shell") {
|
||||
|
||||
generate_jni("jni_headers") {
|
||||
sources = [
|
||||
"apk/src/org/domokit/sky/shell/JavaServiceProvider.java",
|
||||
"apk/src/org/domokit/sky/shell/SkyMain.java",
|
||||
"apk/src/org/domokit/sky/shell/SkyView.java",
|
||||
"apk/src/org/domokit/sky/shell/PlatformView.java",
|
||||
]
|
||||
jni_package = "sky/shell"
|
||||
}
|
||||
@ -31,13 +32,17 @@ shared_library("sky_shell") {
|
||||
"gpu/rasterizer.h",
|
||||
"gpu_delegate.cc",
|
||||
"gpu_delegate.h",
|
||||
"java_service_provider.cc",
|
||||
"java_service_provider.h",
|
||||
"library_loader.cc",
|
||||
"platform_view.cc",
|
||||
"platform_view.h",
|
||||
"shell.cc",
|
||||
"shell.h",
|
||||
"sky_main.cc",
|
||||
"sky_main.h",
|
||||
"sky_view.cc",
|
||||
"sky_view.h",
|
||||
"ui/animator.cc",
|
||||
"ui/animator.h",
|
||||
"ui/engine.cc",
|
||||
"ui/engine.h",
|
||||
"ui/platform_impl.cc",
|
||||
@ -50,7 +55,12 @@ shared_library("sky_shell") {
|
||||
"//base",
|
||||
"//base:i18n",
|
||||
"//build/config/sanitizers:deps",
|
||||
"//mojo/android:libsystem_java",
|
||||
"//mojo/common",
|
||||
"//mojo/edk/system",
|
||||
"//mojo/public/cpp/application",
|
||||
"//mojo/public/interfaces/application",
|
||||
"//mojo/services/network/public/interfaces",
|
||||
"//skia",
|
||||
"//sky/engine",
|
||||
"//ui/gfx/geometry",
|
||||
@ -61,34 +71,54 @@ shared_library("sky_shell") {
|
||||
|
||||
android_library("java") {
|
||||
java_files = [
|
||||
"apk/src/org/domokit/sky/shell/JavaServiceProvider.java",
|
||||
"apk/src/org/domokit/sky/shell/PlatformView.java",
|
||||
"apk/src/org/domokit/sky/shell/SkyMain.java",
|
||||
"apk/src/org/domokit/sky/shell/SkyShellActivity.java",
|
||||
"apk/src/org/domokit/sky/shell/SkyShellApplication.java",
|
||||
"apk/src/org/domokit/sky/shell/SkyView.java",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base:base_java",
|
||||
"//mojo/android:system_java",
|
||||
"//mojo/public/interfaces/application:application_java",
|
||||
"//mojo/public/java:bindings",
|
||||
"//mojo/public/java:system",
|
||||
"//mojo/services/network/public/interfaces:interfaces_java",
|
||||
]
|
||||
}
|
||||
|
||||
sky_shell_assets_dir = "$root_build_dir/sky_shell/assets"
|
||||
|
||||
android_resources("resources") {
|
||||
resource_dirs = [ "apk/res" ]
|
||||
custom_package = "org.domokit.sky.shell"
|
||||
}
|
||||
|
||||
copy_ex("assets") {
|
||||
clear_dir = true
|
||||
dest = sky_shell_assets_dir
|
||||
sources = [
|
||||
"$root_build_dir/icudtl.dat",
|
||||
]
|
||||
deps = [
|
||||
"//third_party/icu",
|
||||
]
|
||||
}
|
||||
|
||||
android_apk("sky_shell_apk") {
|
||||
apk_name = "SkyShell"
|
||||
|
||||
android_manifest = "apk/AndroidManifest.xml"
|
||||
native_libs = [ "libsky_shell.so" ]
|
||||
|
||||
asset_location = "apk/res"
|
||||
asset_location = sky_shell_assets_dir
|
||||
|
||||
deps = [
|
||||
":sky_shell",
|
||||
"//base:base_java",
|
||||
":assets",
|
||||
":java",
|
||||
":resources",
|
||||
"//base:base_java",
|
||||
":sky_shell",
|
||||
]
|
||||
}
|
||||
|
||||
47
shell/apk/src/org/domokit/sky/shell/JavaServiceProvider.java
Normal file
47
shell/apk/src/org/domokit/sky/shell/JavaServiceProvider.java
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2015 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 org.domokit.sky.shell;
|
||||
|
||||
import org.chromium.base.CalledByNative;
|
||||
import org.chromium.base.JNINamespace;
|
||||
import org.chromium.mojo.system.Core;
|
||||
import org.chromium.mojo.system.MessagePipeHandle;
|
||||
import org.chromium.mojo.system.MojoException;
|
||||
import org.chromium.mojo.system.Pair;
|
||||
import org.chromium.mojo.system.impl.CoreImpl;
|
||||
import org.chromium.mojom.mojo.ServiceProvider;
|
||||
|
||||
/**
|
||||
* A class to intialize the network.
|
||||
**/
|
||||
@JNINamespace("sky::shell")
|
||||
public class JavaServiceProvider implements ServiceProvider {
|
||||
private Core mCore;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
public static int create() {
|
||||
Core core = CoreImpl.getInstance();
|
||||
Pair<MessagePipeHandle, MessagePipeHandle> messagePipe = core.createMessagePipe(null);
|
||||
ServiceProvider.MANAGER.bind(new JavaServiceProvider(core), messagePipe.first);
|
||||
return messagePipe.second.releaseNativeHandle();
|
||||
}
|
||||
|
||||
public JavaServiceProvider(Core core) {
|
||||
assert core != null;
|
||||
mCore = core;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {}
|
||||
|
||||
@Override
|
||||
public void onConnectionError(MojoException e) {}
|
||||
|
||||
@Override
|
||||
public void connectToService(String interfaceName, MessagePipeHandle pipe) {
|
||||
pipe.close();
|
||||
}
|
||||
}
|
||||
@ -4,67 +4,60 @@
|
||||
|
||||
package org.domokit.sky.shell;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
|
||||
import org.chromium.base.CalledByNative;
|
||||
import org.chromium.base.JNINamespace;
|
||||
|
||||
/**
|
||||
* A view containing Sky
|
||||
*/
|
||||
@JNINamespace("sky::shell")
|
||||
public class SkyView extends SurfaceView {
|
||||
private long mNativeSkyView;
|
||||
public class PlatformView extends SurfaceView {
|
||||
private long mNativePlatformView;
|
||||
private final SurfaceHolder.Callback mSurfaceCallback;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@CalledByNative
|
||||
public static void createForActivity(Activity activity, long nativeSkyView) {
|
||||
activity.setContentView(new SkyView(activity, nativeSkyView));
|
||||
}
|
||||
|
||||
public SkyView(Context context, long nativeSkyView) {
|
||||
public PlatformView(Context context) {
|
||||
super(context);
|
||||
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
|
||||
mNativeSkyView = nativeSkyView;
|
||||
assert mNativeSkyView != 0;
|
||||
mNativePlatformView = nativeAttach();
|
||||
assert mNativePlatformView != 0;
|
||||
|
||||
final float density = context.getResources().getDisplayMetrics().density;
|
||||
|
||||
mSurfaceCallback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
assert mNativeSkyView != 0;
|
||||
nativeSurfaceSetSize(mNativeSkyView, width, height, density);
|
||||
assert mNativePlatformView != 0;
|
||||
nativeSurfaceSetSize(mNativePlatformView, width, height, density);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
assert mNativeSkyView != 0;
|
||||
nativeSurfaceCreated(mNativeSkyView, holder.getSurface());
|
||||
assert mNativePlatformView != 0;
|
||||
nativeSurfaceCreated(mNativePlatformView, holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
assert mNativeSkyView != 0;
|
||||
nativeSurfaceDestroyed(mNativeSkyView);
|
||||
assert mNativePlatformView != 0;
|
||||
nativeSurfaceDestroyed(mNativePlatformView);
|
||||
}
|
||||
};
|
||||
getHolder().addCallback(mSurfaceCallback);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
getHolder().removeCallback(mSurfaceCallback);
|
||||
nativeDestroy(mNativeSkyView);
|
||||
mNativeSkyView = 0;
|
||||
nativeDetach(mNativePlatformView);
|
||||
mNativePlatformView = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,9 +69,10 @@ public class SkyView extends SurfaceView {
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nativeDestroy(long nativeSkyView);
|
||||
private static native void nativeSurfaceCreated(long nativeSkyView, Surface surface);
|
||||
private static native void nativeSurfaceDestroyed(long nativeSkyView);
|
||||
private static native long nativeAttach();
|
||||
private static native void nativeDetach(long nativePlatformView);
|
||||
private static native void nativeSurfaceCreated(long nativePlatformView, Surface surface);
|
||||
private static native void nativeSurfaceDestroyed(long nativePlatformView);
|
||||
private static native void nativeSurfaceSetSize(
|
||||
long nativeSkyView, int width, int height, float density);
|
||||
long nativePlatformView, int width, int height, float density);
|
||||
}
|
||||
@ -8,6 +8,7 @@ import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.chromium.base.JNINamespace;
|
||||
import org.chromium.base.ResourceExtractor;
|
||||
|
||||
/**
|
||||
* A class to intialize the native code.
|
||||
@ -28,6 +29,9 @@ public class SkyMain {
|
||||
if (sInitialized)
|
||||
return;
|
||||
try {
|
||||
ResourceExtractor resourceExtractor = ResourceExtractor.get(applicationContext);
|
||||
resourceExtractor.startExtractingResources();
|
||||
resourceExtractor.waitForCompletion();
|
||||
nativeInit(applicationContext);
|
||||
sInitialized = true;
|
||||
} catch (Exception e) {
|
||||
@ -36,15 +40,5 @@ public class SkyMain {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the specified application in the specified context.
|
||||
*
|
||||
* @return <code>true</code> if an application has been launched.
|
||||
**/
|
||||
static boolean start() {
|
||||
return nativeStart();
|
||||
}
|
||||
|
||||
private static native void nativeInit(Context context);
|
||||
private static native boolean nativeStart();
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ public class SkyShellActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
SkyMain.ensureInitialized(this);
|
||||
SkyMain.start();
|
||||
SkyMain.ensureInitialized(getApplicationContext());
|
||||
setContentView(new PlatformView(this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import android.util.Log;
|
||||
|
||||
import org.chromium.base.BaseChromiumApplication;
|
||||
import org.chromium.base.PathUtils;
|
||||
import org.chromium.base.ResourceExtractor;
|
||||
import org.chromium.base.library_loader.LibraryLoader;
|
||||
import org.chromium.base.library_loader.ProcessInitException;
|
||||
|
||||
@ -18,12 +19,16 @@ import org.chromium.base.library_loader.ProcessInitException;
|
||||
public class SkyShellApplication extends BaseChromiumApplication {
|
||||
private static final String TAG = "SkyShellApplication";
|
||||
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "sky_shell";
|
||||
private static final String[] SKY_MANDATORY_PAKS = {
|
||||
"icudtl.dat",
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
initializeJavaUtils();
|
||||
initializeNative();
|
||||
ResourceExtractor.setMandatoryPaksToExtract(SKY_MANDATORY_PAKS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -30,7 +30,7 @@ GaneshContext::GaneshContext(scoped_refptr<gfx::GLContext> gl_context)
|
||||
|
||||
gr_context_ = skia::AdoptRef(GrContext::Create(
|
||||
kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
|
||||
DCHECK(gr_context_);
|
||||
DCHECK(gr_context_) << "Failed to create GrContext.";
|
||||
gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount,
|
||||
kMaxGaneshResourceCacheBytes);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ GaneshSurface::GaneshSurface(GaneshContext* context, const gfx::Size& size) {
|
||||
desc.fWidth = size.width();
|
||||
desc.fHeight = size.height();
|
||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||
|
||||
auto target = skia::AdoptRef(context->gr()->wrapBackendRenderTarget(desc));
|
||||
DCHECK(target);
|
||||
|
||||
@ -24,7 +24,8 @@ gfx::Size GetSize(SkPicture* picture) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Rasterizer::Rasterizer() : weak_factory_(this) {
|
||||
Rasterizer::Rasterizer()
|
||||
: share_group_(new gfx::GLShareGroup()), weak_factory_(this) {
|
||||
}
|
||||
|
||||
Rasterizer::~Rasterizer() {
|
||||
@ -35,14 +36,15 @@ base::WeakPtr<Rasterizer> Rasterizer::GetWeakPtr() {
|
||||
}
|
||||
|
||||
void Rasterizer::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
|
||||
share_group_ = make_scoped_refptr(new gfx::GLShareGroup());
|
||||
surface_ = gfx::GLSurface::CreateViewGLSurface(widget);
|
||||
CHECK(surface_) << "GLSurface required.";
|
||||
CHECK(CreateGLContext()) << "GLContext required.";
|
||||
}
|
||||
|
||||
void Rasterizer::Draw(skia::RefPtr<SkPicture> picture) {
|
||||
// TODO(abarth): We should handle losing the GL context.
|
||||
if (!surface_)
|
||||
return;
|
||||
|
||||
EnsureGLContext();
|
||||
CHECK(context_->MakeCurrent(surface_.get()));
|
||||
EnsureGaneshSurface(GetSize(picture.get()));
|
||||
|
||||
@ -54,15 +56,20 @@ void Rasterizer::Draw(skia::RefPtr<SkPicture> picture) {
|
||||
}
|
||||
|
||||
void Rasterizer::OnOutputSurfaceDestroyed() {
|
||||
ganesh_surface_.reset();
|
||||
ganesh_context_.reset();
|
||||
context_ = nullptr;
|
||||
surface_ = nullptr;
|
||||
}
|
||||
|
||||
bool Rasterizer::CreateGLContext() {
|
||||
void Rasterizer::EnsureGLContext() {
|
||||
if (context_)
|
||||
return;
|
||||
context_ = gfx::GLContext::CreateGLContext(share_group_.get(), surface_.get(),
|
||||
gfx::PreferIntegratedGpu);
|
||||
if (!context_)
|
||||
return false;
|
||||
CHECK(context_) << "GLContext required.";
|
||||
CHECK(context_->MakeCurrent(surface_.get()));
|
||||
ganesh_context_.reset(new GaneshContext(context_.get()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Rasterizer::EnsureGaneshSurface(const gfx::Size& size) {
|
||||
|
||||
@ -34,11 +34,10 @@ class Rasterizer : public GPUDelegate {
|
||||
|
||||
void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override;
|
||||
void OnOutputSurfaceDestroyed() override;
|
||||
|
||||
void Draw(skia::RefPtr<SkPicture> picture);
|
||||
void Draw(skia::RefPtr<SkPicture> picture) override;
|
||||
|
||||
private:
|
||||
bool CreateGLContext();
|
||||
void EnsureGLContext();
|
||||
void EnsureGaneshSurface(const gfx::Size& size);
|
||||
|
||||
scoped_refptr<gfx::GLShareGroup> share_group_;
|
||||
|
||||
@ -5,8 +5,11 @@
|
||||
#ifndef SKY_SHELL_GPU_DELEGATE_H_
|
||||
#define SKY_SHELL_GPU_DELEGATE_H_
|
||||
|
||||
#include "skia/ext/refptr.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
|
||||
class SkPicture;
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
@ -14,6 +17,7 @@ class GPUDelegate {
|
||||
public:
|
||||
virtual void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) = 0;
|
||||
virtual void OnOutputSurfaceDestroyed() = 0;
|
||||
virtual void Draw(skia::RefPtr<SkPicture> picture) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~GPUDelegate();
|
||||
|
||||
23
shell/java_service_provider.cc
Normal file
23
shell/java_service_provider.cc
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2015 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/shell/java_service_provider.h"
|
||||
|
||||
#include "jni/JavaServiceProvider_jni.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
bool RegisterJavaServiceProvider(JNIEnv* env) {
|
||||
return RegisterNativesImpl(env);
|
||||
}
|
||||
|
||||
mojo::ScopedMessagePipeHandle CreateJavaServiceProvider() {
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
return mojo::ScopedMessagePipeHandle(
|
||||
mojo::MessagePipeHandle(Java_JavaServiceProvider_create(env)));
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
20
shell/java_service_provider.h
Normal file
20
shell/java_service_provider.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2015 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_SERVICE_PROVIDER_IMPL_H_
|
||||
#define SKY_SHELL_SERVICE_PROVIDER_IMPL_H_
|
||||
|
||||
#include <jni.h>
|
||||
#include "mojo/public/cpp/system/core.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
bool RegisterJavaServiceProvider(JNIEnv* env);
|
||||
mojo::ScopedMessagePipeHandle CreateJavaServiceProvider();
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SHELL_SERVICE_PROVIDER_IMPL_H_
|
||||
@ -7,14 +7,18 @@
|
||||
#include "base/android/jni_registrar.h"
|
||||
#include "base/android/library_loader/library_loader_hooks.h"
|
||||
#include "base/logging.h"
|
||||
#include "mojo/android/system/core_impl.h"
|
||||
#include "sky/shell/java_service_provider.h"
|
||||
#include "sky/shell/platform_view.h"
|
||||
#include "sky/shell/sky_main.h"
|
||||
#include "sky/shell/sky_view.h"
|
||||
|
||||
namespace {
|
||||
|
||||
base::android::RegistrationMethod kSkyRegisteredMethods[] = {
|
||||
{"CoreImpl", mojo::android::RegisterCoreImpl},
|
||||
{"JavaServiceProvider", sky::shell::RegisterJavaServiceProvider},
|
||||
{"SkyMain", sky::shell::RegisterSkyMain},
|
||||
{"SkyView", sky::shell::SkyView::Register},
|
||||
{"PlatformView", sky::shell::PlatformView::Register},
|
||||
};
|
||||
|
||||
bool RegisterSkyJni(JNIEnv* env) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "sky/shell/sky_view.h"
|
||||
#include "sky/shell/platform_view.h"
|
||||
|
||||
#include <android/input.h>
|
||||
#include <android/native_window_jni.h>
|
||||
@ -10,31 +10,35 @@
|
||||
#include "base/android/jni_android.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/location.h"
|
||||
#include "jni/SkyView_jni.h"
|
||||
#include "jni/PlatformView_jni.h"
|
||||
#include "sky/shell/shell.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
static jlong Attach(JNIEnv* env, jclass clazz) {
|
||||
return reinterpret_cast<jlong>(Shell::Shared().view());
|
||||
}
|
||||
|
||||
// static
|
||||
bool SkyView::Register(JNIEnv* env) {
|
||||
bool PlatformView::Register(JNIEnv* env) {
|
||||
return RegisterNativesImpl(env);
|
||||
}
|
||||
|
||||
SkyView::SkyView(const Config& config) : config_(config), window_(nullptr) {
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
Java_SkyView_createForActivity(env, base::android::GetApplicationContext(),
|
||||
reinterpret_cast<jlong>(this));
|
||||
PlatformView::PlatformView(const Config& config)
|
||||
: config_(config), window_(nullptr) {
|
||||
}
|
||||
|
||||
SkyView::~SkyView() {
|
||||
PlatformView::~PlatformView() {
|
||||
if (window_)
|
||||
ReleaseWindow();
|
||||
}
|
||||
|
||||
void SkyView::Destroy(JNIEnv* env, jobject obj) {
|
||||
void PlatformView::Detach(JNIEnv* env, jobject obj) {
|
||||
DCHECK(!window_);
|
||||
}
|
||||
|
||||
void SkyView::SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface) {
|
||||
void PlatformView::SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface) {
|
||||
base::android::ScopedJavaLocalRef<jobject> protector(env, jsurface);
|
||||
// Note: This ensures that any local references used by
|
||||
// ANativeWindow_fromSurface are released immediately. This is needed as a
|
||||
@ -48,7 +52,7 @@ void SkyView::SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface) {
|
||||
config_.gpu_delegate, window_));
|
||||
}
|
||||
|
||||
void SkyView::SurfaceDestroyed(JNIEnv* env, jobject obj) {
|
||||
void PlatformView::SurfaceDestroyed(JNIEnv* env, jobject obj) {
|
||||
DCHECK(window_);
|
||||
config_.gpu_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
@ -56,18 +60,18 @@ void SkyView::SurfaceDestroyed(JNIEnv* env, jobject obj) {
|
||||
ReleaseWindow();
|
||||
}
|
||||
|
||||
void SkyView::SurfaceSetSize(JNIEnv* env,
|
||||
jobject obj,
|
||||
jint width,
|
||||
jint height,
|
||||
jfloat density) {
|
||||
void PlatformView::SurfaceSetSize(JNIEnv* env,
|
||||
jobject obj,
|
||||
jint width,
|
||||
jint height,
|
||||
jfloat density) {
|
||||
config_.ui_task_runner->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&UIDelegate::OnViewportMetricsChanged, config_.ui_delegate,
|
||||
gfx::Size(width, height), density));
|
||||
}
|
||||
|
||||
void SkyView::ReleaseWindow() {
|
||||
void PlatformView::ReleaseWindow() {
|
||||
ANativeWindow_release(window_);
|
||||
window_ = nullptr;
|
||||
}
|
||||
@ -18,7 +18,7 @@ struct ANativeWindow;
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
class SkyView {
|
||||
class PlatformView {
|
||||
public:
|
||||
struct Config {
|
||||
base::WeakPtr<GPUDelegate> gpu_delegate;
|
||||
@ -30,11 +30,11 @@ class SkyView {
|
||||
|
||||
static bool Register(JNIEnv* env);
|
||||
|
||||
explicit SkyView(const Config& config);
|
||||
~SkyView();
|
||||
explicit PlatformView(const Config& config);
|
||||
~PlatformView();
|
||||
|
||||
// Called from Java
|
||||
void Destroy(JNIEnv* env, jobject obj);
|
||||
void Detach(JNIEnv* env, jobject obj);
|
||||
void SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface);
|
||||
void SurfaceDestroyed(JNIEnv* env, jobject obj);
|
||||
void SurfaceSetSize(JNIEnv* env,
|
||||
@ -49,7 +49,7 @@ class SkyView {
|
||||
Config config_;
|
||||
ANativeWindow* window_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SkyView);
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformView);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
@ -6,40 +6,80 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "mojo/common/message_pump_mojo.h"
|
||||
#include "mojo/edk/embedder/embedder.h"
|
||||
#include "mojo/edk/embedder/simple_platform_support.h"
|
||||
#include "sky/shell/gpu/rasterizer.h"
|
||||
#include "sky/shell/sky_view.h"
|
||||
#include "sky/shell/java_service_provider.h"
|
||||
#include "sky/shell/platform_view.h"
|
||||
#include "sky/shell/ui/engine.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
namespace {
|
||||
|
||||
static Shell* g_shell = nullptr;
|
||||
|
||||
scoped_ptr<base::MessagePump> CreateMessagePumpMojo() {
|
||||
return make_scoped_ptr(new mojo::common::MessagePumpMojo);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Shell::Shell(scoped_refptr<base::SingleThreadTaskRunner> java_task_runner)
|
||||
: java_task_runner_(java_task_runner) {
|
||||
DCHECK(!g_shell);
|
||||
mojo::embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>(
|
||||
new mojo::embedder::SimplePlatformSupport()));
|
||||
|
||||
base::Thread::Options options;
|
||||
options.message_pump_factory = base::Bind(&CreateMessagePumpMojo);
|
||||
|
||||
InitGPU(options);
|
||||
InitUI(options);
|
||||
InitView();
|
||||
}
|
||||
|
||||
Shell::~Shell() {
|
||||
}
|
||||
|
||||
void Shell::Init() {
|
||||
gpu_thread_.reset(new base::Thread("gpu_thread"));
|
||||
gpu_thread_->Start();
|
||||
rasterizer_.reset(new Rasterizer());
|
||||
void Shell::Init(scoped_refptr<base::SingleThreadTaskRunner> java_task_runner) {
|
||||
g_shell = new Shell(java_task_runner);
|
||||
}
|
||||
|
||||
Shell& Shell::Shared() {
|
||||
DCHECK(g_shell);
|
||||
return *g_shell;
|
||||
}
|
||||
|
||||
void Shell::InitGPU(const base::Thread::Options& options) {
|
||||
gpu_thread_.reset(new base::Thread("gpu_thread"));
|
||||
gpu_thread_->StartWithOptions(options);
|
||||
|
||||
rasterizer_.reset(new Rasterizer());
|
||||
}
|
||||
|
||||
void Shell::InitUI(const base::Thread::Options& options) {
|
||||
ui_thread_.reset(new base::Thread("ui_thread"));
|
||||
ui_thread_->Start();
|
||||
engine_.reset(new Engine());
|
||||
ui_thread_->StartWithOptions(options);
|
||||
|
||||
Engine::Config config;
|
||||
config.gpu_task_runner = gpu_thread_->message_loop()->task_runner();
|
||||
config.gpu_delegate = rasterizer_->GetWeakPtr();
|
||||
engine_.reset(new Engine(config));
|
||||
|
||||
ui_thread_->message_loop()->PostTask(
|
||||
FROM_HERE, base::Bind(&Engine::Init, engine_->GetWeakPtr()));
|
||||
FROM_HERE, base::Bind(&Engine::Init, engine_->GetWeakPtr(),
|
||||
base::Passed(CreateJavaServiceProvider())));
|
||||
}
|
||||
|
||||
SkyView::Config config;
|
||||
void Shell::InitView() {
|
||||
PlatformView::Config config;
|
||||
config.gpu_task_runner = gpu_thread_->message_loop()->task_runner();
|
||||
config.gpu_delegate = rasterizer_->GetWeakPtr();
|
||||
config.ui_task_runner = ui_thread_->message_loop()->task_runner();
|
||||
config.ui_delegate = engine_->GetWeakPtr();
|
||||
|
||||
view_.reset(new SkyView(config));
|
||||
view_.reset(new PlatformView(config));
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/threading/thread.h"
|
||||
|
||||
namespace base {
|
||||
class Thread;
|
||||
class SingleThreadTaskRunner;
|
||||
}
|
||||
|
||||
@ -18,21 +18,30 @@ namespace sky {
|
||||
namespace shell {
|
||||
class Engine;
|
||||
class Rasterizer;
|
||||
class SkyView;
|
||||
class PlatformView;
|
||||
|
||||
class Shell {
|
||||
public:
|
||||
explicit Shell(scoped_refptr<base::SingleThreadTaskRunner> java_task_runner);
|
||||
~Shell();
|
||||
|
||||
void Init();
|
||||
static void Init(
|
||||
scoped_refptr<base::SingleThreadTaskRunner> java_task_runner);
|
||||
static Shell& Shared();
|
||||
|
||||
PlatformView* view() const { return view_.get(); }
|
||||
|
||||
private:
|
||||
explicit Shell(scoped_refptr<base::SingleThreadTaskRunner> java_task_runner);
|
||||
|
||||
void InitGPU(const base::Thread::Options& options);
|
||||
void InitUI(const base::Thread::Options& options);
|
||||
void InitView();
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> java_task_runner_;
|
||||
scoped_ptr<base::Thread> gpu_thread_;
|
||||
scoped_ptr<base::Thread> ui_thread_;
|
||||
|
||||
scoped_ptr<SkyView> view_;
|
||||
scoped_ptr<PlatformView> view_;
|
||||
scoped_ptr<Rasterizer> rasterizer_;
|
||||
scoped_ptr<Engine> engine_;
|
||||
|
||||
|
||||
@ -31,11 +31,6 @@ namespace {
|
||||
LazyInstance<scoped_ptr<base::MessageLoop>> g_java_message_loop =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
LazyInstance<base::android::ScopedJavaGlobalRef<jobject>> g_main_activiy =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
LazyInstance<scoped_ptr<Shell>> g_shell = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
void InitializeLogging() {
|
||||
logging::LoggingSettings settings;
|
||||
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
||||
@ -49,16 +44,11 @@ void InitializeLogging() {
|
||||
|
||||
} // namespace
|
||||
|
||||
static void Init(JNIEnv* env,
|
||||
jclass clazz,
|
||||
jobject activity) {
|
||||
g_main_activiy.Get().Reset(env, activity);
|
||||
|
||||
base::android::ScopedJavaLocalRef<jobject> scoped_activity(env, activity);
|
||||
base::android::InitApplicationContext(env, scoped_activity);
|
||||
static void Init(JNIEnv* env, jclass clazz, jobject context) {
|
||||
base::android::ScopedJavaLocalRef<jobject> scoped_context(env, context);
|
||||
base::android::InitApplicationContext(env, scoped_context);
|
||||
|
||||
base::CommandLine::Init(0, nullptr);
|
||||
|
||||
InitializeLogging();
|
||||
|
||||
g_java_message_loop.Get().reset(new base::MessageLoopForUI);
|
||||
@ -67,16 +57,7 @@ static void Init(JNIEnv* env,
|
||||
base::i18n::InitializeICU();
|
||||
gfx::GLSurface::InitializeOneOff();
|
||||
|
||||
g_shell.Get().reset(new Shell(g_java_message_loop.Get()->task_runner()));
|
||||
|
||||
g_java_message_loop.Get()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&Shell::Init, base::Unretained(g_shell.Get().get())));
|
||||
}
|
||||
|
||||
static jboolean Start(JNIEnv* env, jclass clazz) {
|
||||
LOG(INFO) << "Native code started!";
|
||||
return true;
|
||||
Shell::Init(g_java_message_loop.Get()->task_runner());
|
||||
}
|
||||
|
||||
bool RegisterSkyMain(JNIEnv* env) {
|
||||
|
||||
59
shell/ui/animator.cc
Normal file
59
shell/ui/animator.cc
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2015 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/shell/ui/animator.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
Animator::Animator(const Engine::Config& config, Engine* engine)
|
||||
: config_(config),
|
||||
engine_(engine),
|
||||
engine_requested_frame_(false),
|
||||
frame_in_progress_(false),
|
||||
weak_factory_(this) {
|
||||
}
|
||||
|
||||
Animator::~Animator() {
|
||||
}
|
||||
|
||||
void Animator::RequestFrame() {
|
||||
if (engine_requested_frame_)
|
||||
return;
|
||||
engine_requested_frame_ = true;
|
||||
|
||||
if (!frame_in_progress_) {
|
||||
frame_in_progress_ = true;
|
||||
base::MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&Animator::BeginFrame, weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
}
|
||||
|
||||
void Animator::BeginFrame() {
|
||||
DCHECK(frame_in_progress_);
|
||||
DCHECK(engine_requested_frame_);
|
||||
engine_requested_frame_ = false;
|
||||
|
||||
engine_->BeginFrame(base::TimeTicks::Now());
|
||||
config_.gpu_task_runner->PostTaskAndReply(
|
||||
FROM_HERE,
|
||||
base::Bind(&GPUDelegate::Draw, config_.gpu_delegate, engine_->Paint()),
|
||||
base::Bind(&Animator::OnFrameComplete, weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void Animator::OnFrameComplete() {
|
||||
DCHECK(frame_in_progress_);
|
||||
frame_in_progress_ = false;
|
||||
if (engine_requested_frame_) {
|
||||
frame_in_progress_ = true;
|
||||
BeginFrame();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
38
shell/ui/animator.h
Normal file
38
shell/ui/animator.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2015 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_ANIMATOR_H_
|
||||
#define SKY_SHELL_UI_ANIMATOR_H_
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "sky/shell/ui/engine.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
class Animator {
|
||||
public:
|
||||
explicit Animator(const Engine::Config& config, Engine* engine);
|
||||
~Animator();
|
||||
|
||||
void RequestFrame();
|
||||
|
||||
private:
|
||||
void BeginFrame();
|
||||
void OnFrameComplete();
|
||||
|
||||
Engine::Config config_;
|
||||
Engine* engine_;
|
||||
bool engine_requested_frame_;
|
||||
bool frame_in_progress_;
|
||||
|
||||
base::WeakPtrFactory<Animator> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Animator);
|
||||
};
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
#endif // SKY_SHELL_UI_ANIMATOR_H_
|
||||
@ -4,15 +4,22 @@
|
||||
|
||||
#include "sky/shell/ui/engine.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "sky/engine/public/web/Sky.h"
|
||||
#include "sky/engine/public/web/WebLocalFrame.h"
|
||||
#include "sky/engine/public/web/WebView.h"
|
||||
#include "sky/shell/ui/animator.h"
|
||||
#include "sky/shell/ui/platform_impl.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkPictureRecorder.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
Engine::Engine() : web_view_(nullptr), weak_factory_(this) {
|
||||
Engine::Engine(const Config& config)
|
||||
: animator_(new Animator(config, this)),
|
||||
web_view_(nullptr),
|
||||
weak_factory_(this) {
|
||||
}
|
||||
|
||||
Engine::~Engine() {
|
||||
@ -24,20 +31,53 @@ base::WeakPtr<Engine> Engine::GetWeakPtr() {
|
||||
return weak_factory_.GetWeakPtr();
|
||||
}
|
||||
|
||||
void Engine::Init() {
|
||||
platform_impl_.reset(new PlatformImpl);
|
||||
void Engine::Init(mojo::ScopedMessagePipeHandle service_provider) {
|
||||
platform_impl_.reset(new PlatformImpl(
|
||||
mojo::MakeProxy<mojo::ServiceProvider>(service_provider.Pass())));
|
||||
blink::initialize(platform_impl_.get());
|
||||
|
||||
web_view_ = blink::WebView::create(this);
|
||||
web_view_->setMainFrame(blink::WebLocalFrame::create(this));
|
||||
web_view_->mainFrame()->load(
|
||||
GURL("http://127.0.0.1:8000/sky/examples/spinning-square.sky"));
|
||||
}
|
||||
|
||||
void Engine::OnViewportMetricsChanged(const gfx::Size& size,
|
||||
void Engine::BeginFrame(base::TimeTicks frame_time) {
|
||||
double frame_time_sec = (frame_time - base::TimeTicks()).InSecondsF();
|
||||
double deadline_sec = frame_time_sec;
|
||||
double interval_sec = 1.0 / 60;
|
||||
blink::WebBeginFrameArgs args(frame_time_sec, deadline_sec, interval_sec);
|
||||
|
||||
web_view_->beginFrame(args);
|
||||
web_view_->layout();
|
||||
}
|
||||
|
||||
skia::RefPtr<SkPicture> Engine::Paint() {
|
||||
SkRTreeFactory factory;
|
||||
SkPictureRecorder recorder;
|
||||
auto canvas = skia::SharePtr(recorder.beginRecording(
|
||||
physical_size_.width(), physical_size_.height(), &factory,
|
||||
SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag));
|
||||
|
||||
web_view_->paint(canvas.get(), blink::WebRect(gfx::Rect(physical_size_)));
|
||||
return skia::AdoptRef(recorder.endRecordingAsPicture());
|
||||
}
|
||||
|
||||
void Engine::OnViewportMetricsChanged(const gfx::Size& physical_size,
|
||||
float device_pixel_ratio) {
|
||||
blink::WebSize web_size(size.width() / device_pixel_ratio,
|
||||
size.height() / device_pixel_ratio);
|
||||
physical_size_ = physical_size;
|
||||
web_view_->setDeviceScaleFactor(device_pixel_ratio);
|
||||
web_view_->resize(web_size);
|
||||
gfx::SizeF size = gfx::ScaleSize(physical_size, 1 / device_pixel_ratio);
|
||||
// FIXME: We should be able to set the size of the WebView in floating point
|
||||
// because its in logical pixels.
|
||||
web_view_->resize(blink::WebSize(size.width(), size.height()));
|
||||
}
|
||||
|
||||
void Engine::initializeLayerTreeView() {
|
||||
}
|
||||
|
||||
void Engine::scheduleVisualUpdate() {
|
||||
animator_->RequestFrame();
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@ -8,32 +8,53 @@
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "mojo/public/cpp/system/core.h"
|
||||
#include "skia/ext/refptr.h"
|
||||
#include "sky/engine/public/web/WebFrameClient.h"
|
||||
#include "sky/engine/public/web/WebViewClient.h"
|
||||
#include "sky/shell/gpu_delegate.h"
|
||||
#include "sky/shell/ui_delegate.h"
|
||||
#include "third_party/skia/include/core/SkPicture.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
class Animator;
|
||||
class PlatformImpl;
|
||||
|
||||
class Engine : public UIDelegate,
|
||||
public blink::WebFrameClient,
|
||||
public blink::WebViewClient {
|
||||
public:
|
||||
Engine();
|
||||
struct Config {
|
||||
base::WeakPtr<GPUDelegate> gpu_delegate;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner;
|
||||
};
|
||||
|
||||
explicit Engine(const Config& config);
|
||||
~Engine() override;
|
||||
|
||||
base::WeakPtr<Engine> GetWeakPtr();
|
||||
|
||||
void Init();
|
||||
void Init(mojo::ScopedMessagePipeHandle service_provider);
|
||||
|
||||
void OnViewportMetricsChanged(const gfx::Size& size,
|
||||
float device_pixel_ratio) override;
|
||||
void BeginFrame(base::TimeTicks frame_time);
|
||||
skia::RefPtr<SkPicture> Paint();
|
||||
|
||||
private:
|
||||
// UIDelegate methods:
|
||||
void OnViewportMetricsChanged(const gfx::Size& physical_size,
|
||||
float device_pixel_ratio) override;
|
||||
|
||||
// WebViewClient methods:
|
||||
void initializeLayerTreeView() override;
|
||||
void scheduleVisualUpdate() override;
|
||||
|
||||
scoped_ptr<PlatformImpl> platform_impl_;
|
||||
scoped_ptr<Animator> animator_;
|
||||
blink::WebView* web_view_;
|
||||
gfx::Size physical_size_;
|
||||
|
||||
base::WeakPtrFactory<Engine> weak_factory_;
|
||||
|
||||
|
||||
@ -4,11 +4,15 @@
|
||||
|
||||
#include "sky/shell/ui/platform_impl.h"
|
||||
|
||||
#include "mojo/public/cpp/application/connect.h"
|
||||
|
||||
namespace sky {
|
||||
namespace shell {
|
||||
|
||||
PlatformImpl::PlatformImpl()
|
||||
: main_thread_task_runner_(base::MessageLoop::current()->task_runner()) {
|
||||
PlatformImpl::PlatformImpl(mojo::ServiceProviderPtr service_provider)
|
||||
: main_thread_task_runner_(base::MessageLoop::current()->task_runner()),
|
||||
service_provider_(service_provider.Pass()) {
|
||||
mojo::ConnectToService(service_provider_.get(), &network_service_);
|
||||
}
|
||||
|
||||
PlatformImpl::~PlatformImpl() {
|
||||
@ -22,5 +26,9 @@ base::SingleThreadTaskRunner* PlatformImpl::mainThreadTaskRunner() {
|
||||
return main_thread_task_runner_.get();
|
||||
}
|
||||
|
||||
mojo::NetworkService* PlatformImpl::networkService() {
|
||||
return network_service_.get();
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
} // namespace sky
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#define SKY_SHELL_UI_PLATFORM_IMPL_H_
|
||||
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "mojo/public/interfaces/application/service_provider.mojom.h"
|
||||
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
|
||||
#include "sky/engine/public/platform/Platform.h"
|
||||
|
||||
namespace sky {
|
||||
@ -13,15 +15,18 @@ namespace shell {
|
||||
|
||||
class PlatformImpl : public blink::Platform {
|
||||
public:
|
||||
PlatformImpl();
|
||||
explicit PlatformImpl(mojo::ServiceProviderPtr service_provider);
|
||||
~PlatformImpl() override;
|
||||
|
||||
// blink::Platform:
|
||||
blink::WebString defaultLocale() override;
|
||||
base::SingleThreadTaskRunner* mainThreadTaskRunner() override;
|
||||
mojo::NetworkService* networkService() override;
|
||||
|
||||
private:
|
||||
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
|
||||
mojo::ServiceProviderPtr service_provider_;
|
||||
mojo::NetworkServicePtr network_service_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformImpl);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user