Remove uses of //base from all //flutter projects and replace them with //fml variants. (flutter/engine#3492)

This commit is contained in:
Chinmay Garde
2017-03-22 15:42:51 -07:00
committed by GitHub
parent 0d3611119a
commit 6ff5a41327
80 changed files with 1400 additions and 1226 deletions

2
DEPS
View File

@@ -46,7 +46,7 @@ allowed_hosts = [
]
deps = {
'src': 'https://github.com/flutter/buildroot.git' + '@' + 'be33a80dc114686c2ddb951d751d195dbac14fb2',
'src': 'https://github.com/flutter/buildroot.git' + '@' + 'c5633e135092754836ab7abee5405b8e5b075b2f',
# Fuchsia compatibility
#

View File

@@ -27,6 +27,7 @@ group("flutter") {
]
}
deps += [
"//flutter/fml:fml_unittests",
"//flutter/sky/engine/wtf:wtf_unittests",
"//flutter/synchronization:synchronization_unittests",
"//lib/ftl:ftl_unittests",

View File

@@ -114,7 +114,8 @@ sk_sp<SkImage> RasterCache::GetPrerolledImage(GrContext* context,
if (!entry.image && !will_change &&
(is_complex || isWorthRasterizing(picture))) {
TRACE_EVENT2("flutter", "Rasterize picture layer", "width",
physical_size.width(), "height", physical_size.height());
std::to_string(physical_size.width()).c_str(), "height",
std::to_string(physical_size.height()).c_str());
SkImageInfo info = SkImageInfo::MakeN32Premul(physical_size);
sk_sp<SkSurface> surface =
SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);

View File

@@ -3,9 +3,105 @@
# found in the LICENSE file.
source_set("fml") {
public_deps = []
sources = [
"icu_util.cc",
"icu_util.h",
"mapping.cc",
"mapping.h",
"message_loop.cc",
"message_loop.h",
"message_loop_impl.cc",
"message_loop_impl.h",
"task_runner.cc",
"task_runner.h",
"thread.cc",
"thread.h",
"thread_checker.cc",
"thread_checker.h",
"thread_local.h",
"trace_event.cc",
"trace_event.h",
]
deps = [
"//dart/runtime:libdart",
"//lib/ftl",
# These need to be in sync with the Fuchsia buildroot.
"//third_party/icu",
]
configs += [ "//third_party/icu:icu_config" ]
libs = []
if (is_ios || is_mac) {
public_deps += [ "platform/darwin" ]
sources += [
"platform/darwin/cf_utils.cc",
"platform/darwin/cf_utils.h",
"platform/darwin/message_loop_darwin.h",
"platform/darwin/message_loop_darwin.mm",
"platform/darwin/nsstring_utils.h",
"platform/darwin/nsstring_utils.mm",
"platform/darwin/resource_mapping_darwin.h",
"platform/darwin/resource_mapping_darwin.mm",
"platform/darwin/scoped_block.h",
"platform/darwin/scoped_block.mm",
"platform/darwin/scoped_nsobject.h",
"platform/darwin/scoped_nsobject.mm",
]
libs += [ "Foundation.framework" ]
}
if (is_android) {
sources += [
"platform/android/jni_util.cc",
"platform/android/jni_util.h",
"platform/android/jni_weak_ref.cc",
"platform/android/jni_weak_ref.h",
"platform/android/message_loop_android.cc",
"platform/android/message_loop_android.h",
"platform/android/scoped_java_ref.cc",
"platform/android/scoped_java_ref.h",
]
libs += [ "android" ]
}
if (is_android) {
# Don't filter away these Linux sources on Android.
set_sources_assignment_filter([])
sources += [
"platform/linux/timerfd.cc",
"platform/linux/timerfd.h",
]
set_sources_assignment_filter(sources_assignment_filter)
}
if (is_linux) {
sources += [
"platform/linux/message_loop_linux.cc",
"platform/linux/message_loop_linux.h",
"platform/linux/timerfd.cc",
"platform/linux/timerfd.h",
]
}
}
executable("fml_unittests") {
testonly = true
sources = [
"message_loop_unittests.cc",
"thread_checker_unittests.cc",
"thread_local_unittests.cc",
"thread_unittests.cc",
]
deps = [
"//flutter/fml",
"//flutter/testing",
"//lib/ftl",
]
}

View File

@@ -1,18 +0,0 @@
# Copyright 2017 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.
source_set("darwin") {
visibility = [ "//flutter/fml" ]
sources = [
"cf_utils.cc",
"cf_utils.h",
]
deps = [
"//lib/ftl",
]
libs = [ "CoreFoundation.framework" ]
}

View File

@@ -0,0 +1,22 @@
// Copyright 2017 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 FLUTTER_FML_PLATFORM_DARWIN_NSSTRING_UTILS_H_
#define FLUTTER_FML_PLATFORM_DARWIN_NSSTRING_UTILS_H_
#include <string>
#include "lib/ftl/macros.h"
@class NSString;
namespace fml {
NSString* StringToNSString(const std::u16string& string);
std::u16string StringFromNSString(NSString* string);
} // namespace fml
#endif // FLUTTER_FML_PLATFORM_DARWIN_NSSTRING_UTILS_H_

View File

@@ -0,0 +1,25 @@
// Copyright 2017 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 "flutter/fml/platform/darwin/nsstring_utils.h"
#include <Foundation/Foundation.h>
namespace fml {
NSString* StringToNSString(const std::u16string& string) {
return [[[NSString alloc] initWithBytes:string.data()
length:string.length()
encoding:NSUTF16StringEncoding] autorelease];
}
std::u16string StringFromNSString(NSString* string) {
if (string.length == 0) {
return {};
}
NSData* data = [string dataUsingEncoding:NSUTF16StringEncoding];
return {reinterpret_cast<const char16_t*>(data.bytes), data.length};
}
} // namespace fml

View File

@@ -0,0 +1,87 @@
// Copyright (c) 2013 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 FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
#define FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
#include <Block.h>
#include "lib/ftl/compiler_specific.h"
namespace fml {
// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
// Block_release() instead of CFRetain() and CFRelease().
enum class OwnershipPolicy {
// The scoped object takes ownership of an object by taking over an existing
// ownership claim.
Assume,
// The scoped object will retain the the object and any initial ownership is
// not changed.
Retain,
};
template <typename B>
class ScopedBlock {
public:
explicit ScopedBlock(B block = nullptr,
OwnershipPolicy policy = OwnershipPolicy::Assume)
: block_(block) {
if (block_ && policy == OwnershipPolicy::Retain)
block_ = Block_copy(block);
}
ScopedBlock(const ScopedBlock<B>& that) : block_(that.block_) {
if (block_)
block_ = Block_copy(block_);
}
~ScopedBlock() {
if (block_)
Block_release(block_);
}
ScopedBlock& operator=(const ScopedBlock<B>& that) {
reset(that.get(), OwnershipPolicy::Retain);
return *this;
}
void reset(B block = nullptr,
OwnershipPolicy policy = OwnershipPolicy::Assume) {
if (block && policy == OwnershipPolicy::Retain)
block = Block_copy(block);
if (block_)
Block_release(block_);
block_ = block;
}
bool operator==(B that) const { return block_ == that; }
bool operator!=(B that) const { return block_ != that; }
operator B() const { return block_; }
B get() const { return block_; }
void swap(ScopedBlock& that) {
B temp = that.block_;
that.block_ = block_;
block_ = temp;
}
B release() FTL_WARN_UNUSED_RESULT {
B temp = block_;
block_ = nullptr;
return temp;
}
private:
B block_;
};
} // namespace fml
#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_

View File

@@ -0,0 +1,11 @@
// Copyright 2017 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 "flutter/fml/platform/darwin/scoped_block.h"
namespace fml {
//
} // namespace fml

View File

@@ -0,0 +1,163 @@
// Copyright 2017 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 FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
#define FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
// Include NSObject.h directly because Foundation.h pulls in many dependencies.
// (Approx 100k lines of code versus 1.5k for NSObject.h). scoped_nsobject gets
// singled out because it is most typically included from other header files.
#import <Foundation/NSObject.h>
#include "lib/ftl/compiler_specific.h"
#include "lib/ftl/macros.h"
@class NSAutoreleasePool;
namespace fml {
// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership
// of an NSObject subclass object. Style deviations here are solely for
// compatibility with scoped_ptr<>'s interface, with which everyone is already
// familiar.
//
// scoped_nsobject<> takes ownership of an object (in the constructor or in
// reset()) by taking over the caller's existing ownership claim. The caller
// must own the object it gives to scoped_nsobject<>, and relinquishes an
// ownership claim to that object. scoped_nsobject<> does not call -retain,
// callers have to call this manually if appropriate.
//
// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
// with protocols.
//
// scoped_nsobject<> is not to be used for NSAutoreleasePools. For
// NSAutoreleasePools use ScopedNSAutoreleasePool from
// scoped_nsautorelease_pool.h instead.
// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
// time with a template specialization (see below).
template <typename NST>
class scoped_nsprotocol {
public:
explicit scoped_nsprotocol(NST object = nil) : object_(object) {}
scoped_nsprotocol(const scoped_nsprotocol<NST>& that)
: object_([that.object_ retain]) {}
template <typename NSU>
scoped_nsprotocol(const scoped_nsprotocol<NSU>& that)
: object_([that.get() retain]) {}
~scoped_nsprotocol() { [object_ release]; }
scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) {
reset([that.get() retain]);
return *this;
}
void reset(NST object = nil) {
// We intentionally do not check that object != object_ as the caller must
// either already have an ownership claim over whatever it passes to this
// method, or call it with the |RETAIN| policy which will have ensured that
// the object is retained once more when reaching this point.
[object_ release];
object_ = object;
}
bool operator==(NST that) const { return object_ == that; }
bool operator!=(NST that) const { return object_ != that; }
operator NST() const { return object_; }
NST get() const { return object_; }
void swap(scoped_nsprotocol& that) {
NST temp = that.object_;
that.object_ = object_;
object_ = temp;
}
// scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a
// wrapper for [object_ release]. To force a scoped_nsprotocol<> to call
// [object_ release], use scoped_nsprotocol<>::reset().
NST release() FTL_WARN_UNUSED_RESULT {
NST temp = object_;
object_ = nil;
return temp;
}
// Shift reference to the autorelease pool to be released later.
NST autorelease() { return [release() autorelease]; }
private:
NST object_;
};
// Free functions
template <class C>
void swap(scoped_nsprotocol<C>& p1, scoped_nsprotocol<C>& p2) {
p1.swap(p2);
}
template <class C>
bool operator==(C p1, const scoped_nsprotocol<C>& p2) {
return p1 == p2.get();
}
template <class C>
bool operator!=(C p1, const scoped_nsprotocol<C>& p2) {
return p1 != p2.get();
}
template <typename NST>
class scoped_nsobject : public scoped_nsprotocol<NST*> {
public:
explicit scoped_nsobject(NST* object = nil)
: scoped_nsprotocol<NST*>(object) {}
scoped_nsobject(const scoped_nsobject<NST>& that)
: scoped_nsprotocol<NST*>(that) {}
template <typename NSU>
scoped_nsobject(const scoped_nsobject<NSU>& that)
: scoped_nsprotocol<NST*>(that) {}
scoped_nsobject& operator=(const scoped_nsobject<NST>& that) {
scoped_nsprotocol<NST*>::operator=(that);
return *this;
}
};
// Specialization to make scoped_nsobject<id> work.
template <>
class scoped_nsobject<id> : public scoped_nsprotocol<id> {
public:
explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {}
scoped_nsobject(const scoped_nsobject<id>& that)
: scoped_nsprotocol<id>(that) {}
template <typename NSU>
scoped_nsobject(const scoped_nsobject<NSU>& that)
: scoped_nsprotocol<id>(that) {}
scoped_nsobject& operator=(const scoped_nsobject<id>& that) {
scoped_nsprotocol<id>::operator=(that);
return *this;
}
};
// Do not use scoped_nsobject for NSAutoreleasePools, use
// ScopedNSAutoreleasePool instead. This is a compile time check. See details
// at top of header.
template <>
class scoped_nsobject<NSAutoreleasePool> {
private:
explicit scoped_nsobject(NSAutoreleasePool* object = nil);
FTL_DISALLOW_COPY_AND_ASSIGN(scoped_nsobject);
};
} // namespace fml
#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_

View File

@@ -0,0 +1,11 @@
// Copyright 2017 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 "flutter/fml/platform/darwin/scoped_nsobject.h"
namespace fml {
//
} // namespace fml

View File

@@ -11,6 +11,8 @@
#include "lib/ftl/macros.h"
#ifndef TRACE_EVENT_HIDE_MACROS
#define TRACE_EVENT0(category_group, name) \
::fml::tracing::TraceEvent0(category_group, name); \
::fml::tracing::ScopedInstantEnd __trace_end0_##__LINE__(name);
@@ -43,6 +45,8 @@
#define TRACE_EVENT_INSTANT0(category_group, name) \
::fml::tracing::TraceEventInstant0(category_group, name);
#endif // TRACE_EVENT_HIDE_MACROS
namespace fml {
namespace tracing {

View File

@@ -19,12 +19,8 @@ source_set("glue") {
"//apps/tracing/lib/trace",
]
} else {
sources += [
"stack_trace_base.cc",
"task_runner_adaptor.cc",
"task_runner_adaptor.h",
]
sources += [ "stack_trace_base.cc" ]
deps += [ "//base" ]
deps += [ "//flutter/fml" ]
}
}

View File

@@ -4,12 +4,8 @@
#include "flutter/glue/stack_trace.h"
#include "base/debug/stack_trace.h"
namespace glue {
void PrintStackTrace() {
base::debug::StackTrace().Print();
}
void PrintStackTrace() {}
} // namespace glue

View File

@@ -1,54 +0,0 @@
// Copyright 2016 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 "flutter/glue/task_runner_adaptor.h"
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/task_runner.h"
namespace glue {
namespace {
void RunClosure(ftl::Closure task) {
task();
}
} // namespace
TaskRunnerAdaptor::TaskRunnerAdaptor(scoped_refptr<base::TaskRunner> runner)
: runner_(std::move(runner)) {
FTL_DCHECK(runner_);
}
TaskRunnerAdaptor::~TaskRunnerAdaptor() {}
void TaskRunnerAdaptor::PostTask(ftl::Closure task) {
runner_->PostTask(FROM_HERE, base::Bind(RunClosure, task));
}
void TaskRunnerAdaptor::PostTaskForTime(ftl::Closure task,
ftl::TimePoint target_time) {
ftl::TimePoint now = ftl::TimePoint::Now();
runner_->PostDelayedTask(FROM_HERE, base::Bind(RunClosure, task),
target_time <= now
? base::TimeDelta()
: base::TimeDelta::FromMicroseconds(
(target_time - now).ToMicroseconds()));
}
void TaskRunnerAdaptor::PostDelayedTask(ftl::Closure task,
ftl::TimeDelta delay) {
runner_->PostDelayedTask(
FROM_HERE, base::Bind(RunClosure, task),
base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
}
bool TaskRunnerAdaptor::RunsTasksOnCurrentThread() {
return runner_->RunsTasksOnCurrentThread();
}
} // namespace glue

View File

@@ -1,35 +0,0 @@
// Copyright 2016 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 FLUTTER_GLU_BASE_TASK_RUNNER_H_
#define FLUTTER_GLU_BASE_TASK_RUNNER_H_
#include "base/memory/ref_counted.h"
#include "lib/ftl/tasks/task_runner.h"
namespace base {
class TaskRunner;
} // namespace base
namespace glue {
class TaskRunnerAdaptor : public ftl::TaskRunner {
public:
explicit TaskRunnerAdaptor(scoped_refptr<base::TaskRunner> runner);
void PostTask(ftl::Closure task) override;
void PostTaskForTime(ftl::Closure task, ftl::TimePoint target_time) override;
void PostDelayedTask(ftl::Closure task, ftl::TimeDelta delay) override;
bool RunsTasksOnCurrentThread() override;
protected:
~TaskRunnerAdaptor() override;
private:
scoped_refptr<base::TaskRunner> runner_;
};
} // namespace glue
#endif // FLUTTER_GLU_BASE_TASK_RUNNER_H_

View File

@@ -2,7 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_GLUE_TRACE_EVENT_H_
#define FLUTTER_GLUE_TRACE_EVENT_H_
#if defined(__Fuchsia__)
#include "apps/tracing/lib/trace/event.h"
#define TRACE_EVENT0(a, b) TRACE_DURATION(a, b)
@@ -10,10 +14,13 @@
#define TRACE_EVENT2(a, b, c, d, e, f) TRACE_DURATION(a, b, c, d, e, f)
#define TRACE_EVENT_ASYNC_BEGIN0(a, b, c) TRACE_ASYNC_BEGIN(a, b, c)
#define TRACE_EVENT_ASYNC_END0(a, b, c) TRACE_ASYNC_END(a, b, c)
#define TRACE_EVENT_ASYNC_BEGIN1(a, b, c, d, e) \
TRACE_ASYNC_BEGIN(a, b, c, d, e)
#define TRACE_EVENT_ASYNC_BEGIN1(a, b, c, d, e) TRACE_ASYNC_BEGIN(a, b, c, d, e)
#define TRACE_EVENT_ASYNC_END1(a, b, c, d, e) TRACE_ASYNC_END(a, b, c, d, e)
#else
#include "base/trace_event/trace_event.h"
#else // defined(__Fuchsia__)
#include "flutter/fml/trace_event.h"
#endif // defined(__Fuchsia__)
#endif // FLUTTER_GLUE_TRACE_EVENT_H_

View File

@@ -19,7 +19,7 @@ source_set("jni") {
]
deps = [
"//base",
"//flutter/fml",
"//lib/tonic",
]
}

View File

@@ -4,22 +4,20 @@
#include "flutter/lib/jni/dart_jni.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/logging.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/lib/jni/jni_api.h"
#include "flutter/lib/jni/jni_array.h"
#include "flutter/lib/jni/jni_class.h"
#include "flutter/lib/jni/jni_object.h"
#include "flutter/lib/jni/jni_string.h"
#include "lib/tonic/converter/dart_converter.h"
#include "lib/tonic/dart_args.h"
#include "lib/tonic/dart_binding_macros.h"
#include "lib/tonic/converter/dart_converter.h"
namespace blink {
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
using fml::jni::ScopedJavaGlobalRef;
using fml::jni::ScopedJavaLocalRef;
using tonic::DartConverter;
using tonic::StdStringToDart;
using tonic::ToDart;
@@ -63,7 +61,7 @@ bool CheckJniException(JNIEnv* env, Dart_Handle* exception) {
jthrowable java_throwable = env->ExceptionOccurred();
env->ExceptionClear();
std::string info = base::android::GetJavaExceptionInfo(env, java_throwable);
std::string info = fml::jni::GetJavaExceptionInfo(env, java_throwable);
*exception = StdStringToDart(info);
return true;
@@ -210,7 +208,7 @@ void DartJni::InitForGlobal(DartJniIsolateDataProvider provider) {
}
void DartJni::InitForIsolate() {
DCHECK(g_natives);
FTL_DCHECK(g_natives);
Dart_Handle jni_library = Dart_LookupLibrary(ToDart("dart:jni"));
DART_CHECK_VALID(jni_library)
@@ -232,53 +230,54 @@ void DartJni::InitForIsolate() {
}
bool DartJni::InitJni() {
JNIEnv* env = base::android::AttachCurrentThread();
JNIEnv* env = fml::jni::AttachCurrentThread();
DCHECK(!g_jvm_data);
FTL_DCHECK(!g_jvm_data);
g_jvm_data = new DartJniJvmData();
g_jvm_data->class_loader.Reset(base::android::GetClassLoader(env));
// TODO: The class loader must be set here.
// g_jvm_data->class_loader.Reset(class_loader);
ScopedJavaLocalRef<jclass> class_loader_clazz(
env, env->FindClass("java/lang/ClassLoader"));
CHECK(!base::android::ClearException(env));
FTL_CHECK(!fml::jni::ClearException(env));
g_jvm_data->class_loader_load_class_method_id =
env->GetMethodID(class_loader_clazz.obj(), "loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;");
CHECK(!base::android::ClearException(env));
FTL_CHECK(!fml::jni::ClearException(env));
g_jvm_data->class_clazz.Reset(env, env->FindClass("java/lang/Class"));
CHECK(!base::android::ClearException(env));
FTL_CHECK(!fml::jni::ClearException(env));
g_jvm_data->class_get_name_method_id = env->GetMethodID(
g_jvm_data->class_clazz.obj(), "getName", "()Ljava/lang/String;");
CHECK(!base::android::ClearException(env));
FTL_CHECK(!fml::jni::ClearException(env));
return true;
}
void DartJni::OnThreadExit() {
base::android::DetachFromVM();
fml::jni::DetachFromVM();
}
ScopedJavaLocalRef<jclass> DartJni::GetClass(JNIEnv* env, const char* name) {
jobject clazz = env->CallObjectMethod(
g_jvm_data->class_loader.obj(),
g_jvm_data->class_loader_load_class_method_id,
base::android::ConvertUTF8ToJavaString(env, name).obj());
jobject clazz =
env->CallObjectMethod(g_jvm_data->class_loader.obj(),
g_jvm_data->class_loader_load_class_method_id,
fml::jni::StringToJavaString(env, name).obj());
return ScopedJavaLocalRef<jclass>(env, static_cast<jclass>(clazz));
}
std::string DartJni::GetObjectClassName(JNIEnv* env, jobject obj) {
jclass clazz = env->GetObjectClass(obj);
DCHECK(clazz);
FTL_DCHECK(clazz);
jstring name = static_cast<jstring>(
env->CallObjectMethod(clazz, g_jvm_data->class_get_name_method_id));
DCHECK(name);
FTL_DCHECK(name);
return base::android::ConvertJavaStringToUTF8(env, name);
return fml::jni::JavaStringToString(env, name);
}
jstring DartJni::DartToJavaString(JNIEnv* env,
@@ -315,14 +314,14 @@ jclass DartJni::class_clazz() {
Dart_Handle DartJni::jni_object_type() {
Dart_Handle object_type =
Dart_HandleFromPersistent(IsolateData()->jni_object_type);
DCHECK(!Dart_IsError(object_type));
FTL_DCHECK(!Dart_IsError(object_type));
return object_type;
}
Dart_Handle DartJni::jni_float_type() {
Dart_Handle float_type =
Dart_HandleFromPersistent(IsolateData()->jni_float_type);
DCHECK(!Dart_IsError(float_type));
FTL_DCHECK(!Dart_IsError(float_type));
return float_type;
}

View File

@@ -7,14 +7,13 @@
#include <vector>
#include "base/android/jni_android.h"
#include "base/android/jni_utils.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "lib/tonic/dart_library_natives.h"
#include "lib/tonic/dart_wrappable.h"
#define ENTER_JNI() \
JNIEnv* env = base::android::AttachCurrentThread(); \
base::android::ScopedJavaLocalFrame java_frame(env);
#define ENTER_JNI() \
JNIEnv* env = fml::jni::AttachCurrentThread(); \
fml::jni::ScopedJavaLocalFrame java_frame(env);
namespace blink {
@@ -36,8 +35,8 @@ class DartJni {
static bool InitJni();
static void OnThreadExit();
static base::android::ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env,
const char* name);
static fml::jni::ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env,
const char* name);
static std::string GetObjectClassName(JNIEnv* env, jobject obj);

View File

@@ -14,7 +14,8 @@ int64_t JniApi::FromReflectedField(const JniObject* field) {
ENTER_JNI();
jfieldID result = env->FromReflectedField(field->java_object());
if (CheckJniException(env, &exception)) goto fail;
if (CheckJniException(env, &exception))
goto fail;
return reinterpret_cast<int64_t>(result);
}
@@ -30,7 +31,8 @@ int64_t JniApi::FromReflectedMethod(const JniObject* method) {
ENTER_JNI();
jmethodID result = env->FromReflectedMethod(method->java_object());
if (CheckJniException(env, &exception)) goto fail;
if (CheckJniException(env, &exception))
goto fail;
return reinterpret_cast<int64_t>(result);
}
@@ -42,7 +44,7 @@ fail:
ftl::RefPtr<JniObject> JniApi::GetApplicationContext() {
ENTER_JNI();
return JniObject::Create(env, base::android::GetApplicationContext());
return JniObject::Create(env, fml::jni::GetAndroidApplicationContext());
}
ftl::RefPtr<JniObject> JniApi::GetClassLoader() {
@@ -50,4 +52,4 @@ ftl::RefPtr<JniObject> JniApi::GetClassLoader() {
return JniObject::Create(env, DartJni::class_loader());
}
} // namespace blink
} // namespace blink

View File

@@ -9,7 +9,7 @@
namespace blink {
using tonic::ToDart;
using base::android::ScopedJavaLocalRef;
using fml::jni::ScopedJavaLocalRef;
IMPLEMENT_WRAPPERTYPEINFO(jni, JniClass);

View File

@@ -7,7 +7,6 @@
#include <jni.h>
#include "base/android/jni_android.h"
#include "flutter/lib/jni/jni_object.h"
#include "lib/tonic/dart_wrappable.h"

View File

@@ -4,7 +4,7 @@
#include "flutter/lib/jni/jni_object.h"
#include "base/strings/string_util.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/lib/jni/dart_jni.h"
#include "flutter/lib/jni/jni_array.h"
#include "flutter/lib/jni/jni_class.h"
@@ -30,7 +30,7 @@ ftl::RefPtr<JniObject> JniObject::Create(JNIEnv* env, jobject object) {
result = ftl::MakeRefCounted<JniString>(env, static_cast<jstring>(object));
} else if (class_name == "java.lang.Class") {
result = ftl::MakeRefCounted<JniClass>(env, static_cast<jclass>(object));
} else if (base::StartsWith(class_name, "[L", base::CompareCase::SENSITIVE)) {
} else if (::strncmp(class_name.c_str(), "[L", ::strlen("[L")) == 0) {
result = ftl::MakeRefCounted<JniObjectArray>(
env, static_cast<jobjectArray>(object));
} else if (class_name == "[Z") {

View File

@@ -7,7 +7,7 @@
#include <jni.h>
#include "base/android/jni_android.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "lib/tonic/dart_wrappable.h"
namespace blink {
@@ -72,7 +72,7 @@ class JniObject : public ftl::RefCountedThreadSafe<JniObject>,
protected:
JniObject(JNIEnv* env, jobject object);
base::android::ScopedJavaGlobalRef<jobject> object_;
fml::jni::ScopedJavaGlobalRef<jobject> object_;
};
} // namespace blink

View File

@@ -101,13 +101,12 @@ source_set("common") {
deps = [
":generate_embedder_diagnostic_server_resources_cc",
"//base",
"//base:i18n",
"//dart/runtime:libdart",
"//dart/runtime/vm:libdart_platform",
"//flutter/assets",
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/glue",
"//flutter/lib/ui",
"//flutter/runtime",

View File

@@ -4,10 +4,8 @@
#include "flutter/shell/common/animator.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/trace_event/trace_event.h"
#include "flutter/common/threads.h"
#include "flutter/fml/trace_event.h"
#include "lib/ftl/time/stopwatch.h"
namespace shell {
@@ -51,8 +49,7 @@ void Animator::BeginFrame(ftl::TimePoint frame_time) {
// If we still don't have valid continuation, the pipeline is currently
// full because the consumer is being too slow. Try again at the next
// frame interval.
TRACE_EVENT_INSTANT0("flutter", "ConsumerSlowDefer",
TRACE_EVENT_SCOPE_PROCESS);
TRACE_EVENT_INSTANT0("flutter", "ConsumerSlowDefer");
RequestFrame();
return;
}
@@ -60,7 +57,7 @@ void Animator::BeginFrame(ftl::TimePoint frame_time) {
// We have acquired a valid continuation from the pipeline and are ready
// to service potential frame.
DCHECK(producer_continuation_);
FTL_DCHECK(producer_continuation_);
// TODO(abarth): We should use |frame_time| instead, but the frame time we get
// on Android appears to be unstable.
@@ -107,7 +104,7 @@ void Animator::RequestFrame() {
blink::Threads::UI()->PostTask([self = weak_factory_.GetWeakPtr()]() {
if (!self.get())
return;
TRACE_EVENT_INSTANT0("flutter", "RequestFrame", TRACE_EVENT_SCOPE_PROCESS);
TRACE_EVENT_INSTANT0("flutter", "RequestFrame");
self->AwaitVSync();
});
}

View File

@@ -90,8 +90,7 @@ void Engine::RunBundle(const std::string& bundle_path) {
} else {
std::vector<uint8_t> kernel;
if (GetAssetAsBuffer(blink::kKernelAssetKey, &kernel)) {
runtime_->dart_controller()->RunFromKernel(kernel.data(),
kernel.size());
runtime_->dart_controller()->RunFromKernel(kernel.data(), kernel.size());
return;
}
std::vector<uint8_t> snapshot;
@@ -304,7 +303,7 @@ void Engine::ConfigureAssetBundle(const std::string& path) {
// custom font loading in hot reload.
if (::stat(path.c_str(), &stat_result) != 0) {
LOG(INFO) << "Could not configure asset bundle at path: " << path;
FTL_LOG(INFO) << "Could not configure asset bundle at path: " << path;
return;
}

View File

@@ -159,7 +159,7 @@ void PlatformView::SetupResourceContextOnIOThreadPerform(
bool current = ResourceContextMakeCurrent();
if (!current) {
LOG(WARNING)
FTL_LOG(WARNING)
<< "WARNING: Could not setup an OpenGL context on the resource loader.";
latch->Signal();
return;

View File

@@ -9,13 +9,13 @@
#include <string>
#include <vector>
#include "base/base64.h"
#include "flutter/common/threads.h"
#include "flutter/shell/common/picture_serializer.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/shell.h"
#include "lib/ftl/memory/weak_ptr.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/src/utils/SkBase64.h"
namespace shell {
namespace {
@@ -271,14 +271,14 @@ bool PlatformViewServiceProtocol::Screenshot(const char* method,
if (!png)
return ErrorServer(json_object, "can not encode screenshot");
std::string base64;
base::Base64Encode(
base::StringPiece(static_cast<const char*>(png->data()), png->size()),
&base64);
size_t b64_size = SkBase64::Encode(png->data(), png->size(), nullptr);
SkAutoTMalloc<char> b64_data(b64_size);
SkBase64::Encode(png->data(), png->size(), b64_data.get());
std::stringstream response;
response << "{\"type\":\"Screenshot\","
<< "\"screenshot\":\"" << base64 << "\"}";
<< "\"screenshot\":\"" << std::string{b64_data.get(), b64_size}
<< "\"}";
*json_object = strdup(response.str().c_str());
return true;
}

View File

@@ -7,20 +7,14 @@
#include <fcntl.h>
#include <memory>
#include <sstream>
#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/memory/discardable_memory.h"
#include "base/memory/discardable_memory_allocator.h"
#include "base/posix/eintr_wrapper.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "dart/runtime/include/dart_tools_api.h"
#include "flutter/common/settings.h"
#include "flutter/common/threads.h"
#include "flutter/glue/task_runner_adaptor.h"
#include "flutter/fml/icu_util.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/trace_event.h"
#include "flutter/runtime/dart_init.h"
#include "flutter/shell/common/diagnostic/diagnostic_server.h"
#include "flutter/shell/common/engine.h"
@@ -43,40 +37,25 @@ bool IsViewInvalid(const ftl::WeakPtr<PlatformView>& platform_view) {
}
template <typename T>
bool GetSwitchValue(const base::CommandLine& command_line,
bool GetSwitchValue(const ftl::CommandLine& command_line,
Switch sw,
T* result) {
auto port_string = command_line.GetSwitchValueASCII(FlagForSwitch(sw));
std::stringstream stream(port_string);
std::string switch_string;
if (!command_line.GetOptionValue(FlagForSwitch(sw), &switch_string)) {
return false;
}
std::stringstream stream(switch_string);
T value = 0;
if (stream >> value) {
*result = value;
return true;
}
return false;
}
class NonDiscardableMemory : public base::DiscardableMemory {
public:
explicit NonDiscardableMemory(size_t size) : data_(new uint8_t[size]) {}
bool Lock() override { return false; }
void Unlock() override {}
void* data() const override { return data_.get(); }
private:
std::unique_ptr<uint8_t[]> data_;
};
class NonDiscardableMemoryAllocator : public base::DiscardableMemoryAllocator {
public:
scoped_ptr<base::DiscardableMemory> AllocateLockedDiscardableMemory(
size_t size) override {
return make_scoped_ptr(new NonDiscardableMemory(size));
}
};
base::LazyInstance<NonDiscardableMemoryAllocator> g_discardable;
void ServiceIsolateHook(bool running_precompiled) {
if (!running_precompiled) {
const blink::Settings& settings = blink::Settings::Get();
@@ -87,28 +66,21 @@ void ServiceIsolateHook(bool running_precompiled) {
} // namespace
Shell::Shell() {
DCHECK(!g_shell);
Shell::Shell(ftl::CommandLine command_line)
: command_line_(std::move(command_line)) {
FTL_DCHECK(!g_shell);
base::Thread::Options options;
gpu_thread_.reset(new fml::Thread("gpu_thread"));
ui_thread_.reset(new fml::Thread("ui_thread"));
io_thread_.reset(new fml::Thread("io_thread"));
gpu_thread_.reset(new base::Thread("gpu_thread"));
gpu_thread_->StartWithOptions(options);
ui_thread_.reset(new base::Thread("ui_thread"));
ui_thread_->StartWithOptions(options);
io_thread_.reset(new base::Thread("io_thread"));
io_thread_->StartWithOptions(options);
blink::Threads threads(ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
base::MessageLoop::current()->task_runner()),
ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
gpu_thread_->message_loop()->task_runner()),
ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
ui_thread_->message_loop()->task_runner()),
ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
io_thread_->message_loop()->task_runner()));
// Since we are not using fml::Thread, we need to initialize the message loop
// manually.
fml::MessageLoop::EnsureInitializedForCurrentThread();
blink::Threads threads(fml::MessageLoop::GetCurrent().GetTaskRunner(),
gpu_thread_->GetTaskRunner(),
ui_thread_->GetTaskRunner(),
io_thread_->GetTaskRunner());
blink::Threads::Set(threads);
blink::Threads::Gpu()->PostTask([this]() { InitGpuThread(); });
@@ -121,34 +93,22 @@ Shell::Shell() {
Shell::~Shell() {}
void Shell::InitStandalone(std::string icu_data_path,
void Shell::InitStandalone(ftl::CommandLine command_line,
std::string icu_data_path,
std::string application_library_path) {
TRACE_EVENT0("flutter", "Shell::InitStandalone");
ftl::UniqueFD icu_fd(
icu_data_path.empty() ? -1 : HANDLE_EINTR(::open(icu_data_path.c_str(),
O_RDONLY)));
if (icu_fd.get() == -1) {
// If the embedder did not specify a valid file, fallback to looking through
// internal search paths.
FTL_CHECK(base::i18n::InitializeICU());
} else {
FTL_CHECK(base::i18n::InitializeICUWithFileDescriptor(
icu_fd.get(), base::MemoryMappedFile::Region::kWholeFile));
icu_fd.reset();
}
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
fml::icu::InitializeICU(icu_data_path);
blink::Settings settings;
settings.application_library_path = application_library_path;
// Enable Observatory
settings.enable_observatory =
!command_line.HasSwitch(FlagForSwitch(Switch::DisableObservatory));
!command_line.HasOption(FlagForSwitch(Switch::DisableObservatory));
// Set Observatory Port
if (command_line.HasSwitch(FlagForSwitch(Switch::DeviceObservatoryPort))) {
if (command_line.HasOption(FlagForSwitch(Switch::DeviceObservatoryPort))) {
if (!GetSwitchValue(command_line, Switch::DeviceObservatoryPort,
&settings.observatory_port)) {
FTL_LOG(INFO)
@@ -159,12 +119,12 @@ void Shell::InitStandalone(std::string icu_data_path,
// Checked mode overrides.
settings.dart_non_checked_mode =
command_line.HasSwitch(FlagForSwitch(Switch::DartNonCheckedMode));
command_line.HasOption(FlagForSwitch(Switch::DartNonCheckedMode));
settings.enable_diagnostic =
!command_line.HasSwitch(FlagForSwitch(Switch::DisableDiagnostic));
!command_line.HasOption(FlagForSwitch(Switch::DisableDiagnostic));
if (command_line.HasSwitch(FlagForSwitch(Switch::DeviceDiagnosticPort))) {
if (command_line.HasOption(FlagForSwitch(Switch::DeviceDiagnosticPort))) {
if (!GetSwitchValue(command_line, Switch::DeviceDiagnosticPort,
&settings.diagnostic_port)) {
FTL_LOG(INFO)
@@ -174,63 +134,62 @@ void Shell::InitStandalone(std::string icu_data_path,
}
settings.start_paused =
command_line.HasSwitch(FlagForSwitch(Switch::StartPaused));
command_line.HasOption(FlagForSwitch(Switch::StartPaused));
settings.enable_dart_profiling =
command_line.HasSwitch(FlagForSwitch(Switch::EnableDartProfiling));
command_line.HasOption(FlagForSwitch(Switch::EnableDartProfiling));
settings.endless_trace_buffer =
command_line.HasSwitch(FlagForSwitch(Switch::EndlessTraceBuffer));
command_line.HasOption(FlagForSwitch(Switch::EndlessTraceBuffer));
settings.trace_startup =
command_line.HasSwitch(FlagForSwitch(Switch::TraceStartup));
command_line.HasOption(FlagForSwitch(Switch::TraceStartup));
settings.aot_snapshot_path =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::AotSnapshotPath));
settings.aot_vm_snapshot_data_filename = command_line.GetSwitchValueASCII(
FlagForSwitch(Switch::AotVmSnapshotData));
settings.aot_vm_snapshot_instr_filename = command_line.GetSwitchValueASCII(
FlagForSwitch(Switch::AotVmSnapshotInstructions));
settings.aot_isolate_snapshot_data_filename =
command_line.GetSwitchValueASCII(
FlagForSwitch(Switch::AotIsolateSnapshotData));
settings.aot_isolate_snapshot_instr_filename =
command_line.GetSwitchValueASCII(
FlagForSwitch(Switch::AotIsolateSnapshotInstructions));
command_line.GetOptionValue(FlagForSwitch(Switch::AotSnapshotPath),
&settings.aot_snapshot_path);
settings.temp_directory_path =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::CacheDirPath));
command_line.GetOptionValue(FlagForSwitch(Switch::AotVmSnapshotData),
&settings.aot_vm_snapshot_data_filename);
command_line.GetOptionValue(FlagForSwitch(Switch::AotVmSnapshotInstructions),
&settings.aot_vm_snapshot_instr_filename);
command_line.GetOptionValue(FlagForSwitch(Switch::AotIsolateSnapshotData),
&settings.aot_isolate_snapshot_data_filename);
command_line.GetOptionValue(
FlagForSwitch(Switch::AotIsolateSnapshotInstructions),
&settings.aot_isolate_snapshot_instr_filename);
command_line.GetOptionValue(FlagForSwitch(Switch::CacheDirPath),
&settings.temp_directory_path);
settings.use_test_fonts =
command_line.HasSwitch(FlagForSwitch(Switch::UseTestFonts));
command_line.HasOption(FlagForSwitch(Switch::UseTestFonts));
if (command_line.HasSwitch(FlagForSwitch(Switch::DartFlags))) {
std::stringstream stream(
command_line.GetSwitchValueNative(FlagForSwitch(Switch::DartFlags)));
std::string all_dart_flags;
if (command_line.GetOptionValue(FlagForSwitch(Switch::DartFlags),
&all_dart_flags)) {
std::stringstream stream(all_dart_flags);
std::istream_iterator<std::string> end;
for (std::istream_iterator<std::string> it(stream); it != end; ++it)
settings.dart_flags.push_back(*it);
}
if (command_line.HasSwitch(FlagForSwitch(Switch::LogTag))) {
settings.log_tag =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::LogTag));
}
command_line.GetOptionValue(FlagForSwitch(Switch::LogTag), &settings.log_tag);
blink::Settings::Set(settings);
Init();
Init(std::move(command_line));
}
void Shell::Init() {
base::DiscardableMemoryAllocator::SetInstance(&g_discardable.Get());
void Shell::Init(ftl::CommandLine command_line) {
#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE
InitSkiaEventTracer();
#endif
FTL_DCHECK(!g_shell);
g_shell = new Shell();
g_shell = new Shell(std::move(command_line));
blink::Threads::UI()->PostTask(Engine::Init);
}
@@ -239,44 +198,51 @@ Shell& Shell::Shared() {
return *g_shell;
}
const ftl::CommandLine& Shell::GetCommandLine() const {
return command_line_;
}
TracingController& Shell::tracing_controller() {
return tracing_controller_;
}
void Shell::InitGpuThread() {
gpu_thread_checker_.reset(new base::ThreadChecker());
gpu_thread_checker_.reset(new fml::ThreadChecker());
}
void Shell::InitUIThread() {
ui_thread_checker_.reset(new base::ThreadChecker());
ui_thread_checker_.reset(new fml::ThreadChecker());
}
void Shell::AddRasterizer(const ftl::WeakPtr<Rasterizer>& rasterizer) {
FTL_DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
FTL_DCHECK(gpu_thread_checker_ &&
gpu_thread_checker_->IsCalledOnValidThread());
rasterizers_.push_back(rasterizer);
}
void Shell::PurgeRasterizers() {
FTL_DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
FTL_DCHECK(gpu_thread_checker_ &&
gpu_thread_checker_->IsCalledOnValidThread());
rasterizers_.erase(
std::remove_if(rasterizers_.begin(), rasterizers_.end(), IsInvalid),
rasterizers_.end());
}
void Shell::GetRasterizers(std::vector<ftl::WeakPtr<Rasterizer>>* rasterizers) {
FTL_DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
FTL_DCHECK(gpu_thread_checker_ &&
gpu_thread_checker_->IsCalledOnValidThread());
*rasterizers = rasterizers_;
}
void Shell::AddPlatformView(const ftl::WeakPtr<PlatformView>& platform_view) {
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
if (platform_view) {
platform_views_.push_back(platform_view);
}
}
void Shell::PurgePlatformViews() {
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
platform_views_.erase(std::remove_if(platform_views_.begin(),
platform_views_.end(), IsViewInvalid),
platform_views_.end());
@@ -284,7 +250,7 @@ void Shell::PurgePlatformViews() {
void Shell::GetPlatformViews(
std::vector<ftl::WeakPtr<PlatformView>>* platform_views) {
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
*platform_views = platform_views_;
}
@@ -351,7 +317,7 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
int64_t* dart_isolate_id,
std::string* isolate_name,
ftl::AutoResetWaitableEvent* latch) {
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
*view_existed = false;

View File

@@ -5,8 +5,10 @@
#ifndef SHELL_COMMON_SHELL_H_
#define SHELL_COMMON_SHELL_H_
#include "base/threading/thread.h"
#include "flutter/fml/thread.h"
#include "flutter/fml/thread_checker.h"
#include "flutter/shell/common/tracing_controller.h"
#include "lib/ftl/command_line.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/memory/ref_ptr.h"
#include "lib/ftl/memory/weak_ptr.h"
@@ -22,12 +24,14 @@ class Shell {
public:
~Shell();
static void InitStandalone(std::string icu_data_path = "",
static void InitStandalone(ftl::CommandLine command_line,
std::string icu_data_path = "",
std::string application_library_path = "");
static void Init();
static Shell& Shared();
const ftl::CommandLine& GetCommandLine() const;
TracingController& tracing_controller();
// Maintain a list of rasterizers.
@@ -65,7 +69,9 @@ class Shell {
std::string* isolate_name);
private:
Shell();
static void Init(ftl::CommandLine command_line);
Shell(ftl::CommandLine command_line);
void InitGpuThread();
void InitUIThread();
@@ -83,12 +89,14 @@ class Shell {
std::string* isolate_name,
ftl::AutoResetWaitableEvent* latch);
std::unique_ptr<base::Thread> gpu_thread_;
std::unique_ptr<base::Thread> ui_thread_;
std::unique_ptr<base::Thread> io_thread_;
ftl::CommandLine command_line_;
std::unique_ptr<base::ThreadChecker> gpu_thread_checker_;
std::unique_ptr<base::ThreadChecker> ui_thread_checker_;
std::unique_ptr<fml::Thread> gpu_thread_;
std::unique_ptr<fml::Thread> ui_thread_;
std::unique_ptr<fml::Thread> io_thread_;
std::unique_ptr<fml::ThreadChecker> gpu_thread_checker_;
std::unique_ptr<fml::ThreadChecker> ui_thread_checker_;
TracingController tracing_controller_;

View File

@@ -4,71 +4,81 @@
#include "flutter/shell/common/skia_event_tracer_impl.h"
#include "base/trace_event/trace_event.h"
#define TRACE_EVENT_HIDE_MACROS
#include "flutter/fml/trace_event.h"
#include <vector>
#include "lib/ftl/logging.h"
#include "third_party/skia/include/utils/SkEventTracer.h"
#include "third_party/skia/src/core/SkTraceEventCommon.h"
namespace skia {
class SkChromiumEventTracer: public SkEventTracer {
const uint8_t* getCategoryGroupEnabled(const char* name) override;
const char* getCategoryGroupName(const uint8_t* categoryEnabledFlag) override;
class FlutterEventTracer : public SkEventTracer {
public:
static constexpr const char* kSkiaTag = "skia";
FlutterEventTracer() = default;
SkEventTracer::Handle addTraceEvent(char phase,
const uint8_t* categoryEnabledFlag,
const uint8_t* category_enabled_flag,
const char* name,
uint64_t id,
int32_t numArgs,
const char** argNames,
const uint8_t* argTypes,
const uint64_t* argValues,
uint8_t flags) override;
void updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
int num_args,
const char** p_arg_names,
const uint8_t* p_arg_types,
const uint64_t* p_arg_values,
uint8_t flags) override {
switch (phase) {
case TRACE_EVENT_PHASE_BEGIN:
case TRACE_EVENT_PHASE_COMPLETE:
fml::tracing::TraceEvent0(kSkiaTag, name);
break;
case TRACE_EVENT_PHASE_END:
fml::tracing::TraceEventEnd(name);
break;
case TRACE_EVENT_PHASE_INSTANT:
fml::tracing::TraceEventInstant0(kSkiaTag, name);
break;
case TRACE_EVENT_PHASE_ASYNC_BEGIN:
fml::tracing::TraceEventAsyncBegin0(kSkiaTag, name, id);
break;
case TRACE_EVENT_PHASE_ASYNC_END:
fml::tracing::TraceEventAsyncEnd0(kSkiaTag, name, id);
break;
default:
break;
}
return 0;
}
void updateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name,
SkEventTracer::Handle handle) override;
SkEventTracer::Handle handle) override {
// This is only ever called from a scoped trace event so we will just end
// the section.
fml::tracing::TraceEventEnd(name);
}
const uint8_t* getCategoryGroupEnabled(const char* name) override {
static const uint8_t kYes = 1;
return &kYes;
}
const char* getCategoryGroupName(
const uint8_t* category_enabled_flag) override {
return kSkiaTag;
}
private:
FTL_DISALLOW_COPY_AND_ASSIGN(FlutterEventTracer);
};
const uint8_t*
SkChromiumEventTracer::getCategoryGroupEnabled(const char* name) {
return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(name);
}
const char* SkChromiumEventTracer::getCategoryGroupName(
const uint8_t* categoryEnabledFlag) {
return base::trace_event::TraceLog::GetCategoryGroupName(categoryEnabledFlag);
}
SkEventTracer::Handle
SkChromiumEventTracer::addTraceEvent(char phase,
const uint8_t* categoryEnabledFlag,
const char* name,
uint64_t id,
int32_t numArgs,
const char** argNames,
const uint8_t* argTypes,
const uint64_t* argValues,
uint8_t flags) {
base::trace_event::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT(
phase, categoryEnabledFlag, name, id, numArgs, argNames, argTypes,
(const long long unsigned int*)argValues, NULL, flags);
SkEventTracer::Handle result;
memcpy(&result, &handle, sizeof(result));
return result;
}
void
SkChromiumEventTracer::updateTraceEventDuration(
const uint8_t* categoryEnabledFlag,
const char *name,
SkEventTracer::Handle handle) {
base::trace_event::TraceEventHandle traceEventHandle;
memcpy(&traceEventHandle, &handle, sizeof(handle));
TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
categoryEnabledFlag, name, traceEventHandle);
}
} // namespace skia
void InitSkiaEventTracer() {
// Initialize the binding to Skia's tracing events. Skia will
// take ownership of and clean up the memory allocated here.
SkEventTracer::SetInstance(new skia::SkChromiumEventTracer());
SkEventTracer::SetInstance(new skia::FlutterEventTracer());
}

View File

@@ -6,17 +6,16 @@
#include <string>
#include "base/trace_event/trace_event.h"
#include "dart/runtime/include/dart_tools_api.h"
#include "flutter/common/threads.h"
#include "flutter/fml/trace_event.h"
#include "flutter/runtime/dart_init.h"
#include "flutter/shell/common/shell.h"
#include "lib/ftl/logging.h"
namespace shell {
TracingController::TracingController()
: picture_tracing_enabled_(false), tracing_active_(false) {
TracingController::TracingController() : tracing_active_(false) {
blink::SetEmbedderTracingCallbacks(
std::unique_ptr<blink::EmbedderTracingCallbacks>(
new blink::EmbedderTracingCallbacks([this]() { StartTracing(); },
@@ -27,122 +26,6 @@ TracingController::~TracingController() {
blink::SetEmbedderTracingCallbacks(nullptr);
}
static const char* WARN_UNUSED_RESULT
ConstructDartTimelineValue(std::vector<void*>& free_list,
const char* format,
...) {
static const char* kConversionError = "Argument Conversion Error";
const char* return_value = nullptr;
va_list args;
va_start(args, format);
char* string;
if (vasprintf(&string, format, args) != -1) {
return_value = string;
free_list.push_back(string);
} else {
return_value = kConversionError;
}
va_end(args);
return return_value;
}
static void BaseTraceEventCallback(base::TraceTicks timestamp,
char phase,
const unsigned char* category_group_enabled,
const char* name,
unsigned long long id,
int num_args,
const char* const arg_names[],
const unsigned char arg_types[],
const unsigned long long arg_values[],
unsigned int flags) {
Dart_Timeline_Event_Type type = Dart_Timeline_Event_Begin;
switch (phase) {
case TRACE_EVENT_PHASE_BEGIN:
type = Dart_Timeline_Event_Begin;
break;
case TRACE_EVENT_PHASE_END:
type = Dart_Timeline_Event_End;
break;
case TRACE_EVENT_PHASE_INSTANT:
type = Dart_Timeline_Event_Instant;
break;
case TRACE_EVENT_PHASE_ASYNC_BEGIN:
type = Dart_Timeline_Event_Async_Begin;
break;
case TRACE_EVENT_PHASE_ASYNC_END:
type = Dart_Timeline_Event_Async_End;
break;
case TRACE_EVENT_PHASE_COUNTER:
type = Dart_Timeline_Event_Counter;
break;
default:
// For TRACE_EVENT_PHASE_COMPLETE events, this callback still receives
// discrete begin-end pairs. This greatly simplifies things. We dont have
// to track the second timestamp to pass to the Dart timeline event
// because we never see a Dart_Timeline_Event_Duration event.
FTL_DCHECK(false) << "Unknown trace event phase";
return;
}
// Try to convert all arguments to strings to pass to the Dart timeline.
char const* dart_argument_values[num_args];
std::vector<void*> free_list;
#define CONVERT_VAL(format) \
dart_argument_values[i] = \
ConstructDartTimelineValue(free_list, format, arg_values[i])
for (int i = 0; i < num_args; i++) {
switch (arg_types[i]) {
case TRACE_VALUE_TYPE_BOOL:
CONVERT_VAL("%d");
break;
case TRACE_VALUE_TYPE_UINT:
CONVERT_VAL("%u");
break;
case TRACE_VALUE_TYPE_INT:
CONVERT_VAL("%d");
break;
case TRACE_VALUE_TYPE_DOUBLE:
CONVERT_VAL("%f");
break;
case TRACE_VALUE_TYPE_POINTER:
CONVERT_VAL("%p");
break;
case TRACE_VALUE_TYPE_STRING:
case TRACE_VALUE_TYPE_COPY_STRING:
// We don't need to reallocate for strings since the string will be
// used within this scope.
dart_argument_values[i] = reinterpret_cast<char*>(arg_values[i]);
break;
default:
continue;
}
}
#undef CONVERT_VAL
Dart_TimelineEvent(name, // label
timestamp.ToInternalValue(), // timestamp0
0, // timestamp1_or_async_id
type, // event type
num_args, // argument_count
(const char**)(arg_names), // argument_names
(const char**)(dart_argument_values) // argument_values
);
// Free up the items that had to be heap allocated (if any)
for (void* item : free_list) {
free(item);
}
}
static void AddTraceMetadata() {
blink::Threads::Gpu()->PostTask([]() { Dart_SetThreadName("gpu_thread"); });
blink::Threads::UI()->PostTask([]() { Dart_SetThreadName("ui_thread"); });
@@ -153,60 +36,14 @@ void TracingController::StartTracing() {
if (tracing_active_)
return;
tracing_active_ = true;
StartBaseTracing();
AddTraceMetadata();
}
void TracingController::StartBaseTracing() {
auto config = base::trace_event::TraceConfig(
"*,disabled-by-default-skia", base::trace_event::RECORD_CONTINUOUSLY);
auto log = base::trace_event::TraceLog::GetInstance();
log->SetEnabled(config, base::trace_event::TraceLog::MONITORING_MODE);
log->SetEventCallbackEnabled(config, &BaseTraceEventCallback);
}
void TracingController::StopTracing() {
if (!tracing_active_) {
return;
}
tracing_active_ = false;
StopBaseTracing();
}
void TracingController::StopBaseTracing() {
auto trace_log = base::trace_event::TraceLog::GetInstance();
trace_log->SetDisabled();
trace_log->SetEventCallbackDisabled();
}
std::string TracingController::TracePathWithExtension(
const std::string& directory,
const std::string& extension) const {
base::Time::Exploded exploded;
base::Time now = base::Time::Now();
now.LocalExplode(&exploded);
std::stringstream stream;
// Example: trace_2015-10-08_at_11.38.25.121_.extension
stream << directory << "/trace_" << exploded.year << "-" << exploded.month
<< "-" << exploded.day_of_month << "_at_" << exploded.hour << "."
<< exploded.minute << "." << exploded.second << "."
<< exploded.millisecond << "." << extension;
return stream.str();
}
std::string TracingController::PictureTracingPathForCurrentTime() const {
return PictureTracingPathForCurrentTime(traces_base_path_);
}
std::string TracingController::PictureTracingPathForCurrentTime(
const std::string& directory) const {
return TracePathWithExtension(directory, "skp");
}
} // namespace shell

View File

@@ -14,44 +14,18 @@ namespace shell {
class TracingController {
public:
TracingController();
~TracingController();
void StartTracing();
void StopTracing();
// Enables tracing in base. Only use this if an instance of a tracing
// controller cannot be obtained (can happen early in the lifecycle of the
// process). In most cases, the |StartTracing| method on an instance of the
// tracing controller should be used.
static void StartBaseTracing();
std::string PictureTracingPathForCurrentTime() const;
std::string PictureTracingPathForCurrentTime(
const std::string& directory) const;
bool tracing_active() const { return tracing_active_; }
void set_traces_base_path(std::string base_path) {
traces_base_path_ = std::move(base_path);
}
void set_picture_tracing_enabled(bool enabled) {
picture_tracing_enabled_ = enabled;
}
bool picture_tracing_enabled() const { return picture_tracing_enabled_; }
private:
std::string traces_base_path_;
bool picture_tracing_enabled_;
bool tracing_active_;
void StopBaseTracing();
std::string TracePathWithExtension(const std::string& directory,
const std::string& extension) const;
FTL_DISALLOW_COPY_AND_ASSIGN(TracingController);
};

View File

@@ -114,8 +114,6 @@ void GPURasterizer::DoDraw(std::unique_ptr<flow::LayerTree> layer_tree) {
DrawToSurface(*layer_tree);
DrawToTraceIfNecessary(*layer_tree);
last_layer_tree_ = std::move(layer_tree);
}
@@ -142,46 +140,4 @@ void GPURasterizer::DrawToSurface(flow::LayerTree& layer_tree) {
frame->Submit();
}
bool GPURasterizer::ShouldDrawToTrace(flow::LayerTree& layer_tree) {
if (Shell::Shared().tracing_controller().picture_tracing_enabled()) {
// Picture tracing is unconditionally enabled for all frames by the tracing
// controller.
return true;
}
const uint32_t threshold_interval = layer_tree.rasterizer_tracing_threshold();
if (threshold_interval == 0) {
// An interval of zero means tracing is disabled.
return false;
}
return compositor_context_.frame_time().LastLap().ToMillisecondsF() >
threshold_interval * 1e3 / 60.0;
}
void GPURasterizer::DrawToTraceIfNecessary(flow::LayerTree& layer_tree) {
if (!ShouldDrawToTrace(layer_tree)) {
return;
}
auto& tracing_controller = Shell::Shared().tracing_controller();
std::string path = tracing_controller.PictureTracingPathForCurrentTime();
LOG(INFO) << "Frame threshold exceeded. Capturing SKP to " << path;
SkPictureRecorder recorder;
recorder.beginRecording(layer_tree.frame_size().width(),
layer_tree.frame_size().height());
auto compositor_frame = compositor_context_.AcquireFrame(
nullptr, recorder.getRecordingCanvas(), false);
layer_tree.Raster(compositor_frame, true /* ignore raster cache */);
sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
SerializePicture(path, picture.get());
}
} // namespace shell

View File

@@ -45,10 +45,6 @@ class GPURasterizer : public Rasterizer {
void DrawToSurface(flow::LayerTree& layer_tree);
bool ShouldDrawToTrace(flow::LayerTree& layer_tree);
void DrawToTraceIfNecessary(flow::LayerTree& layer_tree);
FTL_DISALLOW_COPY_AND_ASSIGN(GPURasterizer);
};

View File

@@ -6,17 +6,6 @@ import("//flutter/shell/config.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
generate_jni("jni_headers") {
visibility = [ ":*" ]
sources = [
"io/flutter/view/FlutterMain.java",
"io/flutter/view/FlutterView.java",
"io/flutter/view/VsyncWaiter.java",
]
jni_package = "shell"
}
shared_library("sky_shell") {
visibility = [ ":*" ]
@@ -36,16 +25,17 @@ shared_library("sky_shell") {
"library_loader.cc",
"platform_view_android.cc",
"platform_view_android.h",
"platform_view_android_jni.cc",
"platform_view_android_jni.h",
"vsync_waiter_android.cc",
"vsync_waiter_android.h",
]
deps = [
":jni_headers",
"//base",
"//dart/runtime:libdart",
"//flutter/common",
"//flutter/flow",
"//flutter/fml",
"//flutter/lib/jni",
"//flutter/lib/ui",
"//flutter/runtime",
@@ -89,14 +79,15 @@ android_library("java") {
"io/flutter/plugin/common/JSONMessageCodec.java",
"io/flutter/plugin/common/JSONMethodCodec.java",
"io/flutter/plugin/common/MessageCodec.java",
"io/flutter/plugin/common/MethodCodec.java",
"io/flutter/plugin/common/MethodCall.java",
"io/flutter/plugin/common/MethodCodec.java",
"io/flutter/plugin/common/StandardMessageCodec.java",
"io/flutter/plugin/common/StandardMethodCodec.java",
"io/flutter/plugin/common/StringCodec.java",
"io/flutter/plugin/editing/InputConnectionAdaptor.java",
"io/flutter/plugin/editing/TextInputPlugin.java",
"io/flutter/plugin/platform/PlatformPlugin.java",
"io/flutter/util/PathUtils.java",
"io/flutter/view/AccessibilityBridge.java",
"io/flutter/view/FlutterMain.java",
"io/flutter/view/FlutterView.java",
@@ -105,10 +96,6 @@ android_library("java") {
"io/flutter/view/ResourcePaths.java",
"io/flutter/view/VsyncWaiter.java",
]
deps = [
"//base:base_java",
]
}
copy_ex("assets") {
@@ -139,6 +126,5 @@ android_apk("android") {
":assets",
":java",
":sky_shell",
"//base:base_java",
]
}

View File

@@ -6,79 +6,35 @@
#include <vector>
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/threading/simple_thread.h"
#include "dart/runtime/include/dart_tools_api.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/runtime/start_up.h"
#include "flutter/shell/common/shell.h"
#include "jni/FlutterMain_jni.h"
#include "lib/ftl/arraysize.h"
#include "lib/ftl/command_line.h"
#include "lib/ftl/macros.h"
using base::LazyInstance;
namespace shell {
namespace {
LazyInstance<std::unique_ptr<base::MessageLoop>> g_java_message_loop =
LAZY_INSTANCE_INITIALIZER;
void InitializeLogging() {
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
logging::InitLogging(settings);
// To view log output with IDs and timestamps use "adb logcat -v threadtime".
logging::SetLogItems(false, // Process ID
false, // Thread ID
false, // Timestamp
false); // Tick count
}
void InitializeTracing() {
base::FilePath path;
bool result = ::PathService::Get(base::DIR_ANDROID_APP_DATA, &path);
DCHECK(result);
shell::Shell::Shared().tracing_controller().set_traces_base_path(
path.AsUTF8Unsafe());
}
} // namespace
static void Init(JNIEnv* env,
jclass clazz,
jobject context,
jobjectArray jargs) {
base::PlatformThread::SetName("java_ui_thread");
base::android::ScopedJavaLocalRef<jobject> scoped_context(
fml::jni::ScopedJavaLocalRef<jobject> scoped_context(
env, env->NewLocalRef(context));
base::android::InitApplicationContext(env, scoped_context);
fml::jni::InitAndroidApplicationContext(scoped_context);
// Prepare command line arguments and initialize the shell.
std::vector<std::string> args;
args.push_back("sky_shell");
base::android::AppendJavaStringArrayToStringVector(env, jargs, &args);
for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
args.push_back(std::move(arg));
}
base::CommandLine::Init(0, nullptr);
base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
InitializeLogging();
g_java_message_loop.Get().reset(new base::MessageLoopForUI);
base::MessageLoopForUI::current()->Start();
Shell::InitStandalone();
InitializeTracing();
auto command_line = ftl::CommandLineFromIterators(args.begin(), args.end());
std::string icu_data_path =
command_line.GetOptionValueWithDefault("icu-data-file-path", "");
Shell::InitStandalone(std::move(command_line), std::move(icu_data_path));
}
static void RecordStartTimestamp(JNIEnv* env,
@@ -90,7 +46,26 @@ static void RecordStartTimestamp(JNIEnv* env,
}
bool RegisterFlutterMain(JNIEnv* env) {
return RegisterNativesImpl(env);
static const JNINativeMethod methods[] = {
{
.name = "nativeInit",
.signature = "(Landroid/content/Context;[Ljava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&Init),
},
{
.name = "nativeRecordStartTimestamp",
.signature = "(J)V",
.fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
},
};
jclass clazz = env->FindClass("io/flutter/view/FlutterMain");
if (clazz == nullptr) {
return false;
}
return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
}
} // namespace shell

View File

@@ -14,7 +14,6 @@ import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;
import java.util.ArrayList;
import org.chromium.base.TraceEvent;
/**
@@ -106,8 +105,6 @@ public class FlutterActivity extends Activity {
* Override this function to customize startup behavior.
*/
protected void onFlutterReady() {
TraceEvent.instant("FlutterActivity.onFlutterReady");
if (loadIntent(getIntent())) {
return;
}

View File

@@ -17,12 +17,13 @@ import android.view.HapticFeedbackConstants;
import android.view.SoundEffectConstants;
import android.view.View;
import io.flutter.util.PathUtils;
import io.flutter.plugin.common.ActivityLifecycleListener;
import io.flutter.plugin.common.FlutterMethodChannel.MethodCallHandler;
import io.flutter.plugin.common.FlutterMethodChannel.Response;
import io.flutter.plugin.common.MethodCall;
import org.chromium.base.PathUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

View File

@@ -0,0 +1,19 @@
// Copyright 2017 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.util;
import android.content.Context;
import java.io.IOException;
import java.lang.String;
public final class PathUtils {
public static String getDataDirectory(Context applicationContext) {
return applicationContext.getDir("sky_shell", Context.MODE_PRIVATE).getPath();
}
public static String getCacheDirectory(Context applicationContext) {
return applicationContext.getCacheDir().getPath();
}
}

View File

@@ -5,12 +5,15 @@
package io.flutter.view;
import android.content.Context;
import android.util.Log;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import io.flutter.util.PathUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -20,16 +23,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.chromium.base.JNINamespace;
import org.chromium.base.PathUtils;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.ProcessInitException;
/**
* A class to intialize the Flutter engine.
*/
@JNINamespace("shell")
public class FlutterMain {
private static final String TAG = "FlutterMain";
@@ -141,9 +137,8 @@ public class FlutterMain {
long initStartTimestampMillis = SystemClock.uptimeMillis();
initConfig(applicationContext);
initJavaUtils(applicationContext);
initResources(applicationContext);
initNative(applicationContext);
System.loadLibrary("sky_shell");
initAot(applicationContext);
// We record the initialization time using SystemClock because at the start of the
@@ -168,6 +163,8 @@ public class FlutterMain {
sResourceExtractor.waitForCompletion();
List<String> shellArgs = new ArrayList<>();
shellArgs.add("--icu-data-file-path=" +
new File(PathUtils.getDataDirectory(applicationContext), "icudtl.dat"));
if (args != null) {
Collections.addAll(shellArgs, args);
}
@@ -219,11 +216,6 @@ public class FlutterMain {
}
}
private static void initJavaUtils(Context applicationContext) {
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX,
applicationContext);
}
private static void initResources(Context applicationContext) {
Context context = applicationContext;
new ResourceCleaner(context).start();
@@ -237,16 +229,6 @@ public class FlutterMain {
.start();
}
private static void initNative(Context applicationContext) {
try {
LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER)
.ensureInitialized(applicationContext);
} catch (ProcessInitException e) {
Log.e(TAG, "Unable to load Sky Engine binary.", e);
throw new RuntimeException(e);
}
}
/**
* Returns a list of the file names at the root of the application's asset
* path.

View File

@@ -37,8 +37,6 @@ import io.flutter.plugin.common.StringCodec;
import io.flutter.plugin.editing.TextInputPlugin;
import io.flutter.plugin.platform.PlatformPlugin;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.json.JSONException;
import org.json.JSONObject;
@@ -55,7 +53,6 @@ import java.util.Map;
/**
* An Android view containing a Flutter app.
*/
@JNINamespace("shell")
public class FlutterView extends SurfaceView
implements AccessibilityManager.AccessibilityStateChangeListener {
@@ -599,7 +596,6 @@ public class FlutterView extends SurfaceView
}
// Called by native to send us a platform message.
@CalledByNative
private void handlePlatformMessage(String channel, ByteBuffer message, final int responseId) {
OnBinaryMessageListenerAsync listener = mMessageListeners.get(channel);
if (listener != null) {
@@ -626,7 +622,6 @@ public class FlutterView extends SurfaceView
private final Map<Integer, BinaryMessageReplyCallback> mPendingResponses = new HashMap<>();
// Called by native to respond to a platform message that we sent.
@CalledByNative
private void handlePlatformMessageResponse(int responseId, ByteBuffer response) {
BinaryMessageReplyCallback callback = mPendingResponses.remove(responseId);
if (callback != null) {
@@ -638,7 +633,6 @@ public class FlutterView extends SurfaceView
}
}
@CalledByNative
private void updateSemantics(ByteBuffer buffer, String[] strings) {
if (mAccessibilityNodeProvider != null) {
buffer.order(ByteOrder.LITTLE_ENDIAN);

View File

@@ -11,8 +11,6 @@ import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.util.Log;
import org.chromium.base.PathUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
@@ -24,6 +22,8 @@ import java.util.HashSet;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import io.flutter.util.PathUtils;
/**
* A class to intialize the native code.
**/

View File

@@ -6,12 +6,7 @@ package io.flutter.view;
import android.view.Choreographer;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
@JNINamespace("shell")
public class VsyncWaiter {
@CalledByNative
public static void asyncWaitForVsync(final long cookie) {
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
@Override

View File

@@ -2,52 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/base_jni_onload.h"
#include "base/android/base_jni_registrar.h"
#include "base/android/jni_android.h"
#include "base/android/jni_registrar.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/bind.h"
#include "base/logging.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/lib/jni/dart_jni.h"
#include "flutter/shell/platform/android/flutter_main.h"
#include "flutter/shell/platform/android/platform_view_android.h"
#include "flutter/shell/platform/android/vsync_waiter_android.h"
namespace {
base::android::RegistrationMethod kSkyRegisteredMethods[] = {
{"FlutterView", shell::PlatformViewAndroid::Register},
{"VsyncWaiter", shell::VsyncWaiterAndroid::Register},
{"FlutterMain", shell::RegisterFlutterMain},
};
bool RegisterJNI(JNIEnv* env) {
if (!base::android::RegisterJni(env))
return false;
return RegisterNativeMethods(env, kSkyRegisteredMethods,
arraysize(kSkyRegisteredMethods));
}
bool InitJNI() {
return blink::DartJni::InitJni();
}
} // namespace
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
std::vector<base::android::RegisterCallback> register_callbacks;
register_callbacks.push_back(base::Bind(&RegisterJNI));
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// Initialize the Java VM.
fml::jni::InitJavaVM(vm);
std::vector<base::android::InitCallback> init_callbacks;
init_callbacks.push_back(base::Bind(&InitJNI));
JNIEnv* env = fml::jni::AttachCurrentThread();
bool result = false;
if (!base::android::OnJNIOnLoadRegisterJNI(vm, register_callbacks) ||
!base::android::OnJNIOnLoadInit(init_callbacks)) {
return -1;
}
// Register FlutterMain.
result = shell::RegisterFlutterMain(env);
FTL_CHECK(result);
// Register PlatformView
result = shell::PlatformViewAndroid::Register(env);
FTL_CHECK(result);
// Register VSyncWaiter.
result = shell::VsyncWaiterAndroid::Register(env);
FTL_CHECK(result);
// Register DartJni
result = blink::DartJni::InitJni();
FTL_CHECK(result);
return JNI_VERSION_1_4;
}

View File

@@ -11,14 +11,14 @@
#include <utility>
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "flutter/common/threads.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "flutter/shell/gpu/gpu_rasterizer.h"
#include "flutter/shell/platform/android/android_surface_gl.h"
#include "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/shell/platform/android/vsync_waiter_android.h"
#include "jni/FlutterView_jni.h"
#include "lib/ftl/functional/make_copyable.h"
#if SHELL_ENABLE_VULKAN
@@ -110,19 +110,18 @@ PlatformViewAndroid::PlatformViewAndroid()
PlatformViewAndroid::~PlatformViewAndroid() = default;
void PlatformViewAndroid::Detach(JNIEnv* env, jobject obj) {
void PlatformViewAndroid::Detach() {
ReleaseSurface();
delete this;
}
void PlatformViewAndroid::SurfaceCreated(JNIEnv* env,
jobject obj,
jobject jsurface,
jint backgroundColor) {
// Note: This frame ensures that any local references used by
// ANativeWindow_fromSurface are released immediately. This is needed as a
// workaround for https://code.google.com/p/android/issues/detail?id=68174
base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
auto native_window = ftl::MakeRefCounted<AndroidNativeWindow>(
ANativeWindow_fromSurface(env, jsurface));
@@ -146,10 +145,7 @@ void PlatformViewAndroid::SurfaceCreated(JNIEnv* env,
] { rasterizer().Clear(backgroundColor, native_window_size); });
}
void PlatformViewAndroid::SurfaceChanged(JNIEnv* env,
jobject obj,
jint width,
jint height) {
void PlatformViewAndroid::SurfaceChanged(jint width, jint height) {
blink::Threads::Gpu()->PostTask([this, width, height]() {
if (android_surface_) {
android_surface_->OnScreenSurfaceResize(SkISize::Make(width, height));
@@ -165,49 +161,36 @@ void PlatformViewAndroid::UpdateThreadPriorities() {
[]() { ::setpriority(PRIO_PROCESS, gettid(), -1); });
}
void PlatformViewAndroid::SurfaceDestroyed(JNIEnv* env, jobject obj) {
void PlatformViewAndroid::SurfaceDestroyed() {
ReleaseSurface();
}
void PlatformViewAndroid::RunBundleAndSnapshot(JNIEnv* env,
jobject obj,
jstring java_bundle_path,
jstring java_snapshot_override) {
std::string bundle_path =
base::android::ConvertJavaStringToUTF8(env, java_bundle_path);
std::string snapshot_override =
java_snapshot_override
? base::android::ConvertJavaStringToUTF8(env, java_snapshot_override)
: "";
blink::Threads::UI()->PostTask(
[ engine = engine_->GetWeakPtr(), bundle_path, snapshot_override ] {
if (engine)
engine->RunBundleAndSnapshot(bundle_path, snapshot_override);
});
void PlatformViewAndroid::RunBundleAndSnapshot(std::string bundle_path,
std::string snapshot_override) {
blink::Threads::UI()->PostTask([
engine = engine_->GetWeakPtr(), bundle_path = std::move(bundle_path),
snapshot_override = std::move(snapshot_override)
] {
if (engine)
engine->RunBundleAndSnapshot(std::move(bundle_path),
std::move(snapshot_override));
});
}
void PlatformViewAndroid::RunBundleAndSource(JNIEnv* env,
jobject obj,
jstring java_bundle_path,
jstring java_main,
jstring java_packages) {
std::string bundle_path =
base::android::ConvertJavaStringToUTF8(env, java_bundle_path);
std::string main = base::android::ConvertJavaStringToUTF8(env, java_main);
std::string packages =
base::android::ConvertJavaStringToUTF8(env, java_packages);
blink::Threads::UI()->PostTask(
[ engine = engine_->GetWeakPtr(), bundle_path, main, packages ] {
if (engine)
engine->RunBundleAndSource(bundle_path, main, packages);
});
void PlatformViewAndroid::RunBundleAndSource(std::string bundle_path,
std::string main,
std::string packages) {
blink::Threads::UI()->PostTask([
engine = engine_->GetWeakPtr(), bundle_path = std::move(bundle_path),
main = std::move(main), packages = std::move(packages)
] {
if (engine)
engine->RunBundleAndSource(std::move(bundle_path), std::move(main),
std::move(packages));
});
}
void PlatformViewAndroid::SetViewportMetrics(JNIEnv* env,
jobject obj,
jfloat device_pixel_ratio,
void PlatformViewAndroid::SetViewportMetrics(jfloat device_pixel_ratio,
jint physical_width,
jint physical_height,
jint physical_padding_top,
@@ -230,19 +213,18 @@ void PlatformViewAndroid::SetViewportMetrics(JNIEnv* env,
}
void PlatformViewAndroid::DispatchPlatformMessage(JNIEnv* env,
jobject obj,
jstring java_name,
std::string name,
jobject java_message_data,
jint java_message_position,
jint response_id) {
std::string name = base::android::ConvertJavaStringToUTF8(env, java_name);
std::vector<uint8_t> message;
if (java_message_data) {
uint8_t* message_data = static_cast<uint8_t*>(env->GetDirectBufferAddress(java_message_data));
message = std::vector<uint8_t>(message_data, message_data + java_message_position);
uint8_t* message_data =
static_cast<uint8_t*>(env->GetDirectBufferAddress(java_message_data));
message = std::vector<uint8_t>(message_data,
message_data + java_message_position);
}
ftl::RefPtr<blink::PlatformMessageResponse> response;
if (response_id) {
response = ftl::MakeRefCounted<PlatformMessageResponseAndroid>(
@@ -250,12 +232,11 @@ void PlatformViewAndroid::DispatchPlatformMessage(JNIEnv* env,
}
PlatformView::DispatchPlatformMessage(
ftl::MakeRefCounted<blink::PlatformMessage>(std::move(name), std::move(message),
std::move(response)));
ftl::MakeRefCounted<blink::PlatformMessage>(
std::move(name), std::move(message), std::move(response)));
}
void PlatformViewAndroid::DispatchPointerDataPacket(JNIEnv* env,
jobject obj,
jobject buffer,
jint position) {
uint8_t* data = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
@@ -271,7 +252,6 @@ void PlatformViewAndroid::DispatchPointerDataPacket(JNIEnv* env,
void PlatformViewAndroid::InvokePlatformMessageResponseCallback(
JNIEnv* env,
jobject obj,
jint response_id,
jobject java_response_data,
jint java_response_position) {
@@ -282,8 +262,10 @@ void PlatformViewAndroid::InvokePlatformMessageResponseCallback(
return;
std::vector<uint8_t> response;
if (java_response_data) {
uint8_t* response_data = static_cast<uint8_t*>(env->GetDirectBufferAddress(java_response_data));
response = std::vector<uint8_t>(response_data, response_data + java_response_position);
uint8_t* response_data =
static_cast<uint8_t*>(env->GetDirectBufferAddress(java_response_data));
response = std::vector<uint8_t>(response_data,
response_data + java_response_position);
}
auto message_response = std::move(it->second);
pending_responses_.erase(it);
@@ -292,8 +274,8 @@ void PlatformViewAndroid::InvokePlatformMessageResponseCallback(
void PlatformViewAndroid::HandlePlatformMessage(
ftl::RefPtr<blink::PlatformMessage> message) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
if (view.is_null())
return;
@@ -304,39 +286,40 @@ void PlatformViewAndroid::HandlePlatformMessage(
}
auto data = message->data();
auto java_channel =
base::android::ConvertUTF8ToJavaString(env, message->channel());
auto java_channel = fml::jni::StringToJavaString(env, message->channel());
message = nullptr;
// This call can re-enter in InvokePlatformMessageResponseCallback.
Java_FlutterView_handlePlatformMessage(env, view.obj(), java_channel.obj(),
env->NewDirectByteBuffer(data.data(), data.size()),
response_id);
FlutterViewHandlePlatformMessage(
env, view.obj(), java_channel.obj(),
env->NewDirectByteBuffer(data.data(), data.size()), response_id);
}
void PlatformViewAndroid::HandlePlatformMessageResponse(
int response_id,
std::vector<uint8_t> data) {
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
JNIEnv* env = fml::jni::AttachCurrentThread();
fml::jni::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
if (view.is_null())
return;
Java_FlutterView_handlePlatformMessageResponse(env, view.obj(), response_id,
env->NewDirectByteBuffer(data.data(), data.size()));
std::string message_data(reinterpret_cast<const char*>(data.data()),
data.size());
auto java_message_data = fml::jni::StringToJavaString(env, message_data);
FlutterViewHandlePlatformMessageResponse(env, view.obj(), response_id,
java_message_data.obj());
}
void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
jobject obj,
jint id,
jint action) {
void PlatformViewAndroid::DispatchSemanticsAction(jint id, jint action) {
PlatformView::DispatchSemanticsAction(
id, static_cast<blink::SemanticsAction>(action));
}
void PlatformViewAndroid::SetSemanticsEnabled(JNIEnv* env,
jobject obj,
jboolean enabled) {
void PlatformViewAndroid::SetSemanticsEnabled(jboolean enabled) {
PlatformView::SetSemanticsEnabled(enabled);
}
@@ -360,9 +343,9 @@ void PlatformViewAndroid::UpdateSemantics(
constexpr size_t kBytesPerNode = 25 * sizeof(int32_t);
constexpr size_t kBytesPerChild = sizeof(int32_t);
JNIEnv* env = base::android::AttachCurrentThread();
JNIEnv* env = fml::jni::AttachCurrentThread();
{
base::android::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
fml::jni::ScopedJavaLocalRef<jobject> view = flutter_view_.get(env);
if (view.is_null())
return;
@@ -399,21 +382,20 @@ void PlatformViewAndroid::UpdateSemantics(
buffer_int32[position++] = child;
}
Java_FlutterView_updateSemantics(
FlutterViewUpdateSemantics(
env, view.obj(), env->NewDirectByteBuffer(buffer.data(), buffer.size()),
base::android::ToJavaArrayOfStrings(env, strings).obj());
fml::jni::VectorToStringArray(env, strings).obj());
}
}
void PlatformViewAndroid::RunFromSource(const std::string& assets_directory,
const std::string& main,
const std::string& packages) {
FTL_CHECK(base::android::IsVMInitialized());
JNIEnv* env = base::android::AttachCurrentThread();
JNIEnv* env = fml::jni::AttachCurrentThread();
FTL_CHECK(env);
{
base::android::ScopedJavaLocalRef<jobject> local_flutter_view =
fml::jni::ScopedJavaLocalRef<jobject> local_flutter_view =
flutter_view_.get(env);
if (local_flutter_view.is_null()) {
// Collected.
@@ -442,12 +424,11 @@ void PlatformViewAndroid::RunFromSource(const std::string& assets_directory,
}
// Detaching from the VM deletes any stray local references.
base::android::DetachFromVM();
fml::jni::DetachFromVM();
}
base::android::ScopedJavaLocalRef<jobject> PlatformViewAndroid::GetBitmap(
JNIEnv* env,
jobject obj) {
fml::jni::ScopedJavaLocalRef<jobject> PlatformViewAndroid::GetBitmap(
JNIEnv* env) {
// Render the last frame to an array of pixels on the GPU thread.
// The pixels will be returned as a global JNI reference to an int array.
ftl::AutoResetWaitableEvent latch;
@@ -462,9 +443,9 @@ base::android::ScopedJavaLocalRef<jobject> PlatformViewAndroid::GetBitmap(
// Convert the pixel array to an Android bitmap.
if (pixels_ref == nullptr)
return base::android::ScopedJavaLocalRef<jobject>();
return fml::jni::ScopedJavaLocalRef<jobject>();
base::android::ScopedJavaGlobalRef<jobject> pixels(env, pixels_ref);
fml::jni::ScopedJavaGlobalRef<jobject> pixels(env, pixels_ref);
jclass bitmap_class = env->FindClass("android/graphics/Bitmap");
FTL_CHECK(bitmap_class);
@@ -493,7 +474,7 @@ base::android::ScopedJavaLocalRef<jobject> PlatformViewAndroid::GetBitmap(
bitmap_class, create_bitmap, pixels.obj(), frame_size.width(),
frame_size.height(), bitmap_config);
return base::android::ScopedJavaLocalRef<jobject>(env, bitmap);
return fml::jni::ScopedJavaLocalRef<jobject>(env, bitmap);
}
void PlatformViewAndroid::GetBitmapGpuTask(jobject* pixels_out,
@@ -502,7 +483,7 @@ void PlatformViewAndroid::GetBitmapGpuTask(jobject* pixels_out,
if (layer_tree == nullptr)
return;
JNIEnv* env = base::android::AttachCurrentThread();
JNIEnv* env = fml::jni::AttachCurrentThread();
FTL_CHECK(env);
const SkISize& frame_size = layer_tree->frame_size();
@@ -542,24 +523,7 @@ void PlatformViewAndroid::GetBitmapGpuTask(jobject* pixels_out,
*pixels_out = env->NewGlobalRef(pixels_array);
*size_out = frame_size;
base::android::DetachFromVM();
}
jstring GetObservatoryUri(JNIEnv* env, jclass clazz) {
return env->NewStringUTF(
blink::DartServiceIsolate::GetObservatoryUri().c_str());
}
bool PlatformViewAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
}
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) {
PlatformViewAndroid* view = new PlatformViewAndroid();
// 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);
fml::jni::DetachFromVM();
}
} // namespace shell

View File

@@ -10,8 +10,8 @@
#include <unordered_map>
#include <vector>
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/android/android_native_window.h"
@@ -28,31 +28,22 @@ class PlatformViewAndroid : public PlatformView {
~PlatformViewAndroid() override;
void Detach(JNIEnv* env, jobject obj);
void Detach();
void SurfaceCreated(JNIEnv* env,
jobject obj,
jobject jsurface,
jint backgroundColor);
void SurfaceCreated(JNIEnv* env, jobject jsurface, jint backgroundColor);
void SurfaceChanged(JNIEnv* env, jobject obj, jint width, jint height);
void SurfaceChanged(jint width, jint height);
void RunBundleAndSnapshot(JNIEnv* env,
jobject obj,
jstring bundle_path,
jstring snapshot_override);
void SurfaceDestroyed();
void RunBundleAndSource(JNIEnv* env,
jobject obj,
jstring bundle_path,
jstring main,
jstring packages);
void RunBundleAndSnapshot(std::string bundle_path,
std::string snapshot_override);
void SurfaceDestroyed(JNIEnv* env, jobject obj);
void RunBundleAndSource(std::string bundle_path,
std::string main,
std::string packages);
void SetViewportMetrics(JNIEnv* env,
jobject obj,
jfloat device_pixel_ratio,
void SetViewportMetrics(jfloat device_pixel_ratio,
jint physical_width,
jint physical_height,
jint physical_padding_top,
@@ -61,29 +52,23 @@ class PlatformViewAndroid : public PlatformView {
jint physical_padding_left);
void DispatchPlatformMessage(JNIEnv* env,
jobject obj,
jstring name,
std::string name,
jobject message_data,
jint message_position,
jint response_id);
void DispatchPointerDataPacket(JNIEnv* env,
jobject obj,
jobject buffer,
jint position);
void DispatchPointerDataPacket(JNIEnv* env, jobject buffer, jint position);
void InvokePlatformMessageResponseCallback(JNIEnv* env,
jobject obj,
jint response_id,
jobject response_data,
jint response_position);
jobject java_response_data,
jint java_response_position);
void DispatchSemanticsAction(JNIEnv* env, jobject obj, jint id, jint action);
void DispatchSemanticsAction(jint id, jint action);
void SetSemanticsEnabled(JNIEnv* env, jobject obj, jboolean enabled);
void SetSemanticsEnabled(jboolean enabled);
base::android::ScopedJavaLocalRef<jobject> GetBitmap(JNIEnv* env,
jobject obj);
fml::jni::ScopedJavaLocalRef<jobject> GetBitmap(JNIEnv* env);
VsyncWaiter* GetVsyncWaiter() override;
@@ -101,13 +86,13 @@ class PlatformViewAndroid : public PlatformView {
const std::string& main,
const std::string& packages) override;
void set_flutter_view(const JavaObjectWeakGlobalRef& flutter_view) {
void set_flutter_view(const fml::jni::JavaObjectWeakGlobalRef& flutter_view) {
flutter_view_ = flutter_view;
}
private:
const std::unique_ptr<AndroidSurface> android_surface_;
JavaObjectWeakGlobalRef flutter_view_;
fml::jni::JavaObjectWeakGlobalRef flutter_view_;
// We use id 0 to mean that no response is expected.
int next_response_id_ = 1;
std::unordered_map<int, ftl::RefPtr<blink::PlatformMessageResponse>>
@@ -117,8 +102,7 @@ class PlatformViewAndroid : public PlatformView {
void ReleaseSurface();
void GetBitmapGpuTask(jobject* pixels_out,
SkISize* size_out);
void GetBitmapGpuTask(jobject* pixels_out, SkISize* size_out);
FTL_DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroid);
};

View File

@@ -0,0 +1,307 @@
// Copyright 2017 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 "flutter/shell/platform/android/platform_view_android_jni.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "lib/ftl/arraysize.h"
#include "lib/ftl/logging.h"
#define PLATFORM_VIEW reinterpret_cast<PlatformViewAndroid*>(platform_view)
namespace shell {
static fml::jni::ScopedJavaGlobalRef<jclass>* g_flutter_view_class = nullptr;
// Called By Native
static jmethodID g_handle_platform_message_method = nullptr;
void FlutterViewHandlePlatformMessage(JNIEnv* env,
jobject obj,
jstring channel,
jobject message,
jint responseId) {
env->CallVoidMethod(obj, g_handle_platform_message_method, channel, message,
responseId);
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
}
static jmethodID g_handle_platform_message_response_method = nullptr;
void FlutterViewHandlePlatformMessageResponse(JNIEnv* env,
jobject obj,
jint responseId,
jobject response) {
env->CallVoidMethod(obj, g_handle_platform_message_response_method,
responseId, response);
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
}
static jmethodID g_update_semantics_method = nullptr;
void FlutterViewUpdateSemantics(JNIEnv* env,
jobject obj,
jobject buffer,
jobjectArray strings) {
env->CallVoidMethod(obj, g_update_semantics_method, buffer, strings);
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
}
// Called By Java
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) {
PlatformViewAndroid* view = new PlatformViewAndroid();
// Create a weak reference to the flutterView Java object so that we can make
// calls into it later.
view->set_flutter_view(fml::jni::JavaObjectWeakGlobalRef(env, flutterView));
return reinterpret_cast<jlong>(view);
}
static void Detach(JNIEnv* env, jobject jcaller, jlong platform_view) {
return PLATFORM_VIEW->Detach();
}
static jstring GetObservatoryUri(JNIEnv* env, jclass clazz) {
return env->NewStringUTF(
blink::DartServiceIsolate::GetObservatoryUri().c_str());
}
static void SurfaceCreated(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jobject surface,
jint backgroundColor) {
return PLATFORM_VIEW->SurfaceCreated(env, surface, backgroundColor);
}
static void SurfaceChanged(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jint width,
jint height) {
return PLATFORM_VIEW->SurfaceChanged(width, height);
}
static void SurfaceDestroyed(JNIEnv* env,
jobject jcaller,
jlong platform_view) {
return PLATFORM_VIEW->SurfaceDestroyed();
}
static void RunBundleAndSnapshot(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jstring bundlePath,
jstring snapshotOverride) {
return PLATFORM_VIEW->RunBundleAndSnapshot(
fml::jni::JavaStringToString(env, bundlePath), //
fml::jni::JavaStringToString(env, snapshotOverride) //
);
}
void RunBundleAndSource(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jstring bundlePath,
jstring main,
jstring packages) {
return PLATFORM_VIEW->RunBundleAndSource(
fml::jni::JavaStringToString(env, bundlePath),
fml::jni::JavaStringToString(env, main),
fml::jni::JavaStringToString(env, packages));
}
static void SetViewportMetrics(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jfloat devicePixelRatio,
jint physicalWidth,
jint physicalHeight,
jint physicalPaddingTop,
jint physicalPaddingRight,
jint physicalPaddingBottom,
jint physicalPaddingLeft) {
return PLATFORM_VIEW->SetViewportMetrics(devicePixelRatio, //
physicalWidth, //
physicalHeight, //
physicalPaddingTop, //
physicalPaddingRight, //
physicalPaddingBottom, //
physicalPaddingLeft);
}
static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong platform_view) {
return PLATFORM_VIEW->GetBitmap(env).Release();
}
static void DispatchPlatformMessage(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jstring channel,
jobject message,
jint position,
jint responseId) {
return PLATFORM_VIEW->DispatchPlatformMessage(
env, fml::jni::JavaStringToString(env, channel), message, position,
responseId);
}
static void DispatchPointerDataPacket(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jobject buffer,
jint position) {
return PLATFORM_VIEW->DispatchPointerDataPacket(env, buffer, position);
}
static void DispatchSemanticsAction(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jint id,
jint action) {
return PLATFORM_VIEW->DispatchSemanticsAction(id, action);
}
static void SetSemanticsEnabled(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jboolean enabled) {
return PLATFORM_VIEW->SetSemanticsEnabled(enabled);
}
static void InvokePlatformMessageResponseCallback(JNIEnv* env,
jobject jcaller,
jlong platform_view,
jint responseId,
jobject message,
jint position) {
return PLATFORM_VIEW->InvokePlatformMessageResponseCallback(
env, responseId, message, position);
}
bool PlatformViewAndroid::Register(JNIEnv* env) {
if (env == nullptr) {
return false;
}
g_flutter_view_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
env, env->FindClass("io/flutter/view/FlutterView"));
if (g_flutter_view_class->is_null()) {
return false;
}
static const JNINativeMethod methods[] = {
{
.name = "nativeAttach",
.signature = "(Lio/flutter/view/FlutterView;)J",
.fnPtr = reinterpret_cast<void*>(&shell::Attach),
},
{
.name = "nativeDetach",
.signature = "(J)V",
.fnPtr = reinterpret_cast<void*>(&shell::Detach),
},
{
.name = "nativeGetObservatoryUri",
.signature = "()Ljava/lang/String;",
.fnPtr = reinterpret_cast<void*>(&shell::GetObservatoryUri),
},
{
.name = "nativeSurfaceCreated",
.signature = "(JLandroid/view/Surface;I)V",
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceCreated),
},
{
.name = "nativeSurfaceChanged",
.signature = "(JII)V",
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceChanged),
},
{
.name = "nativeSurfaceDestroyed",
.signature = "(J)V",
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceDestroyed),
},
{
.name = "nativeRunBundleAndSnapshot",
.signature = "(JLjava/lang/String;Ljava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&shell::RunBundleAndSnapshot),
},
{
.name = "nativeRunBundleAndSource",
.signature =
"(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
.fnPtr = reinterpret_cast<void*>(&shell::RunBundleAndSource),
},
{
.name = "nativeSetViewportMetrics",
.signature = "(JFIIIIII)V",
.fnPtr = reinterpret_cast<void*>(&shell::SetViewportMetrics),
},
{
.name = "nativeGetBitmap",
.signature = "(J)Landroid/graphics/Bitmap;",
.fnPtr = reinterpret_cast<void*>(&shell::GetBitmap),
},
{
.name = "nativeDispatchPlatformMessage",
.signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
.fnPtr = reinterpret_cast<void*>(&shell::DispatchPlatformMessage),
},
{
.name = "nativeDispatchPointerDataPacket",
.signature = "(JLjava/nio/ByteBuffer;I)V",
.fnPtr = reinterpret_cast<void*>(&shell::DispatchPointerDataPacket),
},
{
.name = "nativeDispatchSemanticsAction",
.signature = "(JII)V",
.fnPtr = reinterpret_cast<void*>(&shell::DispatchSemanticsAction),
},
{
.name = "nativeSetSemanticsEnabled",
.signature = "(JZ)V",
.fnPtr = reinterpret_cast<void*>(&shell::SetSemanticsEnabled),
},
{
.name = "nativeInvokePlatformMessageResponseCallback",
.signature = "(JILjava/nio/ByteBuffer;I)V",
.fnPtr = reinterpret_cast<void*>(
&shell::InvokePlatformMessageResponseCallback),
},
};
if (env->RegisterNatives(g_flutter_view_class->obj(), methods,
arraysize(methods)) != 0) {
return false;
}
g_handle_platform_message_method =
env->GetMethodID(g_flutter_view_class->obj(), "handlePlatformMessage",
"(Ljava/lang/String;Ljava/nio/ByteBuffer;I)V");
if (g_handle_platform_message_method == nullptr) {
return false;
}
g_handle_platform_message_response_method = env->GetMethodID(
g_flutter_view_class->obj(), "handlePlatformMessageResponse",
"(ILjava/nio/ByteBuffer;)V");
if (g_handle_platform_message_response_method == nullptr) {
return false;
}
g_update_semantics_method =
env->GetMethodID(g_flutter_view_class->obj(), "updateSemantics",
"(Ljava/nio/ByteBuffer;[Ljava/lang/String;)V");
if (g_update_semantics_method == nullptr) {
return false;
}
return true;
}
} // namespace shell

View File

@@ -0,0 +1,32 @@
// Copyright 2017 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 FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
#define FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
#include <jni.h>
#include "flutter/shell/platform/android/platform_view_android.h"
#include "lib/ftl/macros.h"
namespace shell {
void FlutterViewHandlePlatformMessage(JNIEnv* env,
jobject obj,
jstring channel,
jobject message,
jint responseId);
void FlutterViewHandlePlatformMessageResponse(JNIEnv* env,
jobject obj,
jint responseId,
jobject response);
void FlutterViewUpdateSemantics(JNIEnv* env,
jobject obj,
jobject buffer,
jobjectArray strings);
} // namespace shell
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_

View File

@@ -6,12 +6,17 @@
#include <utility>
#include "jni/VsyncWaiter_jni.h"
#include "lib/ftl/logging.h"
#include "flutter/common/threads.h"
#include "flutter/fml/platform/android/jni_util.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "lib/ftl/arraysize.h"
#include "lib/ftl/logging.h"
namespace shell {
static fml::jni::ScopedJavaGlobalRef<jclass>* g_vsync_waiter_class = nullptr;
static jmethodID g_async_wait_for_vsync_method_ = nullptr;
VsyncWaiterAndroid::VsyncWaiterAndroid() : weak_factory_(this) {}
VsyncWaiterAndroid::~VsyncWaiterAndroid() = default;
@@ -24,8 +29,10 @@ void VsyncWaiterAndroid::AsyncWaitForVsync(Callback callback) {
*weak = weak_factory_.GetWeakPtr();
blink::Threads::Platform()->PostTask([weak] {
JNIEnv* env = base::android::AttachCurrentThread();
Java_VsyncWaiter_asyncWaitForVsync(env, reinterpret_cast<intptr_t>(weak));
JNIEnv* env = fml::jni::AttachCurrentThread();
env->CallStaticVoidMethod(g_vsync_waiter_class->obj(),
g_async_wait_for_vsync_method_,
reinterpret_cast<jlong>(weak));
});
}
@@ -39,10 +46,10 @@ void VsyncWaiterAndroid::OnVsync(long frameTimeNanos) {
});
}
static void OnVsync(JNIEnv* env,
jclass jcaller,
jlong frameTimeNanos,
jlong cookie) {
static void OnNativeVsync(JNIEnv* env,
jclass jcaller,
jlong frameTimeNanos,
jlong cookie) {
ftl::WeakPtr<VsyncWaiterAndroid>* weak =
reinterpret_cast<ftl::WeakPtr<VsyncWaiterAndroid>*>(cookie);
VsyncWaiterAndroid* waiter = weak->get();
@@ -52,7 +59,28 @@ static void OnVsync(JNIEnv* env,
}
bool VsyncWaiterAndroid::Register(JNIEnv* env) {
return RegisterNativesImpl(env);
static const JNINativeMethod methods[] = {{
.name = "nativeOnVsync",
.signature = "(JJ)V",
.fnPtr = reinterpret_cast<void*>(&OnNativeVsync),
}};
jclass clazz = env->FindClass("io/flutter/view/VsyncWaiter");
if (clazz == nullptr) {
return false;
}
g_vsync_waiter_class = new fml::jni::ScopedJavaGlobalRef<jclass>(env, clazz);
FTL_CHECK(!g_vsync_waiter_class->is_null());
g_async_wait_for_vsync_method_ = env->GetStaticMethodID(
g_vsync_waiter_class->obj(), "asyncWaitForVsync", "(J)V");
FTL_CHECK(g_async_wait_for_vsync_method_ != nullptr);
return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
}
} // namespace shell

View File

@@ -5,7 +5,7 @@
#ifndef SHELL_PLATFORM_ANDROID_VSYNC_WAITER_ANDROID_H_
#define SHELL_PLATFORM_ANDROID_VSYNC_WAITER_ANDROID_H_
#include "base/android/jni_android.h"
#include <jni.h>
#include "flutter/shell/common/vsync_waiter.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/memory/weak_ptr.h"
@@ -15,6 +15,7 @@ namespace shell {
class VsyncWaiterAndroid : public VsyncWaiter {
public:
VsyncWaiterAndroid();
~VsyncWaiterAndroid() override;
static bool Register(JNIEnv* env);

View File

@@ -22,21 +22,19 @@ group("darwin") {
source_set("flutter_channels") {
set_sources_assignment_filter([])
sources = [
"common/buffer_conversions.h",
"common/buffer_conversions.mm",
"ios/framework/Headers/FlutterBinaryMessenger.h",
"ios/framework/Headers/FlutterChannels.h",
"ios/framework/Headers/FlutterCodecs.h",
"ios/framework/Source/FlutterChannels.mm",
"ios/framework/Source/FlutterCodecs.mm",
"ios/framework/Source/FlutterStandardCodec_Internal.h",
"ios/framework/Source/FlutterStandardCodec.mm",
"common/buffer_conversions.h",
"common/buffer_conversions.mm",
"ios/framework/Source/FlutterStandardCodec_Internal.h",
]
set_sources_assignment_filter(sources_assignment_filter)
deps = [
"//base",
"//base:i18n",
"//dart/runtime:libdart",
"//flutter/common",
"//flutter/flow",
@@ -51,7 +49,6 @@ source_set("flutter_channels") {
]
}
executable("flutter_channels_unittests") {
testonly = true

View File

@@ -7,18 +7,16 @@ source_set("common") {
# as Mac.
set_sources_assignment_filter([])
sources = [
"buffer_conversions.h",
"buffer_conversions.mm",
"platform_mac.h",
"platform_mac.mm",
"process_info_mac.cc",
"process_info_mac.h",
"buffer_conversions.h",
"buffer_conversions.mm",
]
set_sources_assignment_filter(sources_assignment_filter)
deps = [
"//base",
"//base:i18n",
"//dart/runtime:libdart",
"//flutter/common",
"//flutter/flow",

View File

@@ -8,38 +8,22 @@
#include <asl.h>
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/message_loop/message_loop.h"
#include "base/trace_event/trace_event.h"
#include "dart/runtime/include/dart_tools_api.h"
#include "flutter/common/threads.h"
#include "flutter/fml/trace_event.h"
#include "flutter/runtime/start_up.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/common/tracing_controller.h"
#include "flutter/sky/engine/wtf/MakeUnique.h"
#include "lib/ftl/command_line.h"
namespace shell {
static void InitializeLogging() {
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
logging::InitLogging(settings);
logging::SetLogItems(false, // Process ID
false, // Thread ID
false, // Timestamp
false); // Tick count
}
static void RedirectIOConnectionsToSyslog() {
static void RedirectIOConnectionsToSyslog(
const ftl::CommandLine& command_line) {
#if TARGET_OS_IPHONE
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
FlagForSwitch(Switch::NoRedirectToSyslog))) {
if (command_line.HasOption(FlagForSwitch(Switch::NoRedirectToSyslog))) {
return;
}
@@ -50,17 +34,14 @@ static void RedirectIOConnectionsToSyslog() {
#endif
}
static void InitializeCommandLine() {
base::mac::ScopedNSAutoreleasePool pool;
base::CommandLine::StringVector vector;
static ftl::CommandLine InitializedCommandLine() {
std::vector<std::string> args_vector;
for (NSString* arg in [NSProcessInfo processInfo].arguments) {
vector.emplace_back(arg.UTF8String);
args_vector.emplace_back(arg.UTF8String);
}
base::CommandLine::Init(0, nullptr);
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
command_line.InitFromArgv(vector);
return ftl::CommandLineFromIterators(args_vector.begin(), args_vector.end());
}
class EmbedderState {
@@ -72,51 +53,24 @@ class EmbedderState {
// See https://github.com/flutter/flutter/issues/4006
blink::engine_main_enter_ts = Dart_TimelineGetMicros();
#endif
CHECK([NSThread isMainThread])
FTL_DCHECK([NSThread isMainThread])
<< "Embedder initialization must occur on the main platform thread";
InitializeCommandLine();
auto command_line = InitializedCommandLine();
RedirectIOConnectionsToSyslog();
InitializeLogging();
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(FlagForSwitch(Switch::TraceStartup))) {
// Usually, all tracing within flutter is managed via the tracing
// controller
// The tracing controller is accessed via the shell instance. This means
// that tracing can only be enabled once that instance is created. Traces
// early in startup are lost. This enables tracing only in base manually
// till the tracing controller takes over.
shell::TracingController::StartBaseTracing();
}
RedirectIOConnectionsToSyslog(command_line);
// This is about as early as tracing of any kind can start. Add an instant
// marker that can be used as a reference for startup.
TRACE_EVENT_INSTANT0("flutter", "main", TRACE_EVENT_SCOPE_PROCESS);
TRACE_EVENT_INSTANT0("flutter", "main");
embedder_message_loop_ = WTF::MakeUnique<base::MessageLoopForUI>();
#if TARGET_OS_IPHONE
// One cannot start the message loop on the platform main thread. Instead,
// we attach to the CFRunLoop
embedder_message_loop_->Attach();
#endif
shell::Shell::InitStandalone(icu_data_path, application_library_path);
shell::Shell::InitStandalone(std::move(command_line), icu_data_path,
application_library_path);
}
~EmbedderState() {
#if !TARGET_OS_IPHONE
embedder_message_loop_.release();
#endif
}
~EmbedderState() {}
private:
base::AtExitManager exit_manager_;
std::unique_ptr<base::MessageLoopForUI> embedder_message_loop_;
FTL_DISALLOW_COPY_AND_ASSIGN(EmbedderState);
};
@@ -160,10 +114,11 @@ static bool FlagsValidForCommandLineLaunch(const std::string& bundle_path,
}
static std::string ResolveCommandLineLaunchFlag(const char* name) {
auto command_line = *base::CommandLine::ForCurrentProcess();
const auto& command_line = shell::Shell::Shared().GetCommandLine();
if (command_line.HasSwitch(name)) {
return command_line.GetSwitchValueASCII(name);
std::string command_line_option;
if (command_line.GetOptionValue(name, &command_line_option)) {
return command_line_option;
}
const char* saved_default =
@@ -177,15 +132,13 @@ static std::string ResolveCommandLineLaunchFlag(const char* name) {
}
bool AttemptLaunchFromCommandLineSwitches(Engine* engine) {
base::mac::ScopedNSAutoreleasePool pool;
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
auto command_line = *base::CommandLine::ForCurrentProcess();
const auto& command_line = shell::Shell::Shared().GetCommandLine();
if (command_line.HasSwitch(FlagForSwitch(Switch::FLX)) ||
command_line.HasSwitch(FlagForSwitch(Switch::MainDartFile)) ||
command_line.HasSwitch(FlagForSwitch(Switch::Packages))) {
if (command_line.HasOption(FlagForSwitch(Switch::FLX)) ||
command_line.HasOption(FlagForSwitch(Switch::MainDartFile)) ||
command_line.HasOption(FlagForSwitch(Switch::Packages))) {
// The main dart file, flx bundle and the package root must be specified in
// one go. We dont want to end up in a situation where we take one value
// from the command line and the others from user defaults. In case, any

View File

@@ -24,8 +24,8 @@ source_set("mac_desktop_platform") {
]
deps = [
"//base",
"//flutter/common",
"//flutter/fml",
"//flutter/shell/common",
"//flutter/shell/gpu",
"//flutter/shell/platform/darwin/common",

View File

@@ -2,17 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef __SHELL_PLATFORM_DARWIN_DESKTOP_FLUTTER_APPLICATION__
#define __SHELL_PLATFORM_DARWIN_DESKTOP_FLUTTER_APPLICATION__
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_DESKTOP_FLUTTER_APPLICATION_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_DESKTOP_FLUTTER_APPLICATION_H_
#import <AppKit/AppKit.h>
#include "base/mac/scoped_sending_event.h"
#include "base/message_loop/message_pump_mac.h"
// A specific subclass of NSApplication is necessary on Mac in order to
// interact correctly with the main runloop.
@interface FlutterApplication : NSApplication<CrAppProtocol, CrAppControlProtocol>
@interface FlutterApplication : NSApplication
@end
#endif /* defined(__SHELL_PLATFORM_DARWIN_DESKTOP_FLUTTER_APPLICATION__) */
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_DESKTOP_FLUTTER_APPLICATION_H_

View File

@@ -4,36 +4,5 @@
#include "flutter/shell/platform/darwin/desktop/flutter_application.h"
#include "base/auto_reset.h"
#include "base/logging.h"
@implementation FlutterApplication {
BOOL handlingSendEvent_;
}
+ (void)initialize {
if (self == [FlutterApplication class]) {
NSApplication* app = [FlutterApplication sharedApplication];
DCHECK([app conformsToProtocol:@protocol(CrAppControlProtocol)])
<< "Existing NSApp (class " << [[app className] UTF8String]
<< ") does not conform to required protocol.";
DCHECK(base::MessagePumpMac::UsingCrApp())
<< "MessagePumpMac::Create() was called before "
<< "+[FlutterApplication initialize]";
}
}
- (void)sendEvent:(NSEvent*)event {
base::AutoReset<BOOL> scoper(&handlingSendEvent_, YES);
[super sendEvent:event];
}
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
handlingSendEvent_ = handlingSendEvent;
}
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}
@implementation FlutterApplication
@end

View File

@@ -54,7 +54,7 @@ static inline blink::PointerData::Change PointerChangeFromNSEventPhase(
}
- (void)setupPlatformView {
DCHECK(_platformView == nullptr)
FTL_DCHECK(_platformView == nullptr)
<< "The platform view must not already be set.";
_platformView.reset(new shell::PlatformViewMac(self.renderSurface));

View File

@@ -6,48 +6,34 @@
#include <iostream>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "flutter/fml/message_loop.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/platform/darwin/common/platform_mac.h"
#include "flutter/shell/platform/darwin/desktop/flutter_application.h"
#include "flutter/shell/testing/testing.h"
namespace shell {
namespace {
void AttachMessageLoopToMainRunLoop(void) {
// We want to call Run() on the MessageLoopForUI but after NSApplicationMain.
// If called before this point, the call is blocking and will prevent the
// NSApplicationMain invocation.
dispatch_async(dispatch_get_main_queue(), ^() {
base::MessageLoopForUI::current()->Run();
});
}
} // namespace
} // namespace shell
int main(int argc, const char* argv[]) {
[FlutterApplication sharedApplication];
shell::PlatformMacMain("", "");
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(shell::FlagForSwitch(shell::Switch::Help))) {
const auto& command_line = shell::Shell::Shared().GetCommandLine();
// Print help.
if (command_line.HasOption(shell::FlagForSwitch(shell::Switch::Help))) {
shell::PrintUsage([NSProcessInfo processInfo].processName.UTF8String);
return EXIT_SUCCESS;
}
if (command_line.HasSwitch(
// Decide between interactive and non-interactive modes.
if (command_line.HasOption(
shell::FlagForSwitch(shell::Switch::NonInteractive))) {
if (!shell::InitForTesting())
if (!shell::InitForTesting(std::move(command_line)))
return 1;
base::MessageLoop::current()->Run();
fml::MessageLoop::GetCurrent().Run();
return EXIT_SUCCESS;
} else {
return NSApplicationMain(argc, argv);
}
shell::AttachMessageLoopToMainRunLoop();
return NSApplicationMain(argc, argv);
}

View File

@@ -5,7 +5,7 @@
#ifndef SHELL_PLATFORM_MAC_PLATFORM_VIEW_MAC_H_
#define SHELL_PLATFORM_MAC_PLATFORM_VIEW_MAC_H_
#include "base/mac/scoped_nsobject.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/gpu/gpu_surface_gl.h"
#include "lib/ftl/memory/weak_ptr.h"
@@ -40,8 +40,8 @@ class PlatformViewMac : public PlatformView, public GPUSurfaceGLDelegate {
const std::string& packages) override;
private:
base::scoped_nsobject<NSOpenGLView> opengl_view_;
base::scoped_nsobject<NSOpenGLContext> resource_loading_context_;
fml::scoped_nsobject<NSOpenGLView> opengl_view_;
fml::scoped_nsobject<NSOpenGLContext> resource_loading_context_;
bool IsValid() const;

View File

@@ -7,14 +7,14 @@
#include <AppKit/AppKit.h>
#include <Foundation/Foundation.h>
#include "base/command_line.h"
#include "base/trace_event/trace_event.h"
#include "flutter/common/threads.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/gpu/gpu_rasterizer.h"
#include "flutter/shell/platform/darwin/common/platform_mac.h"
#include "flutter/shell/platform/darwin/common/process_info_mac.h"
#include "flutter/shell/platform/darwin/desktop/vsync_waiter_mac.h"
#include "lib/ftl/command_line.h"
#include "lib/ftl/synchronization/waitable_event.h"
namespace shell {
@@ -27,14 +27,6 @@ PlatformViewMac::PlatformViewMac(NSOpenGLView* gl_view)
initWithFormat:gl_view.pixelFormat
shareContext:gl_view.openGLContext]) {
CreateEngine();
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
if (paths.count > 0) {
shell::Shell::Shared().tracing_controller().set_traces_base_path(
[[paths objectAtIndex:0] UTF8String]);
}
PostAddToShellTask();
}
@@ -47,10 +39,10 @@ void PlatformViewMac::SetupAndLoadDart() {
return;
}
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
const auto& command_line = shell::Shell::Shared().GetCommandLine();
std::string bundle_path =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::FLX));
command_line.GetOptionValueWithDefault(FlagForSwitch(Switch::FLX), "");
if (!bundle_path.empty()) {
blink::Threads::UI()->PostTask(
[ engine = engine().GetWeakPtr(), bundle_path ] {
@@ -60,11 +52,11 @@ void PlatformViewMac::SetupAndLoadDart() {
return;
}
auto args = command_line.GetArgs();
auto args = command_line.positional_args();
if (args.size() > 0) {
std::string main = args[0];
std::string packages =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::Packages));
std::string packages = command_line.GetOptionValueWithDefault(
FlagForSwitch(Switch::Packages), "");
blink::Threads::UI()->PostTask(
[ engine = engine().GetWeakPtr(), main, packages ] {
if (engine)

View File

@@ -17,9 +17,9 @@ shared_library("flutter_framework_dylib") {
sources = [
"framework/Headers/Flutter.h",
"framework/Headers/FlutterAppDelegate.h",
"framework/Headers/FlutterBinaryMessenger.h",
"framework/Headers/FlutterChannels.h",
"framework/Headers/FlutterCodecs.h",
"framework/Headers/FlutterBinaryMessenger.h",
"framework/Headers/FlutterDartProject.h",
"framework/Headers/FlutterMacros.h",
"framework/Headers/FlutterViewController.h",
@@ -32,8 +32,8 @@ shared_library("flutter_framework_dylib") {
"framework/Source/FlutterDartSource.mm",
"framework/Source/FlutterPlatformPlugin.h",
"framework/Source/FlutterPlatformPlugin.mm",
"framework/Source/FlutterStandardCodec_Internal.h",
"framework/Source/FlutterStandardCodec.mm",
"framework/Source/FlutterStandardCodec_Internal.h",
"framework/Source/FlutterTextInputDelegate.h",
"framework/Source/FlutterTextInputPlugin.h",
"framework/Source/FlutterTextInputPlugin.mm",
@@ -63,7 +63,6 @@ shared_library("flutter_framework_dylib") {
]
deps = [
"//base:base",
"//dart/runtime:libdart",
"//flutter/flow",
"//flutter/fml",

View File

@@ -4,19 +4,20 @@
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartProject_Internal.h"
#include "base/command_line.h"
#include "dart/runtime/include/dart_api.h"
#include "flutter/common/threads.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterDartSource.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/flutter_main_ios.h"
static NSURL* URLForSwitch(const char* name) {
auto cmd = *base::CommandLine::ForCurrentProcess();
const auto& cmd = shell::Shell::Shared().GetCommandLine();
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
if (cmd.HasSwitch(name)) {
auto url = [NSURL fileURLWithPath:@(cmd.GetSwitchValueASCII(name).c_str())];
std::string switch_value;
if (cmd.GetOptionValue(name, &switch_value)) {
auto url = [NSURL fileURLWithPath:@(switch_value.c_str())];
[defaults setURL:url forKey:@(name)];
[defaults synchronize];
return url;

View File

@@ -7,8 +7,9 @@
#include <UIKit/UIKit.h>
#include <unicode/utf16.h>
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include <string>
#include "flutter/fml/platform/darwin/nsstring_utils.h"
static const char _kTextAffinityDownstream[] = "TextAffinity.downstream";
static const char _kTextAffinityUpstream[] = "TextAffinity.upstream";
@@ -34,7 +35,7 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
int _selectionBase;
int _selectionExtent;
const char* _selectionAffinity;
base::string16 _text;
std::u16string _text;
}
@synthesize keyboardType = _keyboardType;
@@ -62,7 +63,7 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
_selectionAffinity = _kTextAffinityDownstream;
if ([state[@"selectionAffinity"] isEqualToString:@(_kTextAffinityUpstream)])
_selectionAffinity = _kTextAffinityUpstream;
_text = base::SysNSStringToUTF16(state[@"text"]);
_text = fml::StringFromNSString(state[@"text"]);
}
- (UITextAutocorrectionType)autocorrectionType {
@@ -80,13 +81,13 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
- (void)updateEditingState {
[_textInputDelegate updateEditingClient:_textInputClient
withState:@{
@"selectionBase": @(_selectionBase),
@"selectionExtent": @(_selectionExtent),
@"selectionAffinity": @(_selectionAffinity),
@"selectionIsDirectional": @(false),
@"composingBase": @(0),
@"composingExtent": @(0),
@"text": base::SysUTF16ToNSString(_text),
@"selectionBase" : @(_selectionBase),
@"selectionExtent" : @(_selectionExtent),
@"selectionAffinity" : @(_selectionAffinity),
@"selectionIsDirectional" : @(false),
@"composingBase" : @(0),
@"composingExtent" : @(0),
@"text" : fml::StringToNSString(_text),
}];
}
@@ -98,7 +99,7 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
int start = std::max(0, std::min(_selectionBase, _selectionExtent));
int end = std::max(0, std::max(_selectionBase, _selectionExtent));
int len = end - start;
_text.replace(start, len, base::SysNSStringToUTF16(text));
_text.replace(start, len, fml::StringFromNSString(text));
int caret = start + text.length;
_selectionBase = caret;
_selectionExtent = caret;
@@ -115,8 +116,7 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
} else if (start > 0) {
start -= 1;
len = 1;
if (start > 0 &&
UTF16_IS_LEAD(_text[start - 1]) &&
if (start > 0 && UTF16_IS_LEAD(_text[start - 1]) &&
UTF16_IS_TRAIL(_text[start])) {
start -= 1;
len += 1;
@@ -154,7 +154,8 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
[super dealloc];
}
- (void)handleMethodCall:(FlutterMethodCall*)call resultReceiver:(FlutterResultReceiver)resultReceiver {
- (void)handleMethodCall:(FlutterMethodCall*)call
resultReceiver:(FlutterResultReceiver)resultReceiver {
NSString* method = call.method;
id args = call.arguments;
if ([method isEqualToString:@"TextInput.show"]) {
@@ -173,7 +174,9 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
[self clearTextInputClient];
resultReceiver(nil, nil);
} else {
resultReceiver(nil, [FlutterError errorWithCode:@"UNKNOWN" message:@"Unknown method" details: nil]);
resultReceiver(nil, [FlutterError errorWithCode:@"UNKNOWN"
message:@"Unknown method"
details:nil]);
}
}
@@ -191,7 +194,8 @@ static UIKeyboardType ToUIKeyboardType(NSString* inputType) {
[_view removeFromSuperview];
}
- (void)setTextInputClient:(int)client withConfiguration:(NSDictionary*)configuration {
- (void)setTextInputClient:(int)client
withConfiguration:(NSDictionary*)configuration {
_view.keyboardType = ToUIKeyboardType(configuration[@"inputType"]);
[_view setTextInputClient:client];
[_view reloadInputViews];

View File

@@ -6,10 +6,9 @@
#include <memory>
#include "base/mac/scoped_block.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "flutter/common/threads.h"
#include "flutter/fml/platform/darwin/scoped_block.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/platform/darwin/common/buffer_conversions.h"
#include "flutter/shell/platform/darwin/common/platform_mac.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h"
@@ -44,9 +43,9 @@ class PlatformMessageResponseDarwin : public blink::PlatformMessageResponse {
private:
explicit PlatformMessageResponseDarwin(
PlatformMessageResponseCallback callback)
: callback_(callback, base::scoped_policy::RETAIN) {}
: callback_(callback, fml::OwnershipPolicy::Retain) {}
base::mac::ScopedBlock<PlatformMessageResponseCallback> callback_;
fml::ScopedBlock<PlatformMessageResponseCallback> callback_;
};
} // namespace
@@ -60,20 +59,20 @@ void FlutterInit(int argc, const char* argv[]) {
}
@implementation FlutterViewController {
base::scoped_nsprotocol<FlutterDartProject*> _dartProject;
fml::scoped_nsprotocol<FlutterDartProject*> _dartProject;
UIInterfaceOrientationMask _orientationPreferences;
UIStatusBarStyle _statusBarStyle;
blink::ViewportMetrics _viewportMetrics;
shell::TouchMapper _touchMapper;
std::unique_ptr<shell::PlatformViewIOS> _platformView;
base::scoped_nsprotocol<FlutterPlatformPlugin*> _platformPlugin;
base::scoped_nsprotocol<FlutterTextInputPlugin*> _textInputPlugin;
base::scoped_nsprotocol<FlutterMethodChannel*> _localizationChannel;
base::scoped_nsprotocol<FlutterMethodChannel*> _navigationChannel;
base::scoped_nsprotocol<FlutterMethodChannel*> _platformChannel;
base::scoped_nsprotocol<FlutterMethodChannel*> _textInputChannel;
base::scoped_nsprotocol<FlutterMessageChannel*> _lifecycleChannel;
base::scoped_nsprotocol<FlutterMessageChannel*> _systemChannel;
fml::scoped_nsprotocol<FlutterPlatformPlugin*> _platformPlugin;
fml::scoped_nsprotocol<FlutterTextInputPlugin*> _textInputPlugin;
fml::scoped_nsprotocol<FlutterMethodChannel*> _localizationChannel;
fml::scoped_nsprotocol<FlutterMethodChannel*> _navigationChannel;
fml::scoped_nsprotocol<FlutterMethodChannel*> _platformChannel;
fml::scoped_nsprotocol<FlutterMethodChannel*> _textInputChannel;
fml::scoped_nsprotocol<FlutterMessageChannel*> _lifecycleChannel;
fml::scoped_nsprotocol<FlutterMessageChannel*> _systemChannel;
BOOL _initialized;
}
@@ -123,49 +122,54 @@ void FlutterInit(int argc, const char* argv[]) {
_orientationPreferences = UIInterfaceOrientationMaskAll;
_statusBarStyle = UIStatusBarStyleDefault;
_platformView = std::make_unique<shell::PlatformViewIOS>(
reinterpret_cast<CAEAGLLayer*>(self.view.layer));
reinterpret_cast<CAEAGLLayer*>(self.view.layer));
_platformView->SetupResourceContextOnIOThread();
_localizationChannel.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/localization"
initWithName:@"flutter/localization"
binaryMessenger:self
codec:[FlutterJSONMethodCodec sharedInstance]]);
codec:[FlutterJSONMethodCodec sharedInstance]]);
_navigationChannel.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/navigation"
initWithName:@"flutter/navigation"
binaryMessenger:self
codec:[FlutterJSONMethodCodec sharedInstance]]);
codec:[FlutterJSONMethodCodec sharedInstance]]);
_platformChannel.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/platform"
initWithName:@"flutter/platform"
binaryMessenger:self
codec:[FlutterJSONMethodCodec sharedInstance]]);
codec:[FlutterJSONMethodCodec sharedInstance]]);
_textInputChannel.reset([[FlutterMethodChannel alloc]
initWithName:@"flutter/textinput"
initWithName:@"flutter/textinput"
binaryMessenger:self
codec:[FlutterJSONMethodCodec sharedInstance]]);
codec:[FlutterJSONMethodCodec sharedInstance]]);
_lifecycleChannel.reset([[FlutterMessageChannel alloc]
initWithName:@"flutter/lifecycle"
initWithName:@"flutter/lifecycle"
binaryMessenger:self
codec:[FlutterStringCodec sharedInstance]]);
codec:[FlutterStringCodec sharedInstance]]);
_systemChannel.reset([[FlutterMessageChannel alloc]
initWithName:@"flutter/system"
initWithName:@"flutter/system"
binaryMessenger:self
codec:[FlutterJSONMessageCodec sharedInstance]]);
codec:[FlutterJSONMessageCodec sharedInstance]]);
_platformPlugin.reset([[FlutterPlatformPlugin alloc] init]);
[_platformChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResultReceiver resultReceiver) {
[_platformPlugin.get() handleMethodCall:call resultReceiver:resultReceiver];
[_platformChannel.get() setMethodCallHandler:^(
FlutterMethodCall* call,
FlutterResultReceiver resultReceiver) {
[_platformPlugin.get() handleMethodCall:call resultReceiver:resultReceiver];
}];
_textInputPlugin.reset([[FlutterTextInputPlugin alloc] init]);
_textInputPlugin.get().textInputDelegate = self;
[_textInputChannel.get() setMethodCallHandler:^(FlutterMethodCall* call, FlutterResultReceiver resultReceiver) {
[_textInputPlugin.get() handleMethodCall:call resultReceiver:resultReceiver];
}];
[_textInputChannel.get()
setMethodCallHandler:^(FlutterMethodCall* call,
FlutterResultReceiver resultReceiver) {
[_textInputPlugin.get() handleMethodCall:call
resultReceiver:resultReceiver];
}];
[self setupNotificationCenterObservers];
@@ -333,7 +337,7 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase(
break;
}
DCHECK(device_id != 0);
FTL_DCHECK(device_id != 0);
CGPoint windowCoordinates = [touch locationInView:nil];
blink::PointerData pointer_data;
@@ -429,7 +433,8 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase(
#pragma mark - Text input delegate
- (void)updateEditingClient:(int)client withState:(NSDictionary*)state {
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState" arguments:@[ @(client), state ]];
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState"
arguments:@[ @(client), state ]];
}
#pragma mark - Orientation updates
@@ -488,13 +493,14 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase(
NSLocale* currentLocale = [NSLocale currentLocale];
NSString* languageCode = [currentLocale objectForKey:NSLocaleLanguageCode];
NSString* countryCode = [currentLocale objectForKey:NSLocaleCountryCode];
[_localizationChannel.get() invokeMethod:@"setLocale" arguments: @[ languageCode, countryCode ]];
[_localizationChannel.get() invokeMethod:@"setLocale"
arguments:@[ languageCode, countryCode ]];
}
#pragma mark - Surface creation and teardown updates
- (void)surfaceUpdated:(BOOL)appeared {
CHECK(_platformView != nullptr);
FTL_CHECK(_platformView != nullptr);
if (appeared) {
_platformView->NotifyCreated();

View File

@@ -6,7 +6,6 @@
#include <vector>
#include "base/strings/sys_string_conversions.h"
#include "flutter/shell/platform/darwin/common/buffer_conversions.h"
namespace shell {

View File

@@ -21,7 +21,6 @@
@implementation VSyncClient {
CADisplayLink* _displayLink;
shell::VsyncWaiter::Callback _pendingCallback;
bool _traceCounter;
}
- (instancetype)init {
@@ -50,8 +49,6 @@
}
- (void)onDisplayLink:(CADisplayLink*)link {
_traceCounter = !_traceCounter;
TRACE_COUNTER1("flutter", "OnDisplayLink", _traceCounter);
_displayLink.paused = YES;
// Note: Even though we know we are on the UI thread already (since the

View File

@@ -10,7 +10,7 @@
#import <OpenGLES/ES2/glext.h>
#import <QuartzCore/CAEAGLLayer.h>
#include "base/mac/scoped_nsobject.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "lib/ftl/macros.h"
@@ -35,9 +35,9 @@ class IOSGLContext {
bool ResourceMakeCurrent();
private:
base::scoped_nsobject<CAEAGLLayer> layer_;
base::scoped_nsobject<EAGLContext> context_;
base::scoped_nsobject<EAGLContext> resource_context_;
fml::scoped_nsobject<CAEAGLLayer> layer_;
fml::scoped_nsobject<EAGLContext> context_;
fml::scoped_nsobject<EAGLContext> resource_context_;
GLuint framebuffer_;
GLuint colorbuffer_;
GLuint depthbuffer_;

View File

@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/mac/scoped_nsautorelease_pool.h"
#include "flutter/shell/platform/darwin/ios/ios_gl_context.h"
namespace shell {
@@ -28,8 +27,6 @@ IOSGLContext::IOSGLContext(PlatformView::SurfaceConfig config,
storage_size_width_(0),
storage_size_height_(0),
valid_(false) {
base::mac::ScopedNSAutoreleasePool pool;
VERIFY(layer_ != nullptr);
VERIFY(context_ != nullptr);
VERIFY(resource_context_ != nullptr);
@@ -120,7 +117,7 @@ IOSGLContext::IOSGLContext(PlatformView::SurfaceConfig config,
}
IOSGLContext::~IOSGLContext() {
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
// Deletes on GL_NONEs are ignored
glDeleteFramebuffers(1, &framebuffer_);
@@ -130,7 +127,7 @@ IOSGLContext::~IOSGLContext() {
glDeleteRenderbuffers(1, &stencilbuffer_);
glDeleteRenderbuffers(1, &depth_stencil_packed_buffer_);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
}
bool IOSGLContext::IsValid() const {
@@ -138,8 +135,6 @@ bool IOSGLContext::IsValid() const {
}
bool IOSGLContext::PresentRenderBuffer() const {
base::mac::ScopedNSAutoreleasePool pool;
const GLenum discards[] = {
GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT,
};
@@ -167,12 +162,12 @@ bool IOSGLContext::UpdateStorageSizeIfNecessary() {
return false;
}
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer_);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
if (![context_.get() renderbufferStorage:GL_RENDERBUFFER
fromDrawable:layer_.get()]) {
@@ -189,11 +184,11 @@ bool IOSGLContext::UpdateStorageSizeIfNecessary() {
// so that backing of the attachments can be updated
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
&width);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
&height);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
rebind_color_buffer = true;
}
@@ -202,44 +197,41 @@ bool IOSGLContext::UpdateStorageSizeIfNecessary() {
glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil_packed_buffer_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width,
height);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
}
if (depthbuffer_ != GL_NONE) {
glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
}
if (stencilbuffer_ != GL_NONE) {
glBindRenderbuffer(GL_RENDERBUFFER, stencilbuffer_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
}
if (rebind_color_buffer) {
glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer_);
DCHECK(glGetError() == GL_NO_ERROR);
FTL_DCHECK(glGetError() == GL_NO_ERROR);
}
storage_size_width_ = width;
storage_size_height_ = height;
DCHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
FTL_DCHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
GL_FRAMEBUFFER_COMPLETE);
return true;
}
bool IOSGLContext::MakeCurrent() {
base::mac::ScopedNSAutoreleasePool pool;
return UpdateStorageSizeIfNecessary() &&
[EAGLContext setCurrentContext:context_.get()];
}
bool IOSGLContext::ResourceMakeCurrent() {
base::mac::ScopedNSAutoreleasePool pool;
return [EAGLContext setCurrentContext:resource_context_.get()];
}

View File

@@ -5,7 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_H_
#include "base/mac/scoped_nsobject.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "lib/ftl/macros.h"
@@ -37,7 +37,7 @@ class IOSSurface {
public:
PlatformView::SurfaceConfig surface_config_;
base::scoped_nsobject<CALayer> layer_;
fml::scoped_nsobject<CALayer> layer_;
FTL_DISALLOW_COPY_AND_ASSIGN(IOSSurface);
};

View File

@@ -7,7 +7,6 @@
#include <memory>
#include "base/mac/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_router.h"

View File

@@ -8,9 +8,8 @@
#include <utility>
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/trace_event/trace_event.h"
#include "flutter/common/threads.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/gpu/gpu_rasterizer.h"
#include "flutter/shell/platform/darwin/common/process_info_mac.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h"
@@ -24,12 +23,6 @@ PlatformViewIOS::PlatformViewIOS(CALayer* layer)
ios_surface_(IOSSurface::Create(surface_config_, layer)),
weak_factory_(this) {
CreateEngine();
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
shell::Shell::Shared().tracing_controller().set_traces_base_path(
[paths.firstObject UTF8String]);
PostAddToShellTask();
}

View File

@@ -5,8 +5,6 @@
#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "dart/runtime/bin/embedded_dart_io.h"
#include "flutter/common/threads.h"
@@ -18,6 +16,7 @@
#include "flutter/shell/testing/test_runner.h"
#include "flutter/shell/testing/testing.h"
#include "flutter/sky/engine/public/web/Sky.h"
#include "lib/ftl/command_line.h"
#include "lib/tonic/dart_microtask_queue.h"
namespace {
@@ -58,9 +57,7 @@ class ScriptCompletionTaskObserver : public base::MessageLoop::TaskObserver {
prev_live_ = live;
}
tonic::DartErrorHandleType last_error() {
return last_error_;
}
tonic::DartErrorHandleType last_error() { return last_error_; }
private:
base::MessageLoop& main_message_loop_;
@@ -81,10 +78,11 @@ int ConvertErrorTypeToExitCode(tonic::DartErrorHandleType error) {
}
}
void RunNonInteractive(bool run_forever) {
void RunNonInteractive(ftl::CommandLine initial_command_line,
bool run_forever) {
base::MessageLoop message_loop;
shell::Shell::InitStandalone();
shell::Shell::InitStandalone(initial_command_line);
// Note that this task observer must be added after the observer that drains
// the microtask queue.
@@ -95,7 +93,7 @@ void RunNonInteractive(bool run_forever) {
});
}
if (!shell::InitForTesting()) {
if (!shell::InitForTesting(std::move(initial_command_line))) {
shell::PrintUsage("sky_shell");
exit(1);
}
@@ -103,7 +101,8 @@ void RunNonInteractive(bool run_forever) {
message_loop.Run();
shell::TestRunner& test_runner = shell::TestRunner::Shared();
tonic::DartErrorHandleType error = test_runner.platform_view().engine().GetLoadScriptError();
tonic::DartErrorHandleType error =
test_runner.platform_view().engine().GetLoadScriptError();
if (error == tonic::kNoError)
error = task_observer.last_error();
if (error == tonic::kNoError)
@@ -119,19 +118,19 @@ static bool IsDartFile(const std::string& path) {
return path.rfind(dart_extension) == (path.size() - dart_extension.size());
}
int RunInteractive() {
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
int RunInteractive(ftl::CommandLine initial_command_line) {
base::MessageLoop message_loop(shell::MessagePumpGLFW::Create());
shell::Shell::InitStandalone();
shell::Shell::InitStandalone(std::move(initial_command_line));
std::string target = command_line.GetSwitchValueASCII(
shell::FlagForSwitch(shell::Switch::FLX));
const auto& command_line = shell::Shell::Shared().GetCommandLine();
std::string target = command_line.GetOptionValueWithDefault(
shell::FlagForSwitch(shell::Switch::FLX), "");
if (target.empty()) {
// Alternatively, use the first positional argument.
auto args = command_line.GetArgs();
auto args = command_line.positional_args();
if (args.empty())
return 1;
target = args[0];
@@ -172,22 +171,21 @@ int main(int argc, char* argv[]) {
dart::bin::SetExecutableArguments(argc - 1, argv);
base::AtExitManager exit_manager;
base::CommandLine::Init(argc, argv);
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
auto command_line = ftl::CommandLineFromArgcArgv(argc, argv);
if (command_line.HasSwitch(shell::FlagForSwitch(shell::Switch::Help))) {
if (command_line.HasOption(shell::FlagForSwitch(shell::Switch::Help))) {
shell::PrintUsage("sky_shell");
return 0;
}
if (command_line.HasSwitch(
if (command_line.HasOption(
shell::FlagForSwitch(shell::Switch::NonInteractive))) {
bool run_forever = command_line.HasSwitch(
shell::FlagForSwitch(shell::Switch::RunForever));
RunNonInteractive(run_forever);
bool run_forever =
command_line.HasOption(shell::FlagForSwitch(shell::Switch::RunForever));
RunNonInteractive(std::move(command_line), run_forever);
return 0;
}
return RunInteractive();
return RunInteractive(std::move(command_line));
}

View File

@@ -7,7 +7,6 @@
#include <GLFW/glfw3.h>
#include "base/auto_reset.h"
#include "base/logging.h"
#include "base/time/time.h"
namespace shell {

View File

@@ -132,7 +132,7 @@ void PlatformViewGLFW::OnMouseButtonChanged(int button, int action, int mods) {
change = blink::PointerData::Change::kMove;
}
} else {
DLOG(INFO) << "Unknown mouse action: " << action;
FTL_DLOG(INFO) << "Unknown mouse action: " << action;
return;
}
@@ -140,11 +140,10 @@ void PlatformViewGLFW::OnMouseButtonChanged(int button, int action, int mods) {
double y = 0.0;
glfwGetCursorPos(glfw_window_, &x, &y);
base::TimeDelta time_stamp = base::TimeTicks::Now() - base::TimeTicks();
blink::PointerData pointer_data;
pointer_data.Clear();
pointer_data.time_stamp = time_stamp.InMicroseconds();
pointer_data.time_stamp =
ftl::TimePoint::Now().ToEpochDelta().ToMicroseconds();
pointer_data.change = change;
pointer_data.kind = blink::PointerData::DeviceKind::kMouse;
pointer_data.physical_x = x;
@@ -164,11 +163,10 @@ void PlatformViewGLFW::OnMouseButtonChanged(int button, int action, int mods) {
}
void PlatformViewGLFW::OnCursorPosChanged(double x, double y) {
base::TimeDelta time_stamp = base::TimeTicks::Now() - base::TimeTicks();
blink::PointerData pointer_data;
pointer_data.Clear();
pointer_data.time_stamp = time_stamp.InMicroseconds();
pointer_data.time_stamp =
ftl::TimePoint::Now().ToEpochDelta().ToMicroseconds();
pointer_data.change = blink::PointerData::Change::kMove;
pointer_data.kind = blink::PointerData::DeviceKind::kMouse;
pointer_data.physical_x = x;

View File

@@ -13,7 +13,6 @@ source_set("testing") {
]
deps = [
"//base",
"//flutter/common",
"//flutter/shell/common",
"//lib/ftl",

View File

@@ -4,23 +4,19 @@
#include "flutter/shell/testing/testing.h"
#include "base/command_line.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/testing/test_runner.h"
namespace shell {
bool InitForTesting() {
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
bool InitForTesting(const ftl::CommandLine& command_line) {
TestRunner::TestDescriptor test;
test.packages =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::Packages));
auto args = command_line.GetArgs();
test.packages = command_line.GetOptionValueWithDefault(
FlagForSwitch(Switch::Packages), "");
auto args = command_line.positional_args();
if (args.empty())
return false;
test.path = args[0];
TestRunner::Shared().Run(test);
return true;
}

View File

@@ -5,9 +5,11 @@
#ifndef SHELL_TESTING_TESTING_H_
#define SHELL_TESTING_TESTING_H_
#include "lib/ftl/command_line.h"
namespace shell {
bool InitForTesting();
bool InitForTesting(const ftl::CommandLine& command_line);
} // namespace shell