提交 1c07ea53 编写于 作者: C Chinmay Garde 提交者: GitHub

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

上级 98063f9d
......@@ -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",
......
......@@ -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
#
......
......@@ -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);
......
......@@ -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",
]
}
# 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" ]
}
// 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_
// 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
// 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_
// 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
// 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_
// 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
......@@ -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 {
......
......@@ -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" ]
}
}
......@@ -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
// 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
// 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_
......@@ -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_
......@@ -19,7 +19,7 @@ source_set("jni") {
]
deps = [
"//base",
"//flutter/fml",
"//lib/tonic",
]
}
......@@ -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;
}
......
......@@ -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);
......
......@@ -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
......@@ -9,7 +9,7 @@
namespace blink {
using tonic::ToDart;
using base::android::ScopedJavaLocalRef;
using fml::jni::ScopedJavaLocalRef;
IMPLEMENT_WRAPPERTYPEINFO(jni, JniClass);
......
......@@ -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"
......
......@@ -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") {
......
......@@ -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
......
......@@ -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",
......
......@@ -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();
});
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
base::Thread::Options options;
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);
Shell::Shell(ftl::CommandLine command_line)
: command_line_(std::move(command_line)) {
FTL_DCHECK(!g_shell);
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()));
gpu_thread_.reset(new fml::Thread("gpu_thread"));
ui_thread_.reset(new fml::Thread("ui_thread"));
io_thread_.reset(new fml::Thread("io_thread"));
// 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));
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));
settings.temp_directory_path =
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::CacheDirPath));
command_line.HasOption(FlagForSwitch(Switch::TraceStartup));
command_line.GetOptionValue(FlagForSwitch(Switch::AotSnapshotPath),
&settings.aot_snapshot_path);
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;
......
......@@ -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<fml::Thread> gpu_thread_;
std::unique_ptr<fml::Thread> ui_thread_;
std::unique_ptr<fml::Thread> io_thread_;
std::unique_ptr<base::ThreadChecker> gpu_thread_checker_;
std::unique_ptr<base::ThreadChecker> ui_thread_checker_;
std::unique_ptr<fml::ThreadChecker> gpu_thread_checker_;
std::unique_ptr<fml::ThreadChecker> ui_thread_checker_;
TracingController tracing_controller_;
......
......@@ -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,
const char* name,
SkEventTracer::Handle handle) override;
};
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;
}
const uint8_t*
SkChromiumEventTracer::getCategoryGroupEnabled(const char* name) {
return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(name);
}
void updateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name,
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 char* SkChromiumEventTracer::getCategoryGroupName(
const uint8_t* categoryEnabledFlag) {
return base::trace_event::TraceLog::GetCategoryGroupName(categoryEnabledFlag);
}
const uint8_t* getCategoryGroupEnabled(const char* name) override {
static const uint8_t kYes = 1;
return &kYes;
}
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;
}
const char* getCategoryGroupName(
const uint8_t* category_enabled_flag) override {
return kSkiaTag;
}
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);
}
private:
FTL_DISALLOW_COPY_AND_ASSIGN(FlutterEventTracer);
};
} // 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());
}
......@@ -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
......@@ -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);
};
......
......@@ -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
......@@ -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);
};
......
......@@ -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",
]
}
......@@ -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);
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();
for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
args.push_back(std::move(arg));
}
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
......@@ -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;
}
......
......@@ -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;
......
// 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();
}
}
......@@ -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.
......
......@@ -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);
......
......@@ -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.
**/
......
......@@ -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
......
......@@ -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));
}
// This is called by the VM when the shared library is first loaded.
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// Initialize the Java VM.
fml::jni::InitJavaVM(vm);
bool InitJNI() {
return blink::DartJni::InitJni();
}
JNIEnv* env = fml::jni::AttachCurrentThread();
bool result = false;
} // namespace
// Register FlutterMain.
result = shell::RegisterFlutterMain(env);
FTL_CHECK(result);
// 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));
// Register PlatformView
result = shell::PlatformViewAndroid::Register(env);
FTL_CHECK(result);
std::vector<base::android::InitCallback> init_callbacks;
init_callbacks.push_back(base::Bind(&InitJNI));
// Register VSyncWaiter.
result = shell::VsyncWaiterAndroid::Register(env);
FTL_CHECK(result);
if (!base::android::OnJNIOnLoadRegisterJNI(vm, register_callbacks) ||
!base::android::OnJNIOnLoadInit(init_callbacks)) {
return -1;
}
// Register DartJni
result = blink::DartJni::InitJni();
FTL_CHECK(result);
return JNI_VERSION_1_4;
}
......@@ -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
......@@ -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);
};
......
// 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
// 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_
......@@ -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
......@@ -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);
......
......@@ -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
......
......@@ -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",
......
......@@ -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();
RedirectIOConnectionsToSyslog();
auto command_line = InitializedCommandLine();
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);
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
TRACE_EVENT_INSTANT0("flutter", "main");
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
......
......@@ -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",
......
......@@ -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_
......@@ -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
......@@ -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));
......
......@@ -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);
}
......@@ -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;
......
......@@ -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)
......
......@@ -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",
......
......@@ -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;
......
......@@ -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];
......
......@@ -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();
......
......@@ -6,7 +6,6 @@
#include <vector>
#include "base/strings/sys_string_conversions.h"
#include "flutter/shell/platform/darwin/common/buffer_conversions.h"
namespace shell {
......
......@@ -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
......
......@@ -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_;
......
......@@ -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()];
}
......
......@@ -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);
};
......
......@@ -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"
......
......@@ -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();
}
......
......@@ -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));
const auto& command_line = shell::Shell::Shared().GetCommandLine();
std::string target = command_line.GetSwitchValueASCII(
shell::FlagForSwitch(shell::Switch::FLX));
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));
}
......@@ -7,7 +7,6 @@
#include <GLFW/glfw3.h>
#include "base/auto_reset.h"
#include "base/logging.h"
#include "base/time/time.h"
namespace shell {
......
......@@ -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;
......
......@@ -13,7 +13,6 @@ source_set("testing") {
]
deps = [
"//base",
"//flutter/common",
"//flutter/shell/common",
"//lib/ftl",
......
......@@ -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;
}
......
......@@ -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
......
......@@ -45,10 +45,6 @@ static_library("core") {
"//third_party/zlib",
]
if (!is_fuchsia) {
public_deps += [ "//base" ]
}
if (flutter_runtime_mode != "release") {
public_deps += [ "//lib/tonic/debugger" ]
}
......
......@@ -8,6 +8,7 @@ source_set("web") {
]
deps = [
"//flutter/fml",
"//flutter/sky/engine/core",
"//flutter/sky/engine/platform",
]
......
......@@ -35,9 +35,9 @@
#include "flutter/sky/engine/public/platform/Platform.h"
#include "flutter/sky/engine/wtf/Assertions.h"
#include "flutter/sky/engine/wtf/MainThread.h"
#include "flutter/sky/engine/wtf/WTF.h"
#include "flutter/sky/engine/wtf/text/AtomicString.h"
#include "flutter/sky/engine/wtf/text/TextEncoding.h"
#include "flutter/sky/engine/wtf/WTF.h"
#include "lib/ftl/build_config.h"
#include "lib/tonic/dart_microtask_queue.h"
......@@ -47,7 +47,7 @@
#else // defined(OS_FUCHSIA)
#include "base/message_loop/message_loop.h"
#include "flutter/fml/message_loop.h"
#endif // defined(OS_FUCHSIA)
......@@ -72,29 +72,12 @@ void removeMessageLoopObservers() {
#else // defined(OS_FUCHSIA)
class TaskObserver : public base::MessageLoop::TaskObserver {
public:
void WillProcessTask(const base::PendingTask& pending_task) override {}
void DidProcessTask(const base::PendingTask& pending_task) override {
didProcessTask();
}
};
static TaskObserver* s_taskObserver = 0;
void addMessageLoopObservers() {
ASSERT(!s_taskObserver);
s_taskObserver = new TaskObserver;
base::MessageLoop::current()->AddTaskObserver(s_taskObserver);
fml::MessageLoop::GetCurrent().SetTaskObserver(&didProcessTask);
}
void removeMessageLoopObservers() {
base::MessageLoop::current()->RemoveTaskObserver(s_taskObserver);
ASSERT(s_taskObserver);
delete s_taskObserver;
s_taskObserver = 0;
fml::MessageLoop::GetCurrent().SetTaskObserver(nullptr);
}
#endif // defined(OS_FUCHSIA)
......
......@@ -1701,8 +1701,6 @@ FILE: ../../../flutter/flow/scene_update_context.h
FILE: ../../../flutter/glue/stack_trace.h
FILE: ../../../flutter/glue/stack_trace_base.cc
FILE: ../../../flutter/glue/stack_trace_fuchsia.cc
FILE: ../../../flutter/glue/task_runner_adaptor.cc
FILE: ../../../flutter/glue/task_runner_adaptor.h
FILE: ../../../flutter/glue/trace_event.h
FILE: ../../../flutter/lib/jni/dart_jni.cc
FILE: ../../../flutter/lib/jni/dart_jni.h
......@@ -1927,8 +1925,13 @@ FILE: ../../../flutter/fml/platform/darwin/cf_utils.cc
FILE: ../../../flutter/fml/platform/darwin/cf_utils.h
FILE: ../../../flutter/fml/platform/darwin/message_loop_darwin.h
FILE: ../../../flutter/fml/platform/darwin/message_loop_darwin.mm
FILE: ../../../flutter/fml/platform/darwin/nsstring_utils.h
FILE: ../../../flutter/fml/platform/darwin/nsstring_utils.mm
FILE: ../../../flutter/fml/platform/darwin/resource_mapping_darwin.h
FILE: ../../../flutter/fml/platform/darwin/resource_mapping_darwin.mm
FILE: ../../../flutter/fml/platform/darwin/scoped_block.mm
FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.h
FILE: ../../../flutter/fml/platform/darwin/scoped_nsobject.mm
FILE: ../../../flutter/fml/platform/linux/message_loop_linux.cc
FILE: ../../../flutter/fml/platform/linux/message_loop_linux.h
FILE: ../../../flutter/fml/platform/linux/timerfd.cc
......@@ -1958,6 +1961,9 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodCod
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardMessageCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StringCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/util/PathUtils.java
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterBinaryMessenger.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterChannels.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterCodecs.h
......@@ -2179,6 +2185,41 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================================================
====================================================================================================
LIBRARY: engine
ORIGIN: ../../../flutter/fml/platform/darwin/scoped_block.h + ../../../LICENSE
TYPE: LicenseType.bsd
FILE: ../../../flutter/fml/platform/darwin/scoped_block.h
----------------------------------------------------------------------------------------------------
Copyright (c) 2013 The Chromium Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================================================
====================================================================================================
LIBRARY: engine
ORIGIN: ../../../flutter/lib/ui/painting/image.cc + ../../../LICENSE
......@@ -9330,4 +9371,4 @@ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================================================
Total license count: 207
Total license count: 208
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册