Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
921c8030
Unverified
Commit
921c8030
authored
Aug 08, 2022
by
Jonah Williams
Committed by
GitHub
Aug 08, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] support hot reload of font assets (#109091)
parent
f9391522
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
93 additions
and
2 deletions
+93
-2
devfs.dart
packages/flutter_tools/lib/src/devfs.dart
+11
-0
devfs_web.dart
packages/flutter_tools/lib/src/isolated/devfs_web.dart
+3
-0
run_hot.dart
packages/flutter_tools/lib/src/run_hot.dart
+10
-2
vmservice.dart
packages/flutter_tools/lib/src/vmservice.dart
+15
-0
devfs_test.dart
packages/flutter_tools/test/general.shard/devfs_test.dart
+51
-0
resident_runner_test.dart
...lutter_tools/test/general.shard/resident_runner_test.dart
+3
-0
No files found.
packages/flutter_tools/lib/src/devfs.dart
View file @
921c8030
...
@@ -20,6 +20,8 @@ import 'compile.dart';
...
@@ -20,6 +20,8 @@ import 'compile.dart';
import
'convert.dart'
show
base64
,
utf8
;
import
'convert.dart'
show
base64
,
utf8
;
import
'vmservice.dart'
;
import
'vmservice.dart'
;
const
String
_kFontManifest
=
'FontManifest.json'
;
class
DevFSConfig
{
class
DevFSConfig
{
/// Should DevFS assume that symlink targets are stable?
/// Should DevFS assume that symlink targets are stable?
bool
cacheSymlinks
=
false
;
bool
cacheSymlinks
=
false
;
...
@@ -485,6 +487,9 @@ class DevFS {
...
@@ -485,6 +487,9 @@ class DevFS {
// A flag to indicate whether we have called `setAssetDirectory` on the target device.
// A flag to indicate whether we have called `setAssetDirectory` on the target device.
bool
hasSetAssetDirectory
=
false
;
bool
hasSetAssetDirectory
=
false
;
/// Whether the font manifest was uploaded during [update].
bool
didUpdateFontManifest
=
false
;
List
<
Uri
>
sources
=
<
Uri
>[];
List
<
Uri
>
sources
=
<
Uri
>[];
DateTime
?
lastCompiled
;
DateTime
?
lastCompiled
;
DateTime
?
_previousCompiled
;
DateTime
?
_previousCompiled
;
...
@@ -589,6 +594,7 @@ class DevFS {
...
@@ -589,6 +594,7 @@ class DevFS {
assert
(
trackWidgetCreation
!=
null
);
assert
(
trackWidgetCreation
!=
null
);
assert
(
generator
!=
null
);
assert
(
generator
!=
null
);
final
DateTime
candidateCompileTime
=
DateTime
.
now
();
final
DateTime
candidateCompileTime
=
DateTime
.
now
();
didUpdateFontManifest
=
false
;
lastPackageConfig
=
packageConfig
;
lastPackageConfig
=
packageConfig
;
_widgetCacheOutputFile
=
_fileSystem
.
file
(
'
$dillOutputPath
.incremental.dill.widget_cache'
);
_widgetCacheOutputFile
=
_fileSystem
.
file
(
'
$dillOutputPath
.incremental.dill.widget_cache'
);
...
@@ -644,6 +650,11 @@ class DevFS {
...
@@ -644,6 +650,11 @@ class DevFS {
if
(
deviceUri
.
path
.
startsWith
(
assetBuildDirPrefix
))
{
if
(
deviceUri
.
path
.
startsWith
(
assetBuildDirPrefix
))
{
archivePath
=
deviceUri
.
path
.
substring
(
assetBuildDirPrefix
.
length
);
archivePath
=
deviceUri
.
path
.
substring
(
assetBuildDirPrefix
.
length
);
}
}
// If the font manifest is updated, mark this as true so the hot runner
// can invoke a service extension to force the engine to reload fonts.
if
(
archivePath
==
_kFontManifest
)
{
didUpdateFontManifest
=
true
;
}
if
(
bundle
.
entryKinds
[
archivePath
]
==
AssetKind
.
shader
)
{
if
(
bundle
.
entryKinds
[
archivePath
]
==
AssetKind
.
shader
)
{
final
Future
<
DevFSContent
?>
pending
=
shaderCompiler
.
recompileShader
(
content
);
final
Future
<
DevFSContent
?>
pending
=
shaderCompiler
.
recompileShader
(
content
);
...
...
packages/flutter_tools/lib/src/isolated/devfs_web.dart
View file @
921c8030
...
@@ -677,6 +677,9 @@ class WebDevFS implements DevFS {
...
@@ -677,6 +677,9 @@ class WebDevFS implements DevFS {
@override
@override
bool
hasSetAssetDirectory
=
false
;
bool
hasSetAssetDirectory
=
false
;
@override
bool
didUpdateFontManifest
=
false
;
Future
<
DebugConnection
>?
_cachedExtensionFuture
;
Future
<
DebugConnection
>?
_cachedExtensionFuture
;
StreamSubscription
<
void
>?
_connectedApps
;
StreamSubscription
<
void
>?
_connectedApps
;
...
...
packages/flutter_tools/lib/src/run_hot.dart
View file @
921c8030
...
@@ -1032,7 +1032,7 @@ class HotRunner extends ResidentRunner {
...
@@ -1032,7 +1032,7 @@ class HotRunner extends ResidentRunner {
@visibleForTesting
@visibleForTesting
Future
<
void
>
evictDirtyAssets
()
async
{
Future
<
void
>
evictDirtyAssets
()
async
{
final
List
<
Future
<
Map
<
String
,
dynamic
>?>>
futures
=
<
Future
<
Map
<
String
,
dynamic
>
>>[];
final
List
<
Future
<
void
>>
futures
=
<
Future
<
void
>>[];
for
(
final
FlutterDevice
?
device
in
flutterDevices
)
{
for
(
final
FlutterDevice
?
device
in
flutterDevices
)
{
if
(
device
!.
devFS
!.
assetPathsToEvict
.
isEmpty
&&
device
.
devFS
!.
shaderPathsToEvict
.
isEmpty
)
{
if
(
device
!.
devFS
!.
assetPathsToEvict
.
isEmpty
&&
device
.
devFS
!.
shaderPathsToEvict
.
isEmpty
)
{
continue
;
continue
;
...
@@ -1060,6 +1060,14 @@ class HotRunner extends ResidentRunner {
...
@@ -1060,6 +1060,14 @@ class HotRunner extends ResidentRunner {
globals
.
printError
(
'Application isolate not found for
$device
'
);
globals
.
printError
(
'Application isolate not found for
$device
'
);
continue
;
continue
;
}
}
if
(
device
.
devFS
!.
didUpdateFontManifest
)
{
futures
.
add
(
device
.
vmService
!.
reloadAssetFonts
(
isolateId:
views
.
first
.
uiIsolate
!.
id
!,
viewId:
views
.
first
.
id
,
));
}
for
(
final
String
assetPath
in
device
.
devFS
!.
assetPathsToEvict
)
{
for
(
final
String
assetPath
in
device
.
devFS
!.
assetPathsToEvict
)
{
futures
.
add
(
futures
.
add
(
device
.
vmService
!
device
.
vmService
!
...
@@ -1081,7 +1089,7 @@ class HotRunner extends ResidentRunner {
...
@@ -1081,7 +1089,7 @@ class HotRunner extends ResidentRunner {
device
.
devFS
!.
assetPathsToEvict
.
clear
();
device
.
devFS
!.
assetPathsToEvict
.
clear
();
device
.
devFS
!.
shaderPathsToEvict
.
clear
();
device
.
devFS
!.
shaderPathsToEvict
.
clear
();
}
}
await
Future
.
wait
<
Map
<
String
,
Object
?>?
>(
futures
);
await
Future
.
wait
<
void
>(
futures
);
}
}
@override
@override
...
...
packages/flutter_tools/lib/src/vmservice.dart
View file @
921c8030
...
@@ -24,6 +24,7 @@ const String kListViewsMethod = '_flutter.listViews';
...
@@ -24,6 +24,7 @@ const String kListViewsMethod = '_flutter.listViews';
const
String
kScreenshotSkpMethod
=
'_flutter.screenshotSkp'
;
const
String
kScreenshotSkpMethod
=
'_flutter.screenshotSkp'
;
const
String
kScreenshotMethod
=
'_flutter.screenshot'
;
const
String
kScreenshotMethod
=
'_flutter.screenshot'
;
const
String
kRenderFrameWithRasterStatsMethod
=
'_flutter.renderFrameWithRasterStats'
;
const
String
kRenderFrameWithRasterStatsMethod
=
'_flutter.renderFrameWithRasterStats'
;
const
String
kReloadAssetFonts
=
'_flutter.reloadAssetFonts'
;
/// The error response code from an unrecoverable compilation failure.
/// The error response code from an unrecoverable compilation failure.
const
int
kIsolateReloadBarred
=
1005
;
const
int
kIsolateReloadBarred
=
1005
;
...
@@ -880,6 +881,20 @@ class FlutterVmService {
...
@@ -880,6 +881,20 @@ class FlutterVmService {
}
}
}
}
/// Tell the provided flutter view that the font manifest has been updated
/// and asset fonts should be reloaded.
Future
<
void
>
reloadAssetFonts
({
required
String
isolateId
,
required
String
viewId
,
})
async
{
await
callMethodWrapper
(
kReloadAssetFonts
,
isolateId:
isolateId
,
args:
<
String
,
Object
?>{
'viewId'
:
viewId
,
},
);
}
/// Waits for a signal from the VM service that [extensionName] is registered.
/// Waits for a signal from the VM service that [extensionName] is registered.
///
///
/// Looks at the list of loaded extensions for first Flutter view, as well as
/// Looks at the list of loaded extensions for first Flutter view, as well as
...
...
packages/flutter_tools/test/general.shard/devfs_test.dart
View file @
921c8030
...
@@ -643,6 +643,57 @@ void main() {
...
@@ -643,6 +643,57 @@ void main() {
FileSystem:
()
=>
fileSystem
,
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
ProcessManager:
()
=>
processManager
,
});
});
testUsingContext
(
'DevFS tracks when FontManifest is updated'
,
()
async
{
final
FakeVmServiceHost
fakeVmServiceHost
=
FakeVmServiceHost
(
requests:
<
VmServiceExpectation
>[
createDevFSRequest
],
httpAddress:
Uri
.
parse
(
'http://localhost'
),
);
final
BufferLogger
logger
=
BufferLogger
.
test
();
final
DevFS
devFS
=
DevFS
(
fakeVmServiceHost
.
vmService
,
'test'
,
fileSystem
.
currentDirectory
,
fileSystem:
fileSystem
,
logger:
logger
,
osUtils:
FakeOperatingSystemUtils
(),
httpClient:
FakeHttpClient
.
any
(),
);
await
devFS
.
create
();
expect
(
devFS
.
didUpdateFontManifest
,
false
);
final
FakeResidentCompiler
residentCompiler
=
FakeResidentCompiler
()
..
onRecompile
=
(
Uri
mainUri
,
List
<
Uri
>?
invalidatedFiles
)
async
{
fileSystem
.
file
(
'lib/foo.dill'
)
..
createSync
(
recursive:
true
)
..
writeAsBytesSync
(<
int
>[
1
,
2
,
3
,
4
,
5
]);
return
const
CompilerOutput
(
'lib/foo.dill'
,
0
,
<
Uri
>[]);
};
final
FakeBundle
bundle
=
FakeBundle
()
..
entries
[
'FontManifest.json'
]
=
DevFSByteContent
(<
int
>[
1
,
2
,
3
,
4
]);
final
UpdateFSReport
report
=
await
devFS
.
update
(
mainUri:
Uri
.
parse
(
'lib/main.dart'
),
generator:
residentCompiler
,
dillOutputPath:
'lib/foo.dill'
,
pathToReload:
'lib/foo.txt.dill'
,
trackWidgetCreation:
false
,
invalidatedFiles:
<
Uri
>[],
packageConfig:
PackageConfig
.
empty
,
shaderCompiler:
const
FakeShaderCompiler
(),
bundle:
bundle
,
);
expect
(
report
.
success
,
true
);
expect
(
devFS
.
shaderPathsToEvict
,
<
String
>{});
expect
(
devFS
.
assetPathsToEvict
,
<
String
>{
'FontManifest.json'
});
expect
(
devFS
.
didUpdateFontManifest
,
true
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fileSystem
,
ProcessManager:
()
=>
processManager
,
});
});
});
}
}
...
...
packages/flutter_tools/test/general.shard/resident_runner_test.dart
View file @
921c8030
...
@@ -2633,6 +2633,9 @@ class FakeDevFS extends Fake implements DevFS {
...
@@ -2633,6 +2633,9 @@ class FakeDevFS extends Fake implements DevFS {
@override
@override
Set
<
String
>
shaderPathsToEvict
=
<
String
>{};
Set
<
String
>
shaderPathsToEvict
=
<
String
>{};
@override
bool
didUpdateFontManifest
=
false
;
UpdateFSReport
nextUpdateReport
=
UpdateFSReport
(
success:
true
);
UpdateFSReport
nextUpdateReport
=
UpdateFSReport
(
success:
true
);
@override
@override
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment