Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
dd2c5a1b
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
dd2c5a1b
编写于
8月 13, 2020
作者:
M
Mehmet Fidanboylu
提交者:
GitHub
8月 13, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Plumbing for setting domain network policy (#20218)
上级
4746a93a
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
539 addition
and
111 deletion
+539
-111
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+2
-0
common/settings.h
common/settings.h
+4
-2
lib/io/dart_io.cc
lib/io/dart_io.cc
+19
-11
lib/io/dart_io.h
lib/io/dart_io.h
+3
-1
runtime/dart_isolate.cc
runtime/dart_isolate.cc
+5
-2
runtime/dart_isolate.h
runtime/dart_isolate.h
+2
-1
shell/common/switches.cc
shell/common/switches.cc
+5
-2
shell/common/switches.h
shell/common/switches.h
+9
-6
shell/platform/android/BUILD.gn
shell/platform/android/BUILD.gn
+3
-0
shell/platform/android/io/flutter/embedding/engine/loader/ApplicationInfoLoader.java
...lutter/embedding/engine/loader/ApplicationInfoLoader.java
+161
-0
shell/platform/android/io/flutter/embedding/engine/loader/FlutterApplicationInfo.java
...utter/embedding/engine/loader/FlutterApplicationInfo.java
+46
-0
shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java
...oid/io/flutter/embedding/engine/loader/FlutterLoader.java
+38
-84
shell/platform/android/test/io/flutter/embedding/engine/PluginComponentTest.java
...test/io/flutter/embedding/engine/PluginComponentTest.java
+6
-2
shell/platform/android/test/io/flutter/embedding/engine/loader/ApplicationInfoLoaderTest.java
...er/embedding/engine/loader/ApplicationInfoLoaderTest.java
+193
-0
shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
...latform/darwin/ios/framework/Source/FlutterDartProject.mm
+43
-0
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
dd2c5a1b
...
...
@@ -729,6 +729,8 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/Flutte
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/dart/PlatformMessageHandler.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/loader/ApplicationInfoLoader.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterApplicationInfo.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/loader/ResourceExtractor.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/engine/mutatorsstack/FlutterMutatorView.java
...
...
common/settings.h
浏览文件 @
dd2c5a1b
...
...
@@ -109,8 +109,10 @@ struct Settings {
bool
enable_dart_profiling
=
false
;
bool
disable_dart_asserts
=
false
;
// Used to signal the embedder whether HTTP connections are disabled.
bool
disable_http
=
false
;
// Whether embedder only allows secure connections.
bool
may_insecurely_connect_to_all_domains
=
true
;
// JSON-formatted domain network policy.
std
::
string
domain_network_policy
;
// Used as the script URI in debug messages. Does not affect how the Dart code
// is executed.
...
...
lib/io/dart_io.cc
浏览文件 @
dd2c5a1b
...
...
@@ -16,19 +16,27 @@ using tonic::ToDart;
namespace
flutter
{
void
DartIO
::
InitForIsolate
(
bool
disable_http
)
{
Dart_Handle
result
=
Dart_SetNativeResolver
(
Dart_LookupLibrary
(
ToDart
(
"dart:io"
)),
dart
::
bin
::
LookupIONative
,
dart
::
bin
::
LookupIONativeSymbol
);
void
DartIO
::
InitForIsolate
(
bool
may_insecurely_connect_to_all_domains
,
std
::
string
domain_network_policy
)
{
Dart_Handle
io_lib
=
Dart_LookupLibrary
(
ToDart
(
"dart:io"
));
Dart_Handle
result
=
Dart_SetNativeResolver
(
io_lib
,
dart
::
bin
::
LookupIONative
,
dart
::
bin
::
LookupIONativeSymbol
);
FML_CHECK
(
!
LogIfError
(
result
));
// The SDK expects this field to represent "allow http" so we switch the
// value.
Dart_Handle
allow_http_value
=
disable_http
?
Dart_False
()
:
Dart_True
();
Dart_Handle
set_field_result
=
Dart_SetField
(
Dart_LookupLibrary
(
ToDart
(
"dart:_http"
)),
ToDart
(
"_embedderAllowsHttp"
),
allow_http_value
);
FML_CHECK
(
!
LogIfError
(
set_field_result
));
Dart_Handle
embedder_config_type
=
Dart_GetType
(
io_lib
,
ToDart
(
"_EmbedderConfig"
),
0
,
nullptr
);
FML_CHECK
(
!
LogIfError
(
embedder_config_type
));
Dart_Handle
allow_insecure_connections_result
=
Dart_SetField
(
embedder_config_type
,
ToDart
(
"_mayInsecurelyConnectToAllDomains"
),
ToDart
(
may_insecurely_connect_to_all_domains
));
FML_CHECK
(
!
LogIfError
(
allow_insecure_connections_result
));
Dart_Handle
dart_args
[
1
];
dart_args
[
0
]
=
ToDart
(
domain_network_policy
);
Dart_Handle
set_domain_network_policy_result
=
Dart_Invoke
(
embedder_config_type
,
ToDart
(
"_setDomainPolicies"
),
1
,
dart_args
);
FML_CHECK
(
!
LogIfError
(
set_domain_network_policy_result
));
}
}
// namespace flutter
lib/io/dart_io.h
浏览文件 @
dd2c5a1b
...
...
@@ -6,6 +6,7 @@
#define FLUTTER_LIB_IO_DART_IO_H_
#include <cstdint>
#include <string>
#include "flutter/fml/macros.h"
...
...
@@ -13,7 +14,8 @@ namespace flutter {
class
DartIO
{
public:
static
void
InitForIsolate
(
bool
disable_http
);
static
void
InitForIsolate
(
bool
may_insecurely_connect_to_all_domains
,
std
::
string
domain_network_policy
);
private:
FML_DISALLOW_IMPLICIT_CONSTRUCTORS
(
DartIO
);
...
...
runtime/dart_isolate.cc
浏览文件 @
dd2c5a1b
...
...
@@ -139,7 +139,9 @@ DartIsolate::DartIsolate(const Settings& settings,
settings
.
unhandled_exception_callback
,
DartVMRef
::
GetIsolateNameServer
(),
is_root_isolate
),
disable_http_
(
settings
.
disable_http
)
{
may_insecurely_connect_to_all_domains_
(
settings
.
may_insecurely_connect_to_all_domains
),
domain_network_policy_
(
settings
.
domain_network_policy
)
{
phase_
=
Phase
::
Uninitialized
;
}
...
...
@@ -263,7 +265,8 @@ bool DartIsolate::LoadLibraries() {
tonic
::
DartState
::
Scope
scope
(
this
);
DartIO
::
InitForIsolate
(
disable_http_
);
DartIO
::
InitForIsolate
(
may_insecurely_connect_to_all_domains_
,
domain_network_policy_
);
DartUI
::
InitForIsolate
();
...
...
runtime/dart_isolate.h
浏览文件 @
dd2c5a1b
...
...
@@ -398,7 +398,8 @@ class DartIsolate : public UIDartState {
std
::
vector
<
std
::
shared_ptr
<
const
fml
::
Mapping
>>
kernel_buffers_
;
std
::
vector
<
std
::
unique_ptr
<
AutoFireClosure
>>
shutdown_callbacks_
;
fml
::
RefPtr
<
fml
::
TaskRunner
>
message_handling_task_runner_
;
const
bool
disable_http_
;
const
bool
may_insecurely_connect_to_all_domains_
;
std
::
string
domain_network_policy_
;
DartIsolate
(
const
Settings
&
settings
,
TaskRunners
task_runners
,
...
...
shell/common/switches.cc
浏览文件 @
dd2c5a1b
...
...
@@ -242,8 +242,11 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
}
}
settings
.
disable_http
=
command_line
.
HasOption
(
FlagForSwitch
(
Switch
::
DisableHttp
));
settings
.
may_insecurely_connect_to_all_domains
=
!
command_line
.
HasOption
(
FlagForSwitch
(
Switch
::
DisallowInsecureConnections
));
command_line
.
GetOptionValue
(
FlagForSwitch
(
Switch
::
DomainNetworkPolicy
),
&
settings
.
domain_network_policy
);
// Disable need for authentication codes for VM service communication, if
// specified.
...
...
shell/common/switches.h
浏览文件 @
dd2c5a1b
...
...
@@ -181,12 +181,15 @@ DEF_SWITCH(DisableDartAsserts,
"disabled. This flag may be specified if the user wishes to run "
"with assertions disabled in the debug product mode (i.e. with JIT "
"or DBC)."
)
DEF_SWITCH
(
DisableHttp
,
"disable-http"
,
"Dart VM has a master switch that can be set to disable insecure "
"HTTP and WebSocket protocols. Localhost or loopback addresses are "
"exempted. This flag can be specified if the embedder wants this "
"for a particular platform."
)
DEF_SWITCH
(
DisallowInsecureConnections
,
"disallow-insecure-connections"
,
"By default, dart:io allows all socket connections. If this switch "
"is set, all insecure connections are rejected."
)
DEF_SWITCH
(
DomainNetworkPolicy
,
"domain-network-policy"
,
"JSON encoded network policy per domain. This overrides the "
"DisallowInsecureConnections switch. Embedder can specify whether "
"to allow or disallow insecure connections at a domain level."
)
DEF_SWITCH
(
ForceMultithreading
,
"force-multithreading"
,
...
...
shell/platform/android/BUILD.gn
浏览文件 @
dd2c5a1b
...
...
@@ -153,6 +153,8 @@ android_java_sources = [
"io/flutter/embedding/engine/dart/DartExecutor.java",
"io/flutter/embedding/engine/dart/DartMessenger.java",
"io/flutter/embedding/engine/dart/PlatformMessageHandler.java",
"io/flutter/embedding/engine/loader/ApplicationInfoLoader.java",
"io/flutter/embedding/engine/loader/FlutterApplicationInfo.java",
"io/flutter/embedding/engine/loader/FlutterLoader.java",
"io/flutter/embedding/engine/loader/ResourceExtractor.java",
"io/flutter/embedding/engine/mutatorsstack/FlutterMutatorView.java",
...
...
@@ -430,6 +432,7 @@ action("robolectric_tests") {
"test/io/flutter/embedding/engine/PluginComponentTest.java",
"test/io/flutter/embedding/engine/RenderingComponentTest.java",
"test/io/flutter/embedding/engine/dart/DartExecutorTest.java",
"test/io/flutter/embedding/engine/loader/ApplicationInfoLoaderTest.java",
"test/io/flutter/embedding/engine/plugins/shim/ShimPluginRegistryTest.java",
"test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java",
"test/io/flutter/embedding/engine/systemchannels/RestorationChannelTest.java",
...
...
shell/platform/android/io/flutter/embedding/engine/loader/ApplicationInfoLoader.java
0 → 100644
浏览文件 @
dd2c5a1b
// Copyright 2013 The Flutter 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.embedding.engine.loader
;
import
android.content.Context
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.PackageManager
;
import
android.content.res.XmlResourceParser
;
import
android.os.Bundle
;
import
android.security.NetworkSecurityPolicy
;
import
androidx.annotation.NonNull
;
import
java.io.IOException
;
import
org.json.JSONArray
;
import
org.xmlpull.v1.XmlPullParserException
;
/** Loads application information given a Context. */
final
class
ApplicationInfoLoader
{
// XML Attribute keys supported in AndroidManifest.xml
static
final
String
PUBLIC_AOT_SHARED_LIBRARY_NAME
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
FlutterLoader
.
AOT_SHARED_LIBRARY_NAME
;
static
final
String
PUBLIC_VM_SNAPSHOT_DATA_KEY
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
FlutterLoader
.
VM_SNAPSHOT_DATA_KEY
;
static
final
String
PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
FlutterLoader
.
ISOLATE_SNAPSHOT_DATA_KEY
;
static
final
String
PUBLIC_FLUTTER_ASSETS_DIR_KEY
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
FlutterLoader
.
FLUTTER_ASSETS_DIR_KEY
;
static
final
String
NETWORK_POLICY_METADATA_KEY
=
"io.flutter.network-policy"
;
@NonNull
private
static
ApplicationInfo
getApplicationInfo
(
@NonNull
Context
applicationContext
)
{
try
{
return
applicationContext
.
getPackageManager
()
.
getApplicationInfo
(
applicationContext
.
getPackageName
(),
PackageManager
.
GET_META_DATA
);
}
catch
(
PackageManager
.
NameNotFoundException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
private
static
String
getString
(
Bundle
metadata
,
String
key
)
{
if
(
metadata
==
null
)
{
return
null
;
}
return
metadata
.
getString
(
key
,
null
);
}
private
static
String
getNetworkPolicy
(
ApplicationInfo
appInfo
,
Context
context
)
{
// We cannot use reflection to look at networkSecurityConfigRes because
// Android throws an error when we try to access fields marked as @hide.
// Instead we rely on metadata.
Bundle
metadata
=
appInfo
.
metaData
;
if
(
metadata
==
null
)
{
return
null
;
}
int
networkSecurityConfigRes
=
metadata
.
getInt
(
NETWORK_POLICY_METADATA_KEY
,
0
);
if
(
networkSecurityConfigRes
<=
0
)
{
return
null
;
}
JSONArray
output
=
new
JSONArray
();
try
{
XmlResourceParser
xrp
=
context
.
getResources
().
getXml
(
networkSecurityConfigRes
);
xrp
.
next
();
int
eventType
=
xrp
.
getEventType
();
while
(
eventType
!=
XmlResourceParser
.
END_DOCUMENT
)
{
if
(
eventType
==
XmlResourceParser
.
START_TAG
)
{
if
(
xrp
.
getName
().
equals
(
"domain-config"
))
{
parseDomainConfig
(
xrp
,
output
,
false
);
}
}
eventType
=
xrp
.
next
();
}
}
catch
(
IOException
|
XmlPullParserException
e
)
{
return
null
;
}
return
output
.
toString
();
}
private
static
boolean
getUseEmbeddedView
(
ApplicationInfo
appInfo
)
{
Bundle
bundle
=
appInfo
.
metaData
;
return
bundle
!=
null
&&
bundle
.
getBoolean
(
"io.flutter.embedded_views_preview"
);
}
private
static
void
parseDomainConfig
(
XmlResourceParser
xrp
,
JSONArray
output
,
boolean
inheritedCleartextPermitted
)
throws
IOException
,
XmlPullParserException
{
boolean
cleartextTrafficPermitted
=
xrp
.
getAttributeBooleanValue
(
null
,
"cleartextTrafficPermitted"
,
inheritedCleartextPermitted
);
while
(
true
)
{
int
eventType
=
xrp
.
next
();
if
(
eventType
==
XmlResourceParser
.
START_TAG
)
{
if
(
xrp
.
getName
().
equals
(
"domain"
))
{
// There can be multiple domains.
parseDomain
(
xrp
,
output
,
cleartextTrafficPermitted
);
}
else
if
(
xrp
.
getName
().
equals
(
"domain-config"
))
{
parseDomainConfig
(
xrp
,
output
,
cleartextTrafficPermitted
);
}
else
{
skipTag
(
xrp
);
}
}
else
if
(
eventType
==
XmlResourceParser
.
END_TAG
)
{
break
;
}
}
}
private
static
void
skipTag
(
XmlResourceParser
xrp
)
throws
IOException
,
XmlPullParserException
{
String
name
=
xrp
.
getName
();
int
eventType
=
xrp
.
getEventType
();
while
(
eventType
!=
XmlResourceParser
.
END_TAG
||
xrp
.
getName
()
!=
name
)
{
eventType
=
xrp
.
next
();
}
}
private
static
void
parseDomain
(
XmlResourceParser
xrp
,
JSONArray
output
,
boolean
cleartextPermitted
)
throws
IOException
,
XmlPullParserException
{
boolean
includeSubDomains
=
xrp
.
getAttributeBooleanValue
(
null
,
"includeSubdomains"
,
false
);
xrp
.
next
();
if
(
xrp
.
getEventType
()
!=
XmlResourceParser
.
TEXT
)
{
throw
new
IllegalStateException
(
"Expected text"
);
}
String
domain
=
xrp
.
getText
().
trim
();
JSONArray
outputArray
=
new
JSONArray
();
outputArray
.
put
(
domain
);
outputArray
.
put
(
includeSubDomains
);
outputArray
.
put
(
cleartextPermitted
);
output
.
put
(
outputArray
);
xrp
.
next
();
if
(
xrp
.
getEventType
()
!=
XmlResourceParser
.
END_TAG
)
{
throw
new
IllegalStateException
(
"Expected end of domain tag"
);
}
}
/**
* Initialize our Flutter config values by obtaining them from the manifest XML file, falling back
* to default values.
*/
@NonNull
public
static
FlutterApplicationInfo
load
(
@NonNull
Context
applicationContext
)
{
ApplicationInfo
appInfo
=
getApplicationInfo
(
applicationContext
);
// Prior to API 23, cleartext traffic is allowed.
boolean
clearTextPermitted
=
true
;
if
(
android
.
os
.
Build
.
VERSION
.
SDK_INT
>=
23
)
{
clearTextPermitted
=
NetworkSecurityPolicy
.
getInstance
().
isCleartextTrafficPermitted
();
}
return
new
FlutterApplicationInfo
(
getString
(
appInfo
.
metaData
,
PUBLIC_AOT_SHARED_LIBRARY_NAME
),
getString
(
appInfo
.
metaData
,
PUBLIC_VM_SNAPSHOT_DATA_KEY
),
getString
(
appInfo
.
metaData
,
PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY
),
getString
(
appInfo
.
metaData
,
PUBLIC_FLUTTER_ASSETS_DIR_KEY
),
getNetworkPolicy
(
appInfo
,
applicationContext
),
appInfo
.
nativeLibraryDir
,
clearTextPermitted
,
getUseEmbeddedView
(
appInfo
));
}
}
shell/platform/android/io/flutter/embedding/engine/loader/FlutterApplicationInfo.java
0 → 100644
浏览文件 @
dd2c5a1b
// Copyright 2013 The Flutter 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.embedding.engine.loader
;
/** Encapsulates all the information that Flutter needs from application manifest. */
public
final
class
FlutterApplicationInfo
{
private
static
final
String
DEFAULT_AOT_SHARED_LIBRARY_NAME
=
"libapp.so"
;
private
static
final
String
DEFAULT_VM_SNAPSHOT_DATA
=
"vm_snapshot_data"
;
private
static
final
String
DEFAULT_ISOLATE_SNAPSHOT_DATA
=
"isolate_snapshot_data"
;
private
static
final
String
DEFAULT_FLUTTER_ASSETS_DIR
=
"flutter_assets"
;
final
String
aotSharedLibraryName
;
final
String
vmSnapshotData
;
final
String
isolateSnapshotData
;
final
String
flutterAssetsDir
;
final
String
domainNetworkPolicy
;
final
String
nativeLibraryDir
;
final
boolean
clearTextPermitted
;
// TODO(cyanlaz): Remove this when dynamic thread merging is done.
// https://github.com/flutter/flutter/issues/59930
final
boolean
useEmbeddedView
;
public
FlutterApplicationInfo
(
String
aotSharedLibraryName
,
String
vmSnapshotData
,
String
isolateSnapshotData
,
String
flutterAssetsDir
,
String
domainNetworkPolicy
,
String
nativeLibraryDir
,
boolean
clearTextPermitted
,
boolean
useEmbeddedView
)
{
this
.
aotSharedLibraryName
=
aotSharedLibraryName
==
null
?
DEFAULT_AOT_SHARED_LIBRARY_NAME
:
aotSharedLibraryName
;
this
.
vmSnapshotData
=
vmSnapshotData
==
null
?
DEFAULT_VM_SNAPSHOT_DATA
:
vmSnapshotData
;
this
.
isolateSnapshotData
=
isolateSnapshotData
==
null
?
DEFAULT_ISOLATE_SNAPSHOT_DATA
:
isolateSnapshotData
;
this
.
flutterAssetsDir
=
flutterAssetsDir
==
null
?
DEFAULT_FLUTTER_ASSETS_DIR
:
flutterAssetsDir
;
this
.
nativeLibraryDir
=
nativeLibraryDir
;
this
.
domainNetworkPolicy
=
domainNetworkPolicy
==
null
?
""
:
domainNetworkPolicy
;
this
.
clearTextPermitted
=
clearTextPermitted
;
this
.
useEmbeddedView
=
useEmbeddedView
;
}
}
shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java
浏览文件 @
dd2c5a1b
...
...
@@ -5,10 +5,8 @@
package
io.flutter.embedding.engine.loader
;
import
android.content.Context
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.PackageManager
;
import
android.content.res.AssetManager
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.os.Looper
;
import
android.os.SystemClock
;
...
...
@@ -31,35 +29,15 @@ public class FlutterLoader {
private
static
final
String
TAG
=
"FlutterLoader"
;
// Must match values in flutter::switches
private
static
final
String
AOT_SHARED_LIBRARY_NAME
=
"aot-shared-library-name"
;
private
static
final
String
SNAPSHOT_ASSET_PATH_KEY
=
"snapshot-asset-path"
;
private
static
final
String
VM_SNAPSHOT_DATA_KEY
=
"vm-snapshot-data"
;
private
static
final
String
ISOLATE_SNAPSHOT_DATA_KEY
=
"isolate-snapshot-data"
;
private
static
final
String
FLUTTER_ASSETS_DIR_KEY
=
"flutter-assets-dir"
;
// XML Attribute keys supported in AndroidManifest.xml
private
static
final
String
PUBLIC_AOT_SHARED_LIBRARY_NAME
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
AOT_SHARED_LIBRARY_NAME
;
private
static
final
String
PUBLIC_VM_SNAPSHOT_DATA_KEY
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
VM_SNAPSHOT_DATA_KEY
;
private
static
final
String
PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
ISOLATE_SNAPSHOT_DATA_KEY
;
private
static
final
String
PUBLIC_FLUTTER_ASSETS_DIR_KEY
=
FlutterLoader
.
class
.
getName
()
+
'.'
+
FLUTTER_ASSETS_DIR_KEY
;
static
final
String
AOT_SHARED_LIBRARY_NAME
=
"aot-shared-library-name"
;
static
final
String
SNAPSHOT_ASSET_PATH_KEY
=
"snapshot-asset-path"
;
static
final
String
VM_SNAPSHOT_DATA_KEY
=
"vm-snapshot-data"
;
static
final
String
ISOLATE_SNAPSHOT_DATA_KEY
=
"isolate-snapshot-data"
;
static
final
String
FLUTTER_ASSETS_DIR_KEY
=
"flutter-assets-dir"
;
// Resource names used for components of the precompiled snapshot.
private
static
final
String
DEFAULT_AOT_SHARED_LIBRARY_NAME
=
"libapp.so"
;
private
static
final
String
DEFAULT_VM_SNAPSHOT_DATA
=
"vm_snapshot_data"
;
private
static
final
String
DEFAULT_ISOLATE_SNAPSHOT_DATA
=
"isolate_snapshot_data"
;
private
static
final
String
DEFAULT_LIBRARY
=
"libflutter.so"
;
private
static
final
String
DEFAULT_KERNEL_BLOB
=
"kernel_blob.bin"
;
private
static
final
String
DEFAULT_FLUTTER_ASSETS_DIR
=
"flutter_assets"
;
// Mutable because default values can be overridden via config properties
private
String
aotSharedLibraryName
=
DEFAULT_AOT_SHARED_LIBRARY_NAME
;
private
String
vmSnapshotData
=
DEFAULT_VM_SNAPSHOT_DATA
;
private
String
isolateSnapshotData
=
DEFAULT_ISOLATE_SNAPSHOT_DATA
;
private
String
flutterAssetsDir
=
DEFAULT_FLUTTER_ASSETS_DIR
;
private
static
FlutterLoader
instance
;
...
...
@@ -78,9 +56,17 @@ public class FlutterLoader {
return
instance
;
}
@NonNull
public
static
FlutterLoader
getInstanceForTest
(
FlutterApplicationInfo
flutterApplicationInfo
)
{
FlutterLoader
loader
=
new
FlutterLoader
();
loader
.
flutterApplicationInfo
=
flutterApplicationInfo
;
return
loader
;
}
private
boolean
initialized
=
false
;
@Nullable
private
Settings
settings
;
private
long
initStartTimestampMillis
;
private
FlutterApplicationInfo
flutterApplicationInfo
;
private
static
class
InitResult
{
final
String
appStoragePath
;
...
...
@@ -131,7 +117,7 @@ public class FlutterLoader {
this
.
settings
=
settings
;
initStartTimestampMillis
=
SystemClock
.
uptimeMillis
();
initConfig
(
appContext
);
flutterApplicationInfo
=
ApplicationInfoLoader
.
load
(
appContext
);
VsyncWaiter
.
getInstance
((
WindowManager
)
appContext
.
getSystemService
(
Context
.
WINDOW_SERVICE
))
.
init
();
...
...
@@ -195,10 +181,9 @@ public class FlutterLoader {
List
<
String
>
shellArgs
=
new
ArrayList
<>();
shellArgs
.
add
(
"--icu-symbol-prefix=_binary_icudtl_dat"
);
ApplicationInfo
applicationInfo
=
getApplicationInfo
(
applicationContext
);
shellArgs
.
add
(
"--icu-native-lib-path="
+
a
pplicationInfo
.
nativeLibraryDir
+
flutterA
pplicationInfo
.
nativeLibraryDir
+
File
.
separator
+
DEFAULT_LIBRARY
);
if
(
args
!=
null
)
{
...
...
@@ -207,13 +192,16 @@ public class FlutterLoader {
String
kernelPath
=
null
;
if
(
BuildConfig
.
DEBUG
||
BuildConfig
.
JIT_RELEASE
)
{
String
snapshotAssetPath
=
result
.
dataDirPath
+
File
.
separator
+
flutterAssetsDir
;
String
snapshotAssetPath
=
result
.
dataDirPath
+
File
.
separator
+
flutterApplicationInfo
.
flutterAssetsDir
;
kernelPath
=
snapshotAssetPath
+
File
.
separator
+
DEFAULT_KERNEL_BLOB
;
shellArgs
.
add
(
"--"
+
SNAPSHOT_ASSET_PATH_KEY
+
"="
+
snapshotAssetPath
);
shellArgs
.
add
(
"--"
+
VM_SNAPSHOT_DATA_KEY
+
"="
+
vmSnapshotData
);
shellArgs
.
add
(
"--"
+
ISOLATE_SNAPSHOT_DATA_KEY
+
"="
+
isolateSnapshotData
);
shellArgs
.
add
(
"--"
+
VM_SNAPSHOT_DATA_KEY
+
"="
+
flutterApplicationInfo
.
vmSnapshotData
);
shellArgs
.
add
(
"--"
+
ISOLATE_SNAPSHOT_DATA_KEY
+
"="
+
flutterApplicationInfo
.
isolateSnapshotData
);
}
else
{
shellArgs
.
add
(
"--"
+
AOT_SHARED_LIBRARY_NAME
+
"="
+
aotSharedLibraryName
);
shellArgs
.
add
(
"--"
+
AOT_SHARED_LIBRARY_NAME
+
"="
+
flutterApplicationInfo
.
aotSharedLibraryName
);
// Most devices can load the AOT shared library based on the library name
// with no directory path. Provide a fully qualified path to the library
...
...
@@ -222,28 +210,28 @@ public class FlutterLoader {
"--"
+
AOT_SHARED_LIBRARY_NAME
+
"="
+
a
pplicationInfo
.
nativeLibraryDir
+
flutterA
pplicationInfo
.
nativeLibraryDir
+
File
.
separator
+
aotSharedLibraryName
);
+
flutterApplicationInfo
.
aotSharedLibraryName
);
}
shellArgs
.
add
(
"--cache-dir-path="
+
result
.
engineCachesPath
);
// TODO(mehmetf): Announce this since it is a breaking change then enable it.
// if (!flutterApplicationInfo.clearTextPermitted) {
// shellArgs.add("--disallow-insecure-connections");
// }
if
(
flutterApplicationInfo
.
domainNetworkPolicy
!=
null
)
{
shellArgs
.
add
(
"--domain-network-policy="
+
flutterApplicationInfo
.
domainNetworkPolicy
);
}
if
(
flutterApplicationInfo
.
useEmbeddedView
)
{
shellArgs
.
add
(
"--use-embedded-view"
);
}
if
(
settings
.
getLogTag
()
!=
null
)
{
shellArgs
.
add
(
"--log-tag="
+
settings
.
getLogTag
());
}
long
initTimeMillis
=
SystemClock
.
uptimeMillis
()
-
initStartTimestampMillis
;
// TODO(cyanlaz): Remove this when dynamic thread merging is done.
// https://github.com/flutter/flutter/issues/59930
Bundle
bundle
=
applicationInfo
.
metaData
;
if
(
bundle
!=
null
)
{
boolean
use_embedded_view
=
bundle
.
getBoolean
(
"io.flutter.embedded_views_preview"
);
if
(
use_embedded_view
)
{
shellArgs
.
add
(
"--use-embedded-view"
);
}
}
FlutterJNI
.
nativeInit
(
applicationContext
,
shellArgs
.
toArray
(
new
String
[
0
]),
...
...
@@ -306,40 +294,6 @@ public class FlutterLoader {
});
}
@NonNull
private
ApplicationInfo
getApplicationInfo
(
@NonNull
Context
applicationContext
)
{
try
{
return
applicationContext
.
getPackageManager
()
.
getApplicationInfo
(
applicationContext
.
getPackageName
(),
PackageManager
.
GET_META_DATA
);
}
catch
(
PackageManager
.
NameNotFoundException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
/**
* Initialize our Flutter config values by obtaining them from the manifest XML file, falling back
* to default values.
*/
private
void
initConfig
(
@NonNull
Context
applicationContext
)
{
Bundle
metadata
=
getApplicationInfo
(
applicationContext
).
metaData
;
// There isn't a `<meta-data>` tag as a direct child of `<application>` in
// `AndroidManifest.xml`.
if
(
metadata
==
null
)
{
return
;
}
aotSharedLibraryName
=
metadata
.
getString
(
PUBLIC_AOT_SHARED_LIBRARY_NAME
,
DEFAULT_AOT_SHARED_LIBRARY_NAME
);
flutterAssetsDir
=
metadata
.
getString
(
PUBLIC_FLUTTER_ASSETS_DIR_KEY
,
DEFAULT_FLUTTER_ASSETS_DIR
);
vmSnapshotData
=
metadata
.
getString
(
PUBLIC_VM_SNAPSHOT_DATA_KEY
,
DEFAULT_VM_SNAPSHOT_DATA
);
isolateSnapshotData
=
metadata
.
getString
(
PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY
,
DEFAULT_ISOLATE_SNAPSHOT_DATA
);
}
/** Extract assets out of the APK that need to be cached as uncompressed files on disk. */
private
ResourceExtractor
initResources
(
@NonNull
Context
applicationContext
)
{
ResourceExtractor
resourceExtractor
=
null
;
...
...
@@ -354,8 +308,8 @@ public class FlutterLoader {
// In debug/JIT mode these assets will be written to disk and then
// mapped into memory so they can be provided to the Dart VM.
resourceExtractor
.
addResource
(
fullAssetPathFrom
(
vmSnapshotData
))
.
addResource
(
fullAssetPathFrom
(
isolateSnapshotData
))
.
addResource
(
fullAssetPathFrom
(
flutterApplicationInfo
.
vmSnapshotData
))
.
addResource
(
fullAssetPathFrom
(
flutterApplicationInfo
.
isolateSnapshotData
))
.
addResource
(
fullAssetPathFrom
(
DEFAULT_KERNEL_BLOB
));
resourceExtractor
.
start
();
...
...
@@ -365,7 +319,7 @@ public class FlutterLoader {
@NonNull
public
String
findAppBundlePath
()
{
return
flutterAssetsDir
;
return
flutterA
pplicationInfo
.
flutterA
ssetsDir
;
}
/**
...
...
@@ -396,7 +350,7 @@ public class FlutterLoader {
@NonNull
private
String
fullAssetPathFrom
(
@NonNull
String
filePath
)
{
return
flutterAssetsDir
+
File
.
separator
+
filePath
;
return
flutterA
pplicationInfo
.
flutterA
ssetsDir
+
File
.
separator
+
filePath
;
}
public
static
class
Settings
{
...
...
shell/platform/android/test/io/flutter/embedding/engine/PluginComponentTest.java
浏览文件 @
dd2c5a1b
...
...
@@ -8,6 +8,7 @@ import static org.mockito.Mockito.when;
import
androidx.annotation.NonNull
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.FlutterJNI
;
import
io.flutter.embedding.engine.loader.FlutterApplicationInfo
;
import
io.flutter.embedding.engine.loader.FlutterLoader
;
import
io.flutter.embedding.engine.plugins.FlutterPlugin
;
import
org.junit.Test
;
...
...
@@ -26,6 +27,8 @@ public class PluginComponentTest {
// Setup test.
FlutterJNI
flutterJNI
=
mock
(
FlutterJNI
.
class
);
when
(
flutterJNI
.
isAttached
()).
thenReturn
(
true
);
FlutterApplicationInfo
emptyInfo
=
new
FlutterApplicationInfo
(
null
,
null
,
null
,
null
,
null
,
null
,
false
,
false
);
// FlutterLoader is the object to which the PluginRegistry defers for obtaining
// the path to a Flutter asset. Ideally in this component test we would use a
...
...
@@ -44,7 +47,8 @@ public class PluginComponentTest {
public
String
answer
(
InvocationOnMock
invocation
)
throws
Throwable
{
// Defer to a real FlutterLoader to return the asset path.
String
fileNameOrSubpath
=
(
String
)
invocation
.
getArguments
()[
0
];
return
FlutterLoader
.
getInstance
().
getLookupKeyForAsset
(
fileNameOrSubpath
);
return
FlutterLoader
.
getInstanceForTest
(
emptyInfo
)
.
getLookupKeyForAsset
(
fileNameOrSubpath
);
}
});
when
(
flutterLoader
.
getLookupKeyForAsset
(
any
(
String
.
class
),
any
(
String
.
class
)))
...
...
@@ -55,7 +59,7 @@ public class PluginComponentTest {
// Defer to a real FlutterLoader to return the asset path.
String
fileNameOrSubpath
=
(
String
)
invocation
.
getArguments
()[
0
];
String
packageName
=
(
String
)
invocation
.
getArguments
()[
1
];
return
FlutterLoader
.
getInstance
(
)
return
FlutterLoader
.
getInstance
ForTest
(
emptyInfo
)
.
getLookupKeyForAsset
(
fileNameOrSubpath
,
packageName
);
}
});
...
...
shell/platform/android/test/io/flutter/embedding/engine/loader/ApplicationInfoLoaderTest.java
0 → 100644
浏览文件 @
dd2c5a1b
package
io.flutter.embedding.engine.loader
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
mockito
.
Mockito
.
any
;
import
static
org
.
mockito
.
Mockito
.
anyInt
;
import
static
org
.
mockito
.
Mockito
.
doAnswer
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
android.content.Context
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.PackageManager
;
import
android.content.res.Resources
;
import
android.content.res.XmlResourceParser
;
import
android.os.Bundle
;
import
android.security.NetworkSecurityPolicy
;
import
java.io.StringReader
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.stubbing.Answer
;
import
org.robolectric.RobolectricTestRunner
;
import
org.robolectric.RuntimeEnvironment
;
import
org.robolectric.annotation.Config
;
import
org.robolectric.annotation.Implementation
;
import
org.robolectric.annotation.Implements
;
import
org.xmlpull.v1.XmlPullParser
;
import
org.xmlpull.v1.XmlPullParserFactory
;
@Config
(
manifest
=
Config
.
NONE
)
@RunWith
(
RobolectricTestRunner
.
class
)
public
class
ApplicationInfoLoaderTest
{
@Test
public
void
itGeneratesCorrectApplicationInfoWithDefaultManifest
()
{
FlutterApplicationInfo
info
=
ApplicationInfoLoader
.
load
(
RuntimeEnvironment
.
application
);
assertNotNull
(
info
);
assertEquals
(
"libapp.so"
,
info
.
aotSharedLibraryName
);
assertEquals
(
"vm_snapshot_data"
,
info
.
vmSnapshotData
);
assertEquals
(
"isolate_snapshot_data"
,
info
.
isolateSnapshotData
);
assertEquals
(
"flutter_assets"
,
info
.
flutterAssetsDir
);
assertEquals
(
""
,
info
.
domainNetworkPolicy
);
assertNull
(
info
.
nativeLibraryDir
);
assertEquals
(
true
,
info
.
clearTextPermitted
);
assertEquals
(
false
,
info
.
useEmbeddedView
);
}
@Config
(
shadows
=
{
ApplicationInfoLoaderTest
.
ShadowNetworkSecurityPolicy
.
class
})
@Test
public
void
itVotesAgainstClearTextIfSecurityPolicySaysSo
()
{
FlutterApplicationInfo
info
=
ApplicationInfoLoader
.
load
(
RuntimeEnvironment
.
application
);
assertNotNull
(
info
);
assertEquals
(
false
,
info
.
clearTextPermitted
);
}
@Implements
(
NetworkSecurityPolicy
.
class
)
public
static
class
ShadowNetworkSecurityPolicy
{
@Implementation
public
boolean
isCleartextTrafficPermitted
()
{
return
false
;
}
}
private
Context
generateMockContext
(
Bundle
metadata
,
String
networkPolicyXml
)
throws
Exception
{
Context
context
=
mock
(
Context
.
class
);
PackageManager
packageManager
=
mock
(
PackageManager
.
class
);
ApplicationInfo
applicationInfo
=
mock
(
ApplicationInfo
.
class
);
applicationInfo
.
metaData
=
metadata
;
Resources
resources
=
mock
(
Resources
.
class
);
when
(
context
.
getPackageManager
()).
thenReturn
(
packageManager
);
when
(
context
.
getResources
()).
thenReturn
(
resources
);
when
(
packageManager
.
getApplicationInfo
(
any
(
String
.
class
),
any
(
int
.
class
)))
.
thenReturn
(
applicationInfo
);
if
(
networkPolicyXml
!=
null
)
{
metadata
.
putInt
(
ApplicationInfoLoader
.
NETWORK_POLICY_METADATA_KEY
,
5
);
doAnswer
(
invocationOnMock
->
createMockResourceParser
(
networkPolicyXml
))
.
when
(
resources
)
.
getXml
(
5
);
}
return
context
;
}
@Test
public
void
itGeneratesCorrectApplicationInfoWithCustomValues
()
throws
Exception
{
Bundle
bundle
=
new
Bundle
();
bundle
.
putString
(
ApplicationInfoLoader
.
PUBLIC_AOT_SHARED_LIBRARY_NAME
,
"testaot"
);
bundle
.
putString
(
ApplicationInfoLoader
.
PUBLIC_VM_SNAPSHOT_DATA_KEY
,
"testvmsnapshot"
);
bundle
.
putString
(
ApplicationInfoLoader
.
PUBLIC_ISOLATE_SNAPSHOT_DATA_KEY
,
"testisolatesnapshot"
);
bundle
.
putString
(
ApplicationInfoLoader
.
PUBLIC_FLUTTER_ASSETS_DIR_KEY
,
"testassets"
);
bundle
.
putBoolean
(
"io.flutter.embedded_views_preview"
,
true
);
Context
context
=
generateMockContext
(
bundle
,
null
);
FlutterApplicationInfo
info
=
ApplicationInfoLoader
.
load
(
context
);
assertNotNull
(
info
);
assertEquals
(
"testaot"
,
info
.
aotSharedLibraryName
);
assertEquals
(
"testvmsnapshot"
,
info
.
vmSnapshotData
);
assertEquals
(
"testisolatesnapshot"
,
info
.
isolateSnapshotData
);
assertEquals
(
"testassets"
,
info
.
flutterAssetsDir
);
assertNull
(
info
.
nativeLibraryDir
);
assertEquals
(
""
,
info
.
domainNetworkPolicy
);
assertEquals
(
true
,
info
.
useEmbeddedView
);
}
@Test
public
void
itGeneratesCorrectNetworkPolicy
()
throws
Exception
{
Bundle
bundle
=
new
Bundle
();
String
networkPolicyXml
=
"<network-security-config>"
+
"<domain-config cleartextTrafficPermitted=\"false\">"
+
"<domain includeSubdomains=\"true\">secure.example.com</domain>"
+
"</domain-config>"
+
"</network-security-config>"
;
Context
context
=
generateMockContext
(
bundle
,
networkPolicyXml
);
FlutterApplicationInfo
info
=
ApplicationInfoLoader
.
load
(
context
);
assertNotNull
(
info
);
assertEquals
(
"[[\"secure.example.com\",true,false]]"
,
info
.
domainNetworkPolicy
);
}
@Test
public
void
itHandlesBogusInformationInNetworkPolicy
()
throws
Exception
{
Bundle
bundle
=
new
Bundle
();
String
networkPolicyXml
=
"<network-security-config>"
+
"<domain-config cleartextTrafficPermitted=\"false\">"
+
"<domain includeSubdomains=\"true\">secure.example.com</domain>"
+
"<pin-set expiration=\"2018-01-01\">"
+
"<pin digest=\"SHA-256\">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>"
+
"<!-- backup pin -->"
+
"<pin digest=\"SHA-256\">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>"
+
"</pin-set>"
+
"</domain-config>"
+
"</network-security-config>"
;
Context
context
=
generateMockContext
(
bundle
,
networkPolicyXml
);
FlutterApplicationInfo
info
=
ApplicationInfoLoader
.
load
(
context
);
assertNotNull
(
info
);
assertEquals
(
"[[\"secure.example.com\",true,false]]"
,
info
.
domainNetworkPolicy
);
}
@Test
public
void
itHandlesNestedSubDomains
()
throws
Exception
{
Bundle
bundle
=
new
Bundle
();
String
networkPolicyXml
=
"<network-security-config>"
+
"<domain-config cleartextTrafficPermitted=\"true\">"
+
"<domain includeSubdomains=\"true\">example.com</domain>"
+
"<domain-config>"
+
"<domain includeSubdomains=\"true\">insecure.example.com</domain>"
+
"</domain-config>"
+
"<domain-config cleartextTrafficPermitted=\"false\">"
+
"<domain includeSubdomains=\"true\">secure.example.com</domain>"
+
"</domain-config>"
+
"</domain-config>"
+
"</network-security-config>"
;
Context
context
=
generateMockContext
(
bundle
,
networkPolicyXml
);
FlutterApplicationInfo
info
=
ApplicationInfoLoader
.
load
(
context
);
assertNotNull
(
info
);
assertEquals
(
"[[\"example.com\",true,true],[\"insecure.example.com\",true,true],[\"secure.example.com\",true,false]]"
,
info
.
domainNetworkPolicy
);
}
// The following ridiculousness is needed because Android gives no way for us
// to customize XmlResourceParser. We have to mock it and tie each method
// we use to an actual Xml parser.
private
XmlResourceParser
createMockResourceParser
(
String
xml
)
throws
Exception
{
final
XmlPullParser
xpp
=
XmlPullParserFactory
.
newInstance
().
newPullParser
();
xpp
.
setInput
(
new
StringReader
(
xml
));
XmlResourceParser
resourceParser
=
mock
(
XmlResourceParser
.
class
);
final
Answer
<
Object
>
invokeMethodOnRealParser
=
invocation
->
invocation
.
getMethod
().
invoke
(
xpp
,
invocation
.
getArguments
());
when
(
resourceParser
.
next
()).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getName
()).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getEventType
()).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getText
()).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getAttributeCount
()).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getAttributeName
(
anyInt
())).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getAttributeValue
(
anyInt
())).
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getAttributeValue
(
any
(
String
.
class
),
any
(
String
.
class
)))
.
thenAnswer
(
invokeMethodOnRealParser
);
when
(
resourceParser
.
getAttributeBooleanValue
(
any
(
String
.
class
),
any
(
String
.
class
),
any
(
Boolean
.
class
)))
.
thenAnswer
(
invocation
->
{
Object
[]
args
=
invocation
.
getArguments
();
String
result
=
xpp
.
getAttributeValue
((
String
)
args
[
0
],
(
String
)
args
[
1
]);
if
(
result
==
null
)
{
return
(
Boolean
)
args
[
2
];
}
return
Boolean
.
parseBoolean
(
result
);
});
return
resourceParser
;
}
}
shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm
浏览文件 @
dd2c5a1b
...
...
@@ -26,6 +26,42 @@ extern const intptr_t kPlatformStrongDillSize;
static
const
char
*
kApplicationKernelSnapshotFileName
=
"kernel_blob.bin"
;
// TODO(mehmetf): Announce this since it is breaking change then enable it.
// static NSString* DomainNetworkPolicy(NSDictionary* appTransportSecurity) {
// if (appTransportSecurity == nil) {
// return @"";
// }
// //
// https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsexceptiondomains
// NSDictionary* exceptionDomains = [appTransportSecurity objectForKey:@"NSExceptionDomains"];
// if (exceptionDomains == nil) {
// return @"";
// }
// NSMutableArray* networkConfigArray = [[NSMutableArray alloc] init];
// for (NSString* domain in exceptionDomains) {
// NSDictionary* domainConfiguration = [exceptionDomains objectForKey:domain];
// BOOL includesSubDomains =
// [[domainConfiguration objectForKey:@"NSIncludesSubdomains"] boolValue];
// BOOL allowsCleartextCommunication =
// [[domainConfiguration objectForKey:@"NSExceptionAllowsInsecureHTTPLoads"] boolValue];
// [networkConfigArray addObject:[NSArray arrayWithObjects:domain, includesSubDomains,
// allowsCleartextCommunication, nil]];
// }
// NSData* jsonData = [NSJSONSerialization dataWithJSONObject:networkConfigArray
// options:0
// error:NULL];
// return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// }
// TODO(mehmetf): Announce this since it is breaking change then enable it.
// static bool AllowsArbitraryLoads(NSDictionary* appTransportSecurity) {
// if (appTransportSecurity != nil) {
// return [[appTransportSecurity objectForKey:@"NSAllowsArbitraryLoads"] boolValue];
// } else {
// return false;
// }
// }
static
flutter
::
Settings
DefaultSettingsForProcess
(
NSBundle
*
bundle
=
nil
)
{
auto
command_line
=
flutter
::
CommandLineFromNSProcessInfo
();
...
...
@@ -132,6 +168,13 @@ static flutter::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) {
}
}
// TODO(mehmetf): Announce this since it is breaking change then enable it.
// Domain network configuration
// NSDictionary* appTransportSecurity =
// [mainBundle objectForInfoDictionaryKey:@"NSAppTransportSecurity"];
// settings.may_insecurely_connect_to_all_domains = AllowsArbitraryLoads(appTransportSecurity);
// settings.domain_network_policy = DomainNetworkPolicy(appTransportSecurity).UTF8String;
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
// There are no ownership concerns here as all mappings are owned by the
// embedder and not the engine.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录