Remove uses of //base from all //flutter projects and replace them with //fml variants. (flutter/engine#3492)
This commit is contained in:
2
DEPS
2
DEPS
@@ -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
|
||||
#
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
source_set("darwin") {
|
||||
visibility = [ "//flutter/fml" ]
|
||||
|
||||
sources = [
|
||||
"cf_utils.cc",
|
||||
"cf_utils.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//lib/ftl",
|
||||
]
|
||||
|
||||
libs = [ "CoreFoundation.framework" ]
|
||||
}
|
||||
22
engine/src/flutter/fml/platform/darwin/nsstring_utils.h
Normal file
22
engine/src/flutter/fml/platform/darwin/nsstring_utils.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_FML_PLATFORM_DARWIN_NSSTRING_UTILS_H_
|
||||
#define FLUTTER_FML_PLATFORM_DARWIN_NSSTRING_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "lib/ftl/macros.h"
|
||||
|
||||
@class NSString;
|
||||
|
||||
namespace fml {
|
||||
|
||||
NSString* StringToNSString(const std::u16string& string);
|
||||
|
||||
std::u16string StringFromNSString(NSString* string);
|
||||
|
||||
} // namespace fml
|
||||
|
||||
#endif // FLUTTER_FML_PLATFORM_DARWIN_NSSTRING_UTILS_H_
|
||||
25
engine/src/flutter/fml/platform/darwin/nsstring_utils.mm
Normal file
25
engine/src/flutter/fml/platform/darwin/nsstring_utils.mm
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/fml/platform/darwin/nsstring_utils.h"
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
namespace fml {
|
||||
|
||||
NSString* StringToNSString(const std::u16string& string) {
|
||||
return [[[NSString alloc] initWithBytes:string.data()
|
||||
length:string.length()
|
||||
encoding:NSUTF16StringEncoding] autorelease];
|
||||
}
|
||||
|
||||
std::u16string StringFromNSString(NSString* string) {
|
||||
if (string.length == 0) {
|
||||
return {};
|
||||
}
|
||||
NSData* data = [string dataUsingEncoding:NSUTF16StringEncoding];
|
||||
return {reinterpret_cast<const char16_t*>(data.bytes), data.length};
|
||||
}
|
||||
|
||||
} // namespace fml
|
||||
87
engine/src/flutter/fml/platform/darwin/scoped_block.h
Normal file
87
engine/src/flutter/fml/platform/darwin/scoped_block.h
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
|
||||
#define FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
|
||||
|
||||
#include <Block.h>
|
||||
|
||||
#include "lib/ftl/compiler_specific.h"
|
||||
|
||||
namespace fml {
|
||||
|
||||
// ScopedBlock<> is patterned after ScopedCFTypeRef<>, but uses Block_copy() and
|
||||
// Block_release() instead of CFRetain() and CFRelease().
|
||||
|
||||
enum class OwnershipPolicy {
|
||||
// The scoped object takes ownership of an object by taking over an existing
|
||||
// ownership claim.
|
||||
Assume,
|
||||
|
||||
// The scoped object will retain the the object and any initial ownership is
|
||||
// not changed.
|
||||
Retain,
|
||||
};
|
||||
|
||||
template <typename B>
|
||||
class ScopedBlock {
|
||||
public:
|
||||
explicit ScopedBlock(B block = nullptr,
|
||||
OwnershipPolicy policy = OwnershipPolicy::Assume)
|
||||
: block_(block) {
|
||||
if (block_ && policy == OwnershipPolicy::Retain)
|
||||
block_ = Block_copy(block);
|
||||
}
|
||||
|
||||
ScopedBlock(const ScopedBlock<B>& that) : block_(that.block_) {
|
||||
if (block_)
|
||||
block_ = Block_copy(block_);
|
||||
}
|
||||
|
||||
~ScopedBlock() {
|
||||
if (block_)
|
||||
Block_release(block_);
|
||||
}
|
||||
|
||||
ScopedBlock& operator=(const ScopedBlock<B>& that) {
|
||||
reset(that.get(), OwnershipPolicy::Retain);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset(B block = nullptr,
|
||||
OwnershipPolicy policy = OwnershipPolicy::Assume) {
|
||||
if (block && policy == OwnershipPolicy::Retain)
|
||||
block = Block_copy(block);
|
||||
if (block_)
|
||||
Block_release(block_);
|
||||
block_ = block;
|
||||
}
|
||||
|
||||
bool operator==(B that) const { return block_ == that; }
|
||||
|
||||
bool operator!=(B that) const { return block_ != that; }
|
||||
|
||||
operator B() const { return block_; }
|
||||
|
||||
B get() const { return block_; }
|
||||
|
||||
void swap(ScopedBlock& that) {
|
||||
B temp = that.block_;
|
||||
that.block_ = block_;
|
||||
block_ = temp;
|
||||
}
|
||||
|
||||
B release() FTL_WARN_UNUSED_RESULT {
|
||||
B temp = block_;
|
||||
block_ = nullptr;
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
B block_;
|
||||
};
|
||||
|
||||
} // namespace fml
|
||||
|
||||
#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_BLOCK_H_
|
||||
11
engine/src/flutter/fml/platform/darwin/scoped_block.mm
Normal file
11
engine/src/flutter/fml/platform/darwin/scoped_block.mm
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/fml/platform/darwin/scoped_block.h"
|
||||
|
||||
namespace fml {
|
||||
|
||||
//
|
||||
|
||||
} // namespace fml
|
||||
163
engine/src/flutter/fml/platform/darwin/scoped_nsobject.h
Normal file
163
engine/src/flutter/fml/platform/darwin/scoped_nsobject.h
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
|
||||
#define FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
|
||||
|
||||
// Include NSObject.h directly because Foundation.h pulls in many dependencies.
|
||||
// (Approx 100k lines of code versus 1.5k for NSObject.h). scoped_nsobject gets
|
||||
// singled out because it is most typically included from other header files.
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
#include "lib/ftl/compiler_specific.h"
|
||||
#include "lib/ftl/macros.h"
|
||||
|
||||
@class NSAutoreleasePool;
|
||||
|
||||
namespace fml {
|
||||
|
||||
// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership
|
||||
// of an NSObject subclass object. Style deviations here are solely for
|
||||
// compatibility with scoped_ptr<>'s interface, with which everyone is already
|
||||
// familiar.
|
||||
//
|
||||
// scoped_nsobject<> takes ownership of an object (in the constructor or in
|
||||
// reset()) by taking over the caller's existing ownership claim. The caller
|
||||
// must own the object it gives to scoped_nsobject<>, and relinquishes an
|
||||
// ownership claim to that object. scoped_nsobject<> does not call -retain,
|
||||
// callers have to call this manually if appropriate.
|
||||
//
|
||||
// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used
|
||||
// with protocols.
|
||||
//
|
||||
// scoped_nsobject<> is not to be used for NSAutoreleasePools. For
|
||||
// NSAutoreleasePools use ScopedNSAutoreleasePool from
|
||||
// scoped_nsautorelease_pool.h instead.
|
||||
// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile
|
||||
// time with a template specialization (see below).
|
||||
|
||||
template <typename NST>
|
||||
class scoped_nsprotocol {
|
||||
public:
|
||||
explicit scoped_nsprotocol(NST object = nil) : object_(object) {}
|
||||
|
||||
scoped_nsprotocol(const scoped_nsprotocol<NST>& that)
|
||||
: object_([that.object_ retain]) {}
|
||||
|
||||
template <typename NSU>
|
||||
scoped_nsprotocol(const scoped_nsprotocol<NSU>& that)
|
||||
: object_([that.get() retain]) {}
|
||||
|
||||
~scoped_nsprotocol() { [object_ release]; }
|
||||
|
||||
scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) {
|
||||
reset([that.get() retain]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset(NST object = nil) {
|
||||
// We intentionally do not check that object != object_ as the caller must
|
||||
// either already have an ownership claim over whatever it passes to this
|
||||
// method, or call it with the |RETAIN| policy which will have ensured that
|
||||
// the object is retained once more when reaching this point.
|
||||
[object_ release];
|
||||
object_ = object;
|
||||
}
|
||||
|
||||
bool operator==(NST that) const { return object_ == that; }
|
||||
bool operator!=(NST that) const { return object_ != that; }
|
||||
|
||||
operator NST() const { return object_; }
|
||||
|
||||
NST get() const { return object_; }
|
||||
|
||||
void swap(scoped_nsprotocol& that) {
|
||||
NST temp = that.object_;
|
||||
that.object_ = object_;
|
||||
object_ = temp;
|
||||
}
|
||||
|
||||
// scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a
|
||||
// wrapper for [object_ release]. To force a scoped_nsprotocol<> to call
|
||||
// [object_ release], use scoped_nsprotocol<>::reset().
|
||||
NST release() FTL_WARN_UNUSED_RESULT {
|
||||
NST temp = object_;
|
||||
object_ = nil;
|
||||
return temp;
|
||||
}
|
||||
|
||||
// Shift reference to the autorelease pool to be released later.
|
||||
NST autorelease() { return [release() autorelease]; }
|
||||
|
||||
private:
|
||||
NST object_;
|
||||
};
|
||||
|
||||
// Free functions
|
||||
template <class C>
|
||||
void swap(scoped_nsprotocol<C>& p1, scoped_nsprotocol<C>& p2) {
|
||||
p1.swap(p2);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
bool operator==(C p1, const scoped_nsprotocol<C>& p2) {
|
||||
return p1 == p2.get();
|
||||
}
|
||||
|
||||
template <class C>
|
||||
bool operator!=(C p1, const scoped_nsprotocol<C>& p2) {
|
||||
return p1 != p2.get();
|
||||
}
|
||||
|
||||
template <typename NST>
|
||||
class scoped_nsobject : public scoped_nsprotocol<NST*> {
|
||||
public:
|
||||
explicit scoped_nsobject(NST* object = nil)
|
||||
: scoped_nsprotocol<NST*>(object) {}
|
||||
|
||||
scoped_nsobject(const scoped_nsobject<NST>& that)
|
||||
: scoped_nsprotocol<NST*>(that) {}
|
||||
|
||||
template <typename NSU>
|
||||
scoped_nsobject(const scoped_nsobject<NSU>& that)
|
||||
: scoped_nsprotocol<NST*>(that) {}
|
||||
|
||||
scoped_nsobject& operator=(const scoped_nsobject<NST>& that) {
|
||||
scoped_nsprotocol<NST*>::operator=(that);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization to make scoped_nsobject<id> work.
|
||||
template <>
|
||||
class scoped_nsobject<id> : public scoped_nsprotocol<id> {
|
||||
public:
|
||||
explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {}
|
||||
|
||||
scoped_nsobject(const scoped_nsobject<id>& that)
|
||||
: scoped_nsprotocol<id>(that) {}
|
||||
|
||||
template <typename NSU>
|
||||
scoped_nsobject(const scoped_nsobject<NSU>& that)
|
||||
: scoped_nsprotocol<id>(that) {}
|
||||
|
||||
scoped_nsobject& operator=(const scoped_nsobject<id>& that) {
|
||||
scoped_nsprotocol<id>::operator=(that);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// Do not use scoped_nsobject for NSAutoreleasePools, use
|
||||
// ScopedNSAutoreleasePool instead. This is a compile time check. See details
|
||||
// at top of header.
|
||||
template <>
|
||||
class scoped_nsobject<NSAutoreleasePool> {
|
||||
private:
|
||||
explicit scoped_nsobject(NSAutoreleasePool* object = nil);
|
||||
FTL_DISALLOW_COPY_AND_ASSIGN(scoped_nsobject);
|
||||
};
|
||||
|
||||
} // namespace fml
|
||||
|
||||
#endif // FLUTTER_FML_PLATFORM_DARWIN_SCOPED_NSOBJECT_H_
|
||||
11
engine/src/flutter/fml/platform/darwin/scoped_nsobject.mm
Normal file
11
engine/src/flutter/fml/platform/darwin/scoped_nsobject.mm
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
|
||||
|
||||
namespace fml {
|
||||
|
||||
//
|
||||
|
||||
} // namespace fml
|
||||
@@ -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
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/glue/task_runner_adaptor.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/location.h"
|
||||
#include "base/task_runner.h"
|
||||
|
||||
namespace glue {
|
||||
namespace {
|
||||
|
||||
void RunClosure(ftl::Closure task) {
|
||||
task();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TaskRunnerAdaptor::TaskRunnerAdaptor(scoped_refptr<base::TaskRunner> runner)
|
||||
: runner_(std::move(runner)) {
|
||||
FTL_DCHECK(runner_);
|
||||
}
|
||||
|
||||
TaskRunnerAdaptor::~TaskRunnerAdaptor() {}
|
||||
|
||||
void TaskRunnerAdaptor::PostTask(ftl::Closure task) {
|
||||
runner_->PostTask(FROM_HERE, base::Bind(RunClosure, task));
|
||||
}
|
||||
|
||||
void TaskRunnerAdaptor::PostTaskForTime(ftl::Closure task,
|
||||
ftl::TimePoint target_time) {
|
||||
ftl::TimePoint now = ftl::TimePoint::Now();
|
||||
runner_->PostDelayedTask(FROM_HERE, base::Bind(RunClosure, task),
|
||||
target_time <= now
|
||||
? base::TimeDelta()
|
||||
: base::TimeDelta::FromMicroseconds(
|
||||
(target_time - now).ToMicroseconds()));
|
||||
}
|
||||
|
||||
void TaskRunnerAdaptor::PostDelayedTask(ftl::Closure task,
|
||||
ftl::TimeDelta delay) {
|
||||
runner_->PostDelayedTask(
|
||||
FROM_HERE, base::Bind(RunClosure, task),
|
||||
base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
|
||||
}
|
||||
|
||||
bool TaskRunnerAdaptor::RunsTasksOnCurrentThread() {
|
||||
return runner_->RunsTasksOnCurrentThread();
|
||||
}
|
||||
|
||||
} // namespace glue
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_GLU_BASE_TASK_RUNNER_H_
|
||||
#define FLUTTER_GLU_BASE_TASK_RUNNER_H_
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "lib/ftl/tasks/task_runner.h"
|
||||
|
||||
namespace base {
|
||||
class TaskRunner;
|
||||
} // namespace base
|
||||
|
||||
namespace glue {
|
||||
|
||||
class TaskRunnerAdaptor : public ftl::TaskRunner {
|
||||
public:
|
||||
explicit TaskRunnerAdaptor(scoped_refptr<base::TaskRunner> runner);
|
||||
|
||||
void PostTask(ftl::Closure task) override;
|
||||
void PostTaskForTime(ftl::Closure task, ftl::TimePoint target_time) override;
|
||||
void PostDelayedTask(ftl::Closure task, ftl::TimeDelta delay) override;
|
||||
bool RunsTasksOnCurrentThread() override;
|
||||
|
||||
protected:
|
||||
~TaskRunnerAdaptor() override;
|
||||
|
||||
private:
|
||||
scoped_refptr<base::TaskRunner> runner_;
|
||||
};
|
||||
|
||||
} // namespace glue
|
||||
|
||||
#endif // FLUTTER_GLU_BASE_TASK_RUNNER_H_
|
||||
@@ -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);
|
||||
Shell::Shell(ftl::CommandLine command_line)
|
||||
: command_line_(std::move(command_line)) {
|
||||
FTL_DCHECK(!g_shell);
|
||||
|
||||
base::Thread::Options options;
|
||||
gpu_thread_.reset(new fml::Thread("gpu_thread"));
|
||||
ui_thread_.reset(new fml::Thread("ui_thread"));
|
||||
io_thread_.reset(new fml::Thread("io_thread"));
|
||||
|
||||
gpu_thread_.reset(new base::Thread("gpu_thread"));
|
||||
gpu_thread_->StartWithOptions(options);
|
||||
|
||||
ui_thread_.reset(new base::Thread("ui_thread"));
|
||||
ui_thread_->StartWithOptions(options);
|
||||
|
||||
io_thread_.reset(new base::Thread("io_thread"));
|
||||
io_thread_->StartWithOptions(options);
|
||||
|
||||
blink::Threads threads(ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
|
||||
base::MessageLoop::current()->task_runner()),
|
||||
ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
|
||||
gpu_thread_->message_loop()->task_runner()),
|
||||
ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
|
||||
ui_thread_->message_loop()->task_runner()),
|
||||
ftl::MakeRefCounted<glue::TaskRunnerAdaptor>(
|
||||
io_thread_->message_loop()->task_runner()));
|
||||
// Since we are not using fml::Thread, we need to initialize the message loop
|
||||
// manually.
|
||||
fml::MessageLoop::EnsureInitializedForCurrentThread();
|
||||
blink::Threads threads(fml::MessageLoop::GetCurrent().GetTaskRunner(),
|
||||
gpu_thread_->GetTaskRunner(),
|
||||
ui_thread_->GetTaskRunner(),
|
||||
io_thread_->GetTaskRunner());
|
||||
blink::Threads::Set(threads);
|
||||
|
||||
blink::Threads::Gpu()->PostTask([this]() { InitGpuThread(); });
|
||||
@@ -121,34 +93,22 @@ Shell::Shell() {
|
||||
|
||||
Shell::~Shell() {}
|
||||
|
||||
void Shell::InitStandalone(std::string icu_data_path,
|
||||
void Shell::InitStandalone(ftl::CommandLine command_line,
|
||||
std::string icu_data_path,
|
||||
std::string application_library_path) {
|
||||
TRACE_EVENT0("flutter", "Shell::InitStandalone");
|
||||
|
||||
ftl::UniqueFD icu_fd(
|
||||
icu_data_path.empty() ? -1 : HANDLE_EINTR(::open(icu_data_path.c_str(),
|
||||
O_RDONLY)));
|
||||
if (icu_fd.get() == -1) {
|
||||
// If the embedder did not specify a valid file, fallback to looking through
|
||||
// internal search paths.
|
||||
FTL_CHECK(base::i18n::InitializeICU());
|
||||
} else {
|
||||
FTL_CHECK(base::i18n::InitializeICUWithFileDescriptor(
|
||||
icu_fd.get(), base::MemoryMappedFile::Region::kWholeFile));
|
||||
icu_fd.reset();
|
||||
}
|
||||
|
||||
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
|
||||
fml::icu::InitializeICU(icu_data_path);
|
||||
|
||||
blink::Settings settings;
|
||||
settings.application_library_path = application_library_path;
|
||||
|
||||
// Enable Observatory
|
||||
settings.enable_observatory =
|
||||
!command_line.HasSwitch(FlagForSwitch(Switch::DisableObservatory));
|
||||
!command_line.HasOption(FlagForSwitch(Switch::DisableObservatory));
|
||||
|
||||
// Set Observatory Port
|
||||
if (command_line.HasSwitch(FlagForSwitch(Switch::DeviceObservatoryPort))) {
|
||||
if (command_line.HasOption(FlagForSwitch(Switch::DeviceObservatoryPort))) {
|
||||
if (!GetSwitchValue(command_line, Switch::DeviceObservatoryPort,
|
||||
&settings.observatory_port)) {
|
||||
FTL_LOG(INFO)
|
||||
@@ -159,12 +119,12 @@ void Shell::InitStandalone(std::string icu_data_path,
|
||||
|
||||
// Checked mode overrides.
|
||||
settings.dart_non_checked_mode =
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::DartNonCheckedMode));
|
||||
command_line.HasOption(FlagForSwitch(Switch::DartNonCheckedMode));
|
||||
|
||||
settings.enable_diagnostic =
|
||||
!command_line.HasSwitch(FlagForSwitch(Switch::DisableDiagnostic));
|
||||
!command_line.HasOption(FlagForSwitch(Switch::DisableDiagnostic));
|
||||
|
||||
if (command_line.HasSwitch(FlagForSwitch(Switch::DeviceDiagnosticPort))) {
|
||||
if (command_line.HasOption(FlagForSwitch(Switch::DeviceDiagnosticPort))) {
|
||||
if (!GetSwitchValue(command_line, Switch::DeviceDiagnosticPort,
|
||||
&settings.diagnostic_port)) {
|
||||
FTL_LOG(INFO)
|
||||
@@ -174,63 +134,62 @@ void Shell::InitStandalone(std::string icu_data_path,
|
||||
}
|
||||
|
||||
settings.start_paused =
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::StartPaused));
|
||||
command_line.HasOption(FlagForSwitch(Switch::StartPaused));
|
||||
|
||||
settings.enable_dart_profiling =
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::EnableDartProfiling));
|
||||
command_line.HasOption(FlagForSwitch(Switch::EnableDartProfiling));
|
||||
|
||||
settings.endless_trace_buffer =
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::EndlessTraceBuffer));
|
||||
command_line.HasOption(FlagForSwitch(Switch::EndlessTraceBuffer));
|
||||
|
||||
settings.trace_startup =
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::TraceStartup));
|
||||
command_line.HasOption(FlagForSwitch(Switch::TraceStartup));
|
||||
|
||||
settings.aot_snapshot_path =
|
||||
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::AotSnapshotPath));
|
||||
settings.aot_vm_snapshot_data_filename = command_line.GetSwitchValueASCII(
|
||||
FlagForSwitch(Switch::AotVmSnapshotData));
|
||||
settings.aot_vm_snapshot_instr_filename = command_line.GetSwitchValueASCII(
|
||||
FlagForSwitch(Switch::AotVmSnapshotInstructions));
|
||||
settings.aot_isolate_snapshot_data_filename =
|
||||
command_line.GetSwitchValueASCII(
|
||||
FlagForSwitch(Switch::AotIsolateSnapshotData));
|
||||
settings.aot_isolate_snapshot_instr_filename =
|
||||
command_line.GetSwitchValueASCII(
|
||||
FlagForSwitch(Switch::AotIsolateSnapshotInstructions));
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::AotSnapshotPath),
|
||||
&settings.aot_snapshot_path);
|
||||
|
||||
settings.temp_directory_path =
|
||||
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::CacheDirPath));
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::AotVmSnapshotData),
|
||||
&settings.aot_vm_snapshot_data_filename);
|
||||
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::AotVmSnapshotInstructions),
|
||||
&settings.aot_vm_snapshot_instr_filename);
|
||||
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::AotIsolateSnapshotData),
|
||||
&settings.aot_isolate_snapshot_data_filename);
|
||||
|
||||
command_line.GetOptionValue(
|
||||
FlagForSwitch(Switch::AotIsolateSnapshotInstructions),
|
||||
&settings.aot_isolate_snapshot_instr_filename);
|
||||
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::CacheDirPath),
|
||||
&settings.temp_directory_path);
|
||||
|
||||
settings.use_test_fonts =
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::UseTestFonts));
|
||||
command_line.HasOption(FlagForSwitch(Switch::UseTestFonts));
|
||||
|
||||
if (command_line.HasSwitch(FlagForSwitch(Switch::DartFlags))) {
|
||||
std::stringstream stream(
|
||||
command_line.GetSwitchValueNative(FlagForSwitch(Switch::DartFlags)));
|
||||
std::string all_dart_flags;
|
||||
if (command_line.GetOptionValue(FlagForSwitch(Switch::DartFlags),
|
||||
&all_dart_flags)) {
|
||||
std::stringstream stream(all_dart_flags);
|
||||
std::istream_iterator<std::string> end;
|
||||
for (std::istream_iterator<std::string> it(stream); it != end; ++it)
|
||||
settings.dart_flags.push_back(*it);
|
||||
}
|
||||
|
||||
if (command_line.HasSwitch(FlagForSwitch(Switch::LogTag))) {
|
||||
settings.log_tag =
|
||||
command_line.GetSwitchValueASCII(FlagForSwitch(Switch::LogTag));
|
||||
}
|
||||
command_line.GetOptionValue(FlagForSwitch(Switch::LogTag), &settings.log_tag);
|
||||
|
||||
blink::Settings::Set(settings);
|
||||
|
||||
Init();
|
||||
Init(std::move(command_line));
|
||||
}
|
||||
|
||||
void Shell::Init() {
|
||||
base::DiscardableMemoryAllocator::SetInstance(&g_discardable.Get());
|
||||
|
||||
void Shell::Init(ftl::CommandLine command_line) {
|
||||
#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE
|
||||
InitSkiaEventTracer();
|
||||
#endif
|
||||
|
||||
FTL_DCHECK(!g_shell);
|
||||
g_shell = new Shell();
|
||||
g_shell = new Shell(std::move(command_line));
|
||||
blink::Threads::UI()->PostTask(Engine::Init);
|
||||
}
|
||||
|
||||
@@ -239,44 +198,51 @@ Shell& Shell::Shared() {
|
||||
return *g_shell;
|
||||
}
|
||||
|
||||
const ftl::CommandLine& Shell::GetCommandLine() const {
|
||||
return command_line_;
|
||||
}
|
||||
|
||||
TracingController& Shell::tracing_controller() {
|
||||
return tracing_controller_;
|
||||
}
|
||||
|
||||
void Shell::InitGpuThread() {
|
||||
gpu_thread_checker_.reset(new base::ThreadChecker());
|
||||
gpu_thread_checker_.reset(new fml::ThreadChecker());
|
||||
}
|
||||
|
||||
void Shell::InitUIThread() {
|
||||
ui_thread_checker_.reset(new base::ThreadChecker());
|
||||
ui_thread_checker_.reset(new fml::ThreadChecker());
|
||||
}
|
||||
|
||||
void Shell::AddRasterizer(const ftl::WeakPtr<Rasterizer>& rasterizer) {
|
||||
FTL_DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(gpu_thread_checker_ &&
|
||||
gpu_thread_checker_->IsCalledOnValidThread());
|
||||
rasterizers_.push_back(rasterizer);
|
||||
}
|
||||
|
||||
void Shell::PurgeRasterizers() {
|
||||
FTL_DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(gpu_thread_checker_ &&
|
||||
gpu_thread_checker_->IsCalledOnValidThread());
|
||||
rasterizers_.erase(
|
||||
std::remove_if(rasterizers_.begin(), rasterizers_.end(), IsInvalid),
|
||||
rasterizers_.end());
|
||||
}
|
||||
|
||||
void Shell::GetRasterizers(std::vector<ftl::WeakPtr<Rasterizer>>* rasterizers) {
|
||||
FTL_DCHECK(gpu_thread_checker_ && gpu_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(gpu_thread_checker_ &&
|
||||
gpu_thread_checker_->IsCalledOnValidThread());
|
||||
*rasterizers = rasterizers_;
|
||||
}
|
||||
|
||||
void Shell::AddPlatformView(const ftl::WeakPtr<PlatformView>& platform_view) {
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
|
||||
if (platform_view) {
|
||||
platform_views_.push_back(platform_view);
|
||||
}
|
||||
}
|
||||
|
||||
void Shell::PurgePlatformViews() {
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
|
||||
platform_views_.erase(std::remove_if(platform_views_.begin(),
|
||||
platform_views_.end(), IsViewInvalid),
|
||||
platform_views_.end());
|
||||
@@ -284,7 +250,7 @@ void Shell::PurgePlatformViews() {
|
||||
|
||||
void Shell::GetPlatformViews(
|
||||
std::vector<ftl::WeakPtr<PlatformView>>* platform_views) {
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
|
||||
*platform_views = platform_views_;
|
||||
}
|
||||
|
||||
@@ -351,7 +317,7 @@ void Shell::RunInPlatformViewUIThread(uintptr_t view_id,
|
||||
int64_t* dart_isolate_id,
|
||||
std::string* isolate_name,
|
||||
ftl::AutoResetWaitableEvent* latch) {
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->CalledOnValidThread());
|
||||
FTL_DCHECK(ui_thread_checker_ && ui_thread_checker_->IsCalledOnValidThread());
|
||||
|
||||
*view_existed = false;
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
#ifndef SHELL_COMMON_SHELL_H_
|
||||
#define SHELL_COMMON_SHELL_H_
|
||||
|
||||
#include "base/threading/thread.h"
|
||||
#include "flutter/fml/thread.h"
|
||||
#include "flutter/fml/thread_checker.h"
|
||||
#include "flutter/shell/common/tracing_controller.h"
|
||||
#include "lib/ftl/command_line.h"
|
||||
#include "lib/ftl/macros.h"
|
||||
#include "lib/ftl/memory/ref_ptr.h"
|
||||
#include "lib/ftl/memory/weak_ptr.h"
|
||||
@@ -22,12 +24,14 @@ class Shell {
|
||||
public:
|
||||
~Shell();
|
||||
|
||||
static void InitStandalone(std::string icu_data_path = "",
|
||||
static void InitStandalone(ftl::CommandLine command_line,
|
||||
std::string icu_data_path = "",
|
||||
std::string application_library_path = "");
|
||||
static void Init();
|
||||
|
||||
static Shell& Shared();
|
||||
|
||||
const ftl::CommandLine& GetCommandLine() const;
|
||||
|
||||
TracingController& tracing_controller();
|
||||
|
||||
// Maintain a list of rasterizers.
|
||||
@@ -65,7 +69,9 @@ class Shell {
|
||||
std::string* isolate_name);
|
||||
|
||||
private:
|
||||
Shell();
|
||||
static void Init(ftl::CommandLine command_line);
|
||||
|
||||
Shell(ftl::CommandLine command_line);
|
||||
|
||||
void InitGpuThread();
|
||||
void InitUIThread();
|
||||
@@ -83,12 +89,14 @@ class Shell {
|
||||
std::string* isolate_name,
|
||||
ftl::AutoResetWaitableEvent* latch);
|
||||
|
||||
std::unique_ptr<base::Thread> gpu_thread_;
|
||||
std::unique_ptr<base::Thread> ui_thread_;
|
||||
std::unique_ptr<base::Thread> io_thread_;
|
||||
ftl::CommandLine command_line_;
|
||||
|
||||
std::unique_ptr<base::ThreadChecker> gpu_thread_checker_;
|
||||
std::unique_ptr<base::ThreadChecker> ui_thread_checker_;
|
||||
std::unique_ptr<fml::Thread> gpu_thread_;
|
||||
std::unique_ptr<fml::Thread> ui_thread_;
|
||||
std::unique_ptr<fml::Thread> io_thread_;
|
||||
|
||||
std::unique_ptr<fml::ThreadChecker> gpu_thread_checker_;
|
||||
std::unique_ptr<fml::ThreadChecker> ui_thread_checker_;
|
||||
|
||||
TracingController tracing_controller_;
|
||||
|
||||
|
||||
@@ -4,71 +4,81 @@
|
||||
|
||||
#include "flutter/shell/common/skia_event_tracer_impl.h"
|
||||
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#define TRACE_EVENT_HIDE_MACROS
|
||||
#include "flutter/fml/trace_event.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "lib/ftl/logging.h"
|
||||
#include "third_party/skia/include/utils/SkEventTracer.h"
|
||||
#include "third_party/skia/src/core/SkTraceEventCommon.h"
|
||||
|
||||
namespace skia {
|
||||
|
||||
class SkChromiumEventTracer: public SkEventTracer {
|
||||
const uint8_t* getCategoryGroupEnabled(const char* name) override;
|
||||
const char* getCategoryGroupName(const uint8_t* categoryEnabledFlag) override;
|
||||
class FlutterEventTracer : public SkEventTracer {
|
||||
public:
|
||||
static constexpr const char* kSkiaTag = "skia";
|
||||
|
||||
FlutterEventTracer() = default;
|
||||
|
||||
SkEventTracer::Handle addTraceEvent(char phase,
|
||||
const uint8_t* categoryEnabledFlag,
|
||||
const uint8_t* category_enabled_flag,
|
||||
const char* name,
|
||||
uint64_t id,
|
||||
int32_t numArgs,
|
||||
const char** argNames,
|
||||
const uint8_t* argTypes,
|
||||
const uint64_t* argValues,
|
||||
uint8_t flags) override;
|
||||
void updateTraceEventDuration(const uint8_t* categoryEnabledFlag,
|
||||
int num_args,
|
||||
const char** p_arg_names,
|
||||
const uint8_t* p_arg_types,
|
||||
const uint64_t* p_arg_values,
|
||||
uint8_t flags) override {
|
||||
switch (phase) {
|
||||
case TRACE_EVENT_PHASE_BEGIN:
|
||||
case TRACE_EVENT_PHASE_COMPLETE:
|
||||
fml::tracing::TraceEvent0(kSkiaTag, name);
|
||||
break;
|
||||
case TRACE_EVENT_PHASE_END:
|
||||
fml::tracing::TraceEventEnd(name);
|
||||
break;
|
||||
case TRACE_EVENT_PHASE_INSTANT:
|
||||
fml::tracing::TraceEventInstant0(kSkiaTag, name);
|
||||
break;
|
||||
case TRACE_EVENT_PHASE_ASYNC_BEGIN:
|
||||
fml::tracing::TraceEventAsyncBegin0(kSkiaTag, name, id);
|
||||
break;
|
||||
case TRACE_EVENT_PHASE_ASYNC_END:
|
||||
fml::tracing::TraceEventAsyncEnd0(kSkiaTag, name, id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void updateTraceEventDuration(const uint8_t* category_enabled_flag,
|
||||
const char* name,
|
||||
SkEventTracer::Handle handle) override;
|
||||
SkEventTracer::Handle handle) override {
|
||||
// This is only ever called from a scoped trace event so we will just end
|
||||
// the section.
|
||||
fml::tracing::TraceEventEnd(name);
|
||||
}
|
||||
|
||||
const uint8_t* getCategoryGroupEnabled(const char* name) override {
|
||||
static const uint8_t kYes = 1;
|
||||
return &kYes;
|
||||
}
|
||||
|
||||
const char* getCategoryGroupName(
|
||||
const uint8_t* category_enabled_flag) override {
|
||||
return kSkiaTag;
|
||||
}
|
||||
|
||||
private:
|
||||
FTL_DISALLOW_COPY_AND_ASSIGN(FlutterEventTracer);
|
||||
};
|
||||
|
||||
const uint8_t*
|
||||
SkChromiumEventTracer::getCategoryGroupEnabled(const char* name) {
|
||||
return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(name);
|
||||
}
|
||||
|
||||
const char* SkChromiumEventTracer::getCategoryGroupName(
|
||||
const uint8_t* categoryEnabledFlag) {
|
||||
return base::trace_event::TraceLog::GetCategoryGroupName(categoryEnabledFlag);
|
||||
}
|
||||
|
||||
SkEventTracer::Handle
|
||||
SkChromiumEventTracer::addTraceEvent(char phase,
|
||||
const uint8_t* categoryEnabledFlag,
|
||||
const char* name,
|
||||
uint64_t id,
|
||||
int32_t numArgs,
|
||||
const char** argNames,
|
||||
const uint8_t* argTypes,
|
||||
const uint64_t* argValues,
|
||||
uint8_t flags) {
|
||||
base::trace_event::TraceEventHandle handle = TRACE_EVENT_API_ADD_TRACE_EVENT(
|
||||
phase, categoryEnabledFlag, name, id, numArgs, argNames, argTypes,
|
||||
(const long long unsigned int*)argValues, NULL, flags);
|
||||
SkEventTracer::Handle result;
|
||||
memcpy(&result, &handle, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
SkChromiumEventTracer::updateTraceEventDuration(
|
||||
const uint8_t* categoryEnabledFlag,
|
||||
const char *name,
|
||||
SkEventTracer::Handle handle) {
|
||||
base::trace_event::TraceEventHandle traceEventHandle;
|
||||
memcpy(&traceEventHandle, &handle, sizeof(handle));
|
||||
TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
|
||||
categoryEnabledFlag, name, traceEventHandle);
|
||||
}
|
||||
|
||||
} // namespace skia
|
||||
|
||||
void InitSkiaEventTracer() {
|
||||
// Initialize the binding to Skia's tracing events. Skia will
|
||||
// take ownership of and clean up the memory allocated here.
|
||||
SkEventTracer::SetInstance(new skia::SkChromiumEventTracer());
|
||||
SkEventTracer::SetInstance(new skia::FlutterEventTracer());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
|
||||
args.push_back(std::move(arg));
|
||||
}
|
||||
|
||||
base::CommandLine::Init(0, nullptr);
|
||||
base::CommandLine::ForCurrentProcess()->InitFromArgv(args);
|
||||
|
||||
InitializeLogging();
|
||||
|
||||
g_java_message_loop.Get().reset(new base::MessageLoopForUI);
|
||||
base::MessageLoopForUI::current()->Start();
|
||||
|
||||
Shell::InitStandalone();
|
||||
|
||||
InitializeTracing();
|
||||
auto command_line = ftl::CommandLineFromIterators(args.begin(), args.end());
|
||||
std::string icu_data_path =
|
||||
command_line.GetOptionValueWithDefault("icu-data-file-path", "");
|
||||
Shell::InitStandalone(std::move(command_line), std::move(icu_data_path));
|
||||
}
|
||||
|
||||
static void RecordStartTimestamp(JNIEnv* env,
|
||||
@@ -90,7 +46,26 @@ static void RecordStartTimestamp(JNIEnv* env,
|
||||
}
|
||||
|
||||
bool RegisterFlutterMain(JNIEnv* env) {
|
||||
return RegisterNativesImpl(env);
|
||||
static const JNINativeMethod methods[] = {
|
||||
{
|
||||
.name = "nativeInit",
|
||||
.signature = "(Landroid/content/Context;[Ljava/lang/String;)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&Init),
|
||||
},
|
||||
{
|
||||
.name = "nativeRecordStartTimestamp",
|
||||
.signature = "(J)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&RecordStartTimestamp),
|
||||
},
|
||||
};
|
||||
|
||||
jclass clazz = env->FindClass("io/flutter/view/FlutterMain");
|
||||
|
||||
if (clazz == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return env->RegisterNatives(clazz, methods, arraysize(methods)) == 0;
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package io.flutter.util;
|
||||
|
||||
import android.content.Context;
|
||||
import java.io.IOException;
|
||||
import java.lang.String;
|
||||
|
||||
public final class PathUtils {
|
||||
public static String getDataDirectory(Context applicationContext) {
|
||||
return applicationContext.getDir("sky_shell", Context.MODE_PRIVATE).getPath();
|
||||
}
|
||||
|
||||
public static String getCacheDirectory(Context applicationContext) {
|
||||
return applicationContext.getCacheDir().getPath();
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
bool InitJNI() {
|
||||
return blink::DartJni::InitJni();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// This is called by the VM when the shared library is first loaded.
|
||||
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
std::vector<base::android::RegisterCallback> register_callbacks;
|
||||
register_callbacks.push_back(base::Bind(&RegisterJNI));
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
// Initialize the Java VM.
|
||||
fml::jni::InitJavaVM(vm);
|
||||
|
||||
std::vector<base::android::InitCallback> init_callbacks;
|
||||
init_callbacks.push_back(base::Bind(&InitJNI));
|
||||
JNIEnv* env = fml::jni::AttachCurrentThread();
|
||||
bool result = false;
|
||||
|
||||
if (!base::android::OnJNIOnLoadRegisterJNI(vm, register_callbacks) ||
|
||||
!base::android::OnJNIOnLoadInit(init_callbacks)) {
|
||||
return -1;
|
||||
}
|
||||
// Register FlutterMain.
|
||||
result = shell::RegisterFlutterMain(env);
|
||||
FTL_CHECK(result);
|
||||
|
||||
// Register PlatformView
|
||||
result = shell::PlatformViewAndroid::Register(env);
|
||||
FTL_CHECK(result);
|
||||
|
||||
// Register VSyncWaiter.
|
||||
result = shell::VsyncWaiterAndroid::Register(env);
|
||||
FTL_CHECK(result);
|
||||
|
||||
// Register DartJni
|
||||
result = blink::DartJni::InitJni();
|
||||
FTL_CHECK(result);
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/android/platform_view_android_jni.h"
|
||||
#include "flutter/fml/platform/android/jni_util.h"
|
||||
#include "flutter/fml/platform/android/jni_weak_ref.h"
|
||||
#include "flutter/fml/platform/android/scoped_java_ref.h"
|
||||
#include "flutter/runtime/dart_service_isolate.h"
|
||||
#include "lib/ftl/arraysize.h"
|
||||
#include "lib/ftl/logging.h"
|
||||
|
||||
#define PLATFORM_VIEW reinterpret_cast<PlatformViewAndroid*>(platform_view)
|
||||
|
||||
namespace shell {
|
||||
|
||||
static fml::jni::ScopedJavaGlobalRef<jclass>* g_flutter_view_class = nullptr;
|
||||
|
||||
// Called By Native
|
||||
|
||||
static jmethodID g_handle_platform_message_method = nullptr;
|
||||
void FlutterViewHandlePlatformMessage(JNIEnv* env,
|
||||
jobject obj,
|
||||
jstring channel,
|
||||
jobject message,
|
||||
jint responseId) {
|
||||
env->CallVoidMethod(obj, g_handle_platform_message_method, channel, message,
|
||||
responseId);
|
||||
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
|
||||
}
|
||||
|
||||
static jmethodID g_handle_platform_message_response_method = nullptr;
|
||||
void FlutterViewHandlePlatformMessageResponse(JNIEnv* env,
|
||||
jobject obj,
|
||||
jint responseId,
|
||||
jobject response) {
|
||||
env->CallVoidMethod(obj, g_handle_platform_message_response_method,
|
||||
responseId, response);
|
||||
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
|
||||
}
|
||||
|
||||
static jmethodID g_update_semantics_method = nullptr;
|
||||
void FlutterViewUpdateSemantics(JNIEnv* env,
|
||||
jobject obj,
|
||||
jobject buffer,
|
||||
jobjectArray strings) {
|
||||
env->CallVoidMethod(obj, g_update_semantics_method, buffer, strings);
|
||||
FTL_CHECK(env->ExceptionCheck() == JNI_FALSE);
|
||||
}
|
||||
|
||||
// Called By Java
|
||||
|
||||
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) {
|
||||
PlatformViewAndroid* view = new PlatformViewAndroid();
|
||||
// Create a weak reference to the flutterView Java object so that we can make
|
||||
// calls into it later.
|
||||
view->set_flutter_view(fml::jni::JavaObjectWeakGlobalRef(env, flutterView));
|
||||
return reinterpret_cast<jlong>(view);
|
||||
}
|
||||
|
||||
static void Detach(JNIEnv* env, jobject jcaller, jlong platform_view) {
|
||||
return PLATFORM_VIEW->Detach();
|
||||
}
|
||||
|
||||
static jstring GetObservatoryUri(JNIEnv* env, jclass clazz) {
|
||||
return env->NewStringUTF(
|
||||
blink::DartServiceIsolate::GetObservatoryUri().c_str());
|
||||
}
|
||||
|
||||
static void SurfaceCreated(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jobject surface,
|
||||
jint backgroundColor) {
|
||||
return PLATFORM_VIEW->SurfaceCreated(env, surface, backgroundColor);
|
||||
}
|
||||
|
||||
static void SurfaceChanged(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jint width,
|
||||
jint height) {
|
||||
return PLATFORM_VIEW->SurfaceChanged(width, height);
|
||||
}
|
||||
|
||||
static void SurfaceDestroyed(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view) {
|
||||
return PLATFORM_VIEW->SurfaceDestroyed();
|
||||
}
|
||||
|
||||
static void RunBundleAndSnapshot(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jstring bundlePath,
|
||||
jstring snapshotOverride) {
|
||||
return PLATFORM_VIEW->RunBundleAndSnapshot(
|
||||
fml::jni::JavaStringToString(env, bundlePath), //
|
||||
fml::jni::JavaStringToString(env, snapshotOverride) //
|
||||
);
|
||||
}
|
||||
|
||||
void RunBundleAndSource(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jstring bundlePath,
|
||||
jstring main,
|
||||
jstring packages) {
|
||||
return PLATFORM_VIEW->RunBundleAndSource(
|
||||
fml::jni::JavaStringToString(env, bundlePath),
|
||||
fml::jni::JavaStringToString(env, main),
|
||||
fml::jni::JavaStringToString(env, packages));
|
||||
}
|
||||
|
||||
static void SetViewportMetrics(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jfloat devicePixelRatio,
|
||||
jint physicalWidth,
|
||||
jint physicalHeight,
|
||||
jint physicalPaddingTop,
|
||||
jint physicalPaddingRight,
|
||||
jint physicalPaddingBottom,
|
||||
jint physicalPaddingLeft) {
|
||||
return PLATFORM_VIEW->SetViewportMetrics(devicePixelRatio, //
|
||||
physicalWidth, //
|
||||
physicalHeight, //
|
||||
physicalPaddingTop, //
|
||||
physicalPaddingRight, //
|
||||
physicalPaddingBottom, //
|
||||
physicalPaddingLeft);
|
||||
}
|
||||
|
||||
static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong platform_view) {
|
||||
return PLATFORM_VIEW->GetBitmap(env).Release();
|
||||
}
|
||||
|
||||
static void DispatchPlatformMessage(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jstring channel,
|
||||
jobject message,
|
||||
jint position,
|
||||
jint responseId) {
|
||||
return PLATFORM_VIEW->DispatchPlatformMessage(
|
||||
env, fml::jni::JavaStringToString(env, channel), message, position,
|
||||
responseId);
|
||||
}
|
||||
|
||||
static void DispatchPointerDataPacket(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jobject buffer,
|
||||
jint position) {
|
||||
return PLATFORM_VIEW->DispatchPointerDataPacket(env, buffer, position);
|
||||
}
|
||||
|
||||
static void DispatchSemanticsAction(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jint id,
|
||||
jint action) {
|
||||
return PLATFORM_VIEW->DispatchSemanticsAction(id, action);
|
||||
}
|
||||
|
||||
static void SetSemanticsEnabled(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jboolean enabled) {
|
||||
return PLATFORM_VIEW->SetSemanticsEnabled(enabled);
|
||||
}
|
||||
|
||||
static void InvokePlatformMessageResponseCallback(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong platform_view,
|
||||
jint responseId,
|
||||
jobject message,
|
||||
jint position) {
|
||||
return PLATFORM_VIEW->InvokePlatformMessageResponseCallback(
|
||||
env, responseId, message, position);
|
||||
}
|
||||
|
||||
bool PlatformViewAndroid::Register(JNIEnv* env) {
|
||||
if (env == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_flutter_view_class = new fml::jni::ScopedJavaGlobalRef<jclass>(
|
||||
env, env->FindClass("io/flutter/view/FlutterView"));
|
||||
|
||||
if (g_flutter_view_class->is_null()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static const JNINativeMethod methods[] = {
|
||||
{
|
||||
.name = "nativeAttach",
|
||||
.signature = "(Lio/flutter/view/FlutterView;)J",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::Attach),
|
||||
},
|
||||
{
|
||||
.name = "nativeDetach",
|
||||
.signature = "(J)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::Detach),
|
||||
},
|
||||
{
|
||||
.name = "nativeGetObservatoryUri",
|
||||
.signature = "()Ljava/lang/String;",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::GetObservatoryUri),
|
||||
},
|
||||
{
|
||||
.name = "nativeSurfaceCreated",
|
||||
.signature = "(JLandroid/view/Surface;I)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceCreated),
|
||||
},
|
||||
{
|
||||
.name = "nativeSurfaceChanged",
|
||||
.signature = "(JII)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceChanged),
|
||||
},
|
||||
{
|
||||
.name = "nativeSurfaceDestroyed",
|
||||
.signature = "(J)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceDestroyed),
|
||||
},
|
||||
{
|
||||
.name = "nativeRunBundleAndSnapshot",
|
||||
.signature = "(JLjava/lang/String;Ljava/lang/String;)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::RunBundleAndSnapshot),
|
||||
},
|
||||
{
|
||||
.name = "nativeRunBundleAndSource",
|
||||
.signature =
|
||||
"(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::RunBundleAndSource),
|
||||
},
|
||||
{
|
||||
.name = "nativeSetViewportMetrics",
|
||||
.signature = "(JFIIIIII)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SetViewportMetrics),
|
||||
},
|
||||
{
|
||||
.name = "nativeGetBitmap",
|
||||
.signature = "(J)Landroid/graphics/Bitmap;",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::GetBitmap),
|
||||
},
|
||||
{
|
||||
.name = "nativeDispatchPlatformMessage",
|
||||
.signature = "(JLjava/lang/String;Ljava/nio/ByteBuffer;II)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::DispatchPlatformMessage),
|
||||
},
|
||||
{
|
||||
.name = "nativeDispatchPointerDataPacket",
|
||||
.signature = "(JLjava/nio/ByteBuffer;I)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::DispatchPointerDataPacket),
|
||||
},
|
||||
{
|
||||
.name = "nativeDispatchSemanticsAction",
|
||||
.signature = "(JII)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::DispatchSemanticsAction),
|
||||
},
|
||||
{
|
||||
.name = "nativeSetSemanticsEnabled",
|
||||
.signature = "(JZ)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SetSemanticsEnabled),
|
||||
},
|
||||
{
|
||||
.name = "nativeInvokePlatformMessageResponseCallback",
|
||||
.signature = "(JILjava/nio/ByteBuffer;I)V",
|
||||
.fnPtr = reinterpret_cast<void*>(
|
||||
&shell::InvokePlatformMessageResponseCallback),
|
||||
},
|
||||
};
|
||||
|
||||
if (env->RegisterNatives(g_flutter_view_class->obj(), methods,
|
||||
arraysize(methods)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_handle_platform_message_method =
|
||||
env->GetMethodID(g_flutter_view_class->obj(), "handlePlatformMessage",
|
||||
"(Ljava/lang/String;Ljava/nio/ByteBuffer;I)V");
|
||||
|
||||
if (g_handle_platform_message_method == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_handle_platform_message_response_method = env->GetMethodID(
|
||||
g_flutter_view_class->obj(), "handlePlatformMessageResponse",
|
||||
"(ILjava/nio/ByteBuffer;)V");
|
||||
|
||||
if (g_handle_platform_message_response_method == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_update_semantics_method =
|
||||
env->GetMethodID(g_flutter_view_class->obj(), "updateSemantics",
|
||||
"(Ljava/nio/ByteBuffer;[Ljava/lang/String;)V");
|
||||
|
||||
if (g_update_semantics_method == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace shell
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2017 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
|
||||
|
||||
#include <jni.h>
|
||||
#include "flutter/shell/platform/android/platform_view_android.h"
|
||||
#include "lib/ftl/macros.h"
|
||||
|
||||
namespace shell {
|
||||
|
||||
void FlutterViewHandlePlatformMessage(JNIEnv* env,
|
||||
jobject obj,
|
||||
jstring channel,
|
||||
jobject message,
|
||||
jint responseId);
|
||||
|
||||
void FlutterViewHandlePlatformMessageResponse(JNIEnv* env,
|
||||
jobject obj,
|
||||
jint responseId,
|
||||
jobject response);
|
||||
|
||||
void FlutterViewUpdateSemantics(JNIEnv* env,
|
||||
jobject obj,
|
||||
jobject buffer,
|
||||
jobjectArray strings);
|
||||
|
||||
} // namespace shell
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_JNI_H_
|
||||
@@ -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();
|
||||
auto command_line = InitializedCommandLine();
|
||||
|
||||
RedirectIOConnectionsToSyslog();
|
||||
|
||||
InitializeLogging();
|
||||
|
||||
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
|
||||
if (command_line.HasSwitch(FlagForSwitch(Switch::TraceStartup))) {
|
||||
// Usually, all tracing within flutter is managed via the tracing
|
||||
// controller
|
||||
// The tracing controller is accessed via the shell instance. This means
|
||||
// that tracing can only be enabled once that instance is created. Traces
|
||||
// early in startup are lost. This enables tracing only in base manually
|
||||
// till the tracing controller takes over.
|
||||
shell::TracingController::StartBaseTracing();
|
||||
}
|
||||
RedirectIOConnectionsToSyslog(command_line);
|
||||
|
||||
// This is about as early as tracing of any kind can start. Add an instant
|
||||
// marker that can be used as a reference for startup.
|
||||
TRACE_EVENT_INSTANT0("flutter", "main", TRACE_EVENT_SCOPE_PROCESS);
|
||||
TRACE_EVENT_INSTANT0("flutter", "main");
|
||||
|
||||
embedder_message_loop_ = WTF::MakeUnique<base::MessageLoopForUI>();
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// One cannot start the message loop on the platform main thread. Instead,
|
||||
// we attach to the CFRunLoop
|
||||
embedder_message_loop_->Attach();
|
||||
#endif
|
||||
|
||||
shell::Shell::InitStandalone(icu_data_path, application_library_path);
|
||||
shell::Shell::InitStandalone(std::move(command_line), icu_data_path,
|
||||
application_library_path);
|
||||
}
|
||||
|
||||
~EmbedderState() {
|
||||
#if !TARGET_OS_IPHONE
|
||||
embedder_message_loop_.release();
|
||||
#endif
|
||||
}
|
||||
~EmbedderState() {}
|
||||
|
||||
private:
|
||||
base::AtExitManager exit_manager_;
|
||||
std::unique_ptr<base::MessageLoopForUI> embedder_message_loop_;
|
||||
|
||||
FTL_DISALLOW_COPY_AND_ASSIGN(EmbedderState);
|
||||
};
|
||||
|
||||
@@ -160,10 +114,11 @@ static bool FlagsValidForCommandLineLaunch(const std::string& bundle_path,
|
||||
}
|
||||
|
||||
static std::string ResolveCommandLineLaunchFlag(const char* name) {
|
||||
auto command_line = *base::CommandLine::ForCurrentProcess();
|
||||
const auto& command_line = shell::Shell::Shared().GetCommandLine();
|
||||
|
||||
if (command_line.HasSwitch(name)) {
|
||||
return command_line.GetSwitchValueASCII(name);
|
||||
std::string command_line_option;
|
||||
if (command_line.GetOptionValue(name, &command_line_option)) {
|
||||
return command_line_option;
|
||||
}
|
||||
|
||||
const char* saved_default =
|
||||
@@ -177,15 +132,13 @@ static std::string ResolveCommandLineLaunchFlag(const char* name) {
|
||||
}
|
||||
|
||||
bool AttemptLaunchFromCommandLineSwitches(Engine* engine) {
|
||||
base::mac::ScopedNSAutoreleasePool pool;
|
||||
|
||||
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
auto command_line = *base::CommandLine::ForCurrentProcess();
|
||||
const auto& command_line = shell::Shell::Shared().GetCommandLine();
|
||||
|
||||
if (command_line.HasSwitch(FlagForSwitch(Switch::FLX)) ||
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::MainDartFile)) ||
|
||||
command_line.HasSwitch(FlagForSwitch(Switch::Packages))) {
|
||||
if (command_line.HasOption(FlagForSwitch(Switch::FLX)) ||
|
||||
command_line.HasOption(FlagForSwitch(Switch::MainDartFile)) ||
|
||||
command_line.HasOption(FlagForSwitch(Switch::Packages))) {
|
||||
// The main dart file, flx bundle and the package root must be specified in
|
||||
// one go. We dont want to end up in a situation where we take one value
|
||||
// from the command line and the others from user defaults. In case, any
|
||||
|
||||
@@ -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));
|
||||
|
||||
std::string target = command_line.GetSwitchValueASCII(
|
||||
shell::FlagForSwitch(shell::Switch::FLX));
|
||||
const auto& command_line = shell::Shell::Shared().GetCommandLine();
|
||||
|
||||
std::string target = command_line.GetOptionValueWithDefault(
|
||||
shell::FlagForSwitch(shell::Switch::FLX), "");
|
||||
|
||||
if (target.empty()) {
|
||||
// Alternatively, use the first positional argument.
|
||||
auto args = command_line.GetArgs();
|
||||
auto args = command_line.positional_args();
|
||||
if (args.empty())
|
||||
return 1;
|
||||
target = args[0];
|
||||
@@ -172,22 +171,21 @@ int main(int argc, char* argv[]) {
|
||||
dart::bin::SetExecutableArguments(argc - 1, argv);
|
||||
|
||||
base::AtExitManager exit_manager;
|
||||
base::CommandLine::Init(argc, argv);
|
||||
|
||||
base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
|
||||
auto command_line = ftl::CommandLineFromArgcArgv(argc, argv);
|
||||
|
||||
if (command_line.HasSwitch(shell::FlagForSwitch(shell::Switch::Help))) {
|
||||
if (command_line.HasOption(shell::FlagForSwitch(shell::Switch::Help))) {
|
||||
shell::PrintUsage("sky_shell");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command_line.HasSwitch(
|
||||
if (command_line.HasOption(
|
||||
shell::FlagForSwitch(shell::Switch::NonInteractive))) {
|
||||
bool run_forever = command_line.HasSwitch(
|
||||
shell::FlagForSwitch(shell::Switch::RunForever));
|
||||
RunNonInteractive(run_forever);
|
||||
bool run_forever =
|
||||
command_line.HasOption(shell::FlagForSwitch(shell::Switch::RunForever));
|
||||
RunNonInteractive(std::move(command_line), run_forever);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return RunInteractive();
|
||||
return RunInteractive(std::move(command_line));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user