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
beb8afa4
Commit
beb8afa4
authored
Oct 20, 2016
by
Adam Barth
Committed by
GitHub
Oct 20, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch to the assets plugin (#6408)
This patch removes our dependency on asset_bundle.mojom.
parent
32e95cc6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
94 additions
and
171 deletions
+94
-171
example_code_parser_test.dart
examples/flutter_gallery/test/example_code_parser_test.dart
+2
-2
asset_bundle.dart
packages/flutter/lib/src/services/asset_bundle.dart
+13
-52
image_provider.dart
packages/flutter/lib/src/services/image_provider.dart
+60
-101
image_resolution_test.dart
packages/flutter/test/widget/image_resolution_test.dart
+19
-16
No files found.
examples/flutter_gallery/test/example_code_parser_test.dart
View file @
beb8afa4
...
...
@@ -3,10 +3,10 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:typed_data'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_gallery/gallery/example_code_parser.dart'
;
import
'package:mojo/core.dart'
as
core
;
import
'package:test/test.dart'
;
void
main
(
)
{
...
...
@@ -36,7 +36,7 @@ test 1 1
class
TestAssetBundle
extends
AssetBundle
{
@override
Future
<
core
.
MojoDataPipeConsumer
>
load
(
String
key
)
=>
null
;
Future
<
ByteData
>
load
(
String
key
)
=>
null
;
@override
Future
<
String
>
loadString
(
String
key
,
{
bool
cache:
true
})
{
...
...
packages/flutter/lib/src/services/asset_bundle.dart
View file @
beb8afa4
...
...
@@ -4,14 +4,12 @@
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:io'
;
import
'dart:ui'
as
ui
;
import
'dart:typed_data'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/http.dart'
as
http
;
import
'package:mojo/core.dart'
as
core
;
import
'p
ackage:flutter_services/mojo/asset_bundle/asset_bundle.dart'
as
mojom
;
import
'p
latform_messages.dart'
;
/// A collection of resources used by the application.
///
...
...
@@ -42,7 +40,7 @@ import 'package:flutter_services/mojo/asset_bundle/asset_bundle.dart' as mojom;
/// * [rootBundle]
abstract
class
AssetBundle
{
/// Retrieve a binary resource from the asset bundle as a data stream.
Future
<
core
.
MojoDataPipeConsumer
>
load
(
String
key
);
Future
<
ByteData
>
load
(
String
key
);
/// Retrieve a string from the asset bundle.
///
...
...
@@ -83,13 +81,11 @@ class NetworkAssetBundle extends AssetBundle {
String
_urlFromKey
(
String
key
)
=>
_baseUrl
.
resolve
(
key
).
toString
();
@override
Future
<
core
.
MojoDataPipeConsumer
>
load
(
String
key
)
async
{
Future
<
ByteData
>
load
(
String
key
)
async
{
http
.
Response
response
=
await
http
.
get
(
_urlFromKey
(
key
));
if
(
response
.
statusCode
==
200
)
return
null
;
core
.
MojoDataPipe
pipe
=
new
core
.
MojoDataPipe
();
core
.
DataPipeFiller
.
fillHandle
(
pipe
.
producer
,
response
.
bodyBytes
.
buffer
.
asByteData
());
return
pipe
.
consumer
;
return
response
.
bodyBytes
.
buffer
.
asByteData
();
}
@override
...
...
@@ -138,9 +134,8 @@ abstract class CachingAssetBundle extends AssetBundle {
}
Future
<
String
>
_fetchString
(
String
key
)
async
{
final
core
.
MojoDataPipeConsumer
pipe
=
await
load
(
key
);
final
ByteData
data
=
await
core
.
DataPipeDrainer
.
drainHandle
(
pipe
);
return
UTF8
.
decode
(
new
Uint8List
.
view
(
data
.
buffer
));
final
ByteData
data
=
await
load
(
key
);
return
UTF8
.
decode
(
data
.
buffer
.
asUint8List
());
}
/// Retrieve a string from the asset bundle, parse it with the given function,
...
...
@@ -190,47 +185,17 @@ abstract class CachingAssetBundle extends AssetBundle {
}
}
/// An [AssetBundle] that loads resources from a Mojo service.
class
MojoAssetBundle
extends
CachingAssetBundle
{
/// Creates an [AssetBundle] interface around the given [mojom.AssetBundleProxy] Mojo service.
MojoAssetBundle
(
this
.
_bundle
);
mojom
.
AssetBundleProxy
_bundle
;
/// An [AssetBundle] that loads resources using platform messages.
class
PlatformAssetBundle
extends
CachingAssetBundle
{
@override
Future
<
core
.
MojoDataPipeConsumer
>
load
(
String
key
)
{
Completer
<
core
.
MojoDataPipeConsumer
>
completer
=
new
Completer
<
core
.
MojoDataPipeConsumer
>();
_bundle
.
getAsStream
(
key
,
(
core
.
MojoDataPipeConsumer
assetData
)
{
completer
.
complete
(
assetData
);
});
return
completer
.
future
;
Future
<
ByteData
>
load
(
String
key
)
{
Uint8List
encoded
=
UTF8
.
encoder
.
convert
(
key
);
return
PlatformMessages
.
sendBinary
(
'flutter/assets'
,
encoded
.
buffer
.
asByteData
());
}
}
AssetBundle
_initRootBundle
(
)
{
int
h
=
ui
.
MojoServices
.
takeRootBundle
();
if
(
h
==
core
.
MojoHandle
.
INVALID
)
{
assert
(()
{
if
(!
Platform
.
environment
.
containsKey
(
'FLUTTER_TEST'
))
{
FlutterError
.
reportError
(
new
FlutterErrorDetails
(
exception:
'dart:ui MojoServices.takeRootBundle() returned an invalid handle.
\n
'
'This might happen if the Dart VM was restarted without restarting the underlying Flutter engine, '
'or if the Flutter framework
\'
s rootBundle object was first accessed after some other code called '
'takeRootBundle. The root bundle handle can only be obtained once in the lifetime of the Flutter '
'engine. Mojo handles cannot be shared.
\n
'
'The rootBundle object will be initialised with a NetworkAssetBundle instead of a MojoAssetBundle. '
'This may cause subsequent network errors.'
,
library
:
'services library'
,
context:
'while initialising the root bundle'
));
}
return
true
;
});
return
new
NetworkAssetBundle
(
Uri
.
base
);
}
core
.
MojoHandle
handle
=
new
core
.
MojoHandle
(
h
);
return
new
MojoAssetBundle
(
new
mojom
.
AssetBundleProxy
.
fromHandle
(
handle
));
return
new
PlatformAssetBundle
();
}
/// The [AssetBundle] from which this application was loaded.
...
...
@@ -248,10 +213,6 @@ AssetBundle _initRootBundle() {
/// convenience, the [WidgetsApp] or [MaterialApp] widget at the top of the
/// widget hierarchy configures the [DefaultAssetBundle] to be the [rootBundle].
///
/// In normal operation, the [rootBundle] is a [MojoAssetBundle], though it can
/// also end up being a [NetworkAssetBundle] in some cases (e.g. if the
/// application's resources are being served from a local HTTP server).
///
/// See also:
///
/// * [DefaultAssetBundle]
...
...
packages/flutter/lib/src/services/image_provider.dart
View file @
beb8afa4
...
...
@@ -10,7 +10,6 @@ import 'dart:typed_data';
import
'package:flutter/foundation.dart'
;
import
'package:flutter/http.dart'
as
http
;
import
'package:meta/meta.dart'
;
import
'package:mojo/core.dart'
as
mojo
;
import
'asset_bundle.dart'
;
import
'image_cache.dart'
;
...
...
@@ -209,26 +208,62 @@ abstract class ImageProvider<T> {
String
toString
()
=>
'
$runtimeType
()'
;
}
/// A subclass of [ImageProvider] that knows how to invoke
/// [decodeImageFromDataPipe].
/// Key for the image obtained by an [AssetImage] or [ExactAssetImage].
///
/// This factors out the common logic of many [ImageProvider] classes,
/// simplifying what subclasses must implement to just three small methods:
/// This is used to identify the precise resource in the [imageCache].
class
AssetBundleImageKey
{
/// Creates the key for an [AssetImage] or [AssetBundleImageProvider].
///
/// The arguments must not be null.
const
AssetBundleImageKey
({
@required
this
.
bundle
,
@required
this
.
name
,
@required
this
.
scale
});
/// The bundle from which the image will be obtained.
///
/// The image is obtained by calling [AssetBundle.load] on the given [bundle]
/// using the key given by [name].
final
AssetBundle
bundle
;
/// The key to use to obtain the resource from the [bundle]. This is the
/// argument passed to [AssetBundle.load].
final
String
name
;
/// The scale to place in the [ImageInfo] object of the image.
final
double
scale
;
@override
bool
operator
==(
dynamic
other
)
{
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
final
AssetBundleImageKey
typedOther
=
other
;
return
bundle
==
typedOther
.
bundle
&&
name
==
typedOther
.
name
&&
scale
==
typedOther
.
scale
;
}
@override
int
get
hashCode
=>
hashValues
(
bundle
,
name
,
scale
);
@override
String
toString
()
=>
'
$runtimeType
(bundle:
$bundle
, name:
$name
, scale:
$scale
)'
;
}
/// A subclass of [ImageProvider] that knows about [AssetBundle]s.
///
/// * [obtainKey], to resolve an [ImageConfiguration].
/// * [getScale], to determine the scale of the image associated with a
/// particular key.
/// * [loadDataPipe], to obtain the [mojo.MojoDataPipeConsumer] object that
/// contains the actual image data.
abstract
class
DataPipeImageProvider
<
T
>
extends
ImageProvider
<
T
>
{
/// This factors out the common logic of [AssetBundle]-based [ImageProvider]
/// classes, simplifying what subclasses must implement to just [obtainKey].
abstract
class
AssetBundleImageProvider
extends
ImageProvider
<
AssetBundleImageKey
>
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
DataPip
eImageProvider
();
const
AssetBundl
eImageProvider
();
/// Converts a key into an [ImageStreamCompleter], and begins fetching the
/// image using [loadAsync].
@override
ImageStreamCompleter
load
(
T
key
)
{
ImageStreamCompleter
load
(
AssetBundleImageKey
key
)
{
return
new
OneFrameImageStreamCompleter
(
loadAsync
(
key
),
informationCollector:
(
StringBuffer
information
)
{
...
...
@@ -238,39 +273,29 @@ abstract class DataPipeImageProvider<T> extends ImageProvider<T> {
);
}
/// Fetches the image from the
data pip
e, decodes it, and returns a
/// Fetches the image from the
asset bundl
e, decodes it, and returns a
/// corresponding [ImageInfo] object.
///
/// This function is used by [load].
@protected
Future
<
ImageInfo
>
loadAsync
(
T
key
)
async
{
final
mojo
.
MojoDataPipeConsumer
dataPipe
=
await
loadDataPipe
(
key
);
if
(
data
Pipe
==
null
)
Future
<
ImageInfo
>
loadAsync
(
AssetBundleImageKey
key
)
async
{
final
ByteData
data
=
await
key
.
bundle
.
load
(
key
.
name
);
if
(
data
==
null
)
throw
'Unable to read data'
;
final
ui
.
Image
image
=
await
decodeImage
(
data
Pipe
);
final
ui
.
Image
image
=
await
decodeImage
(
data
);
if
(
image
==
null
)
throw
'Unable to decode image data'
;
return
new
ImageInfo
(
image:
image
,
scale:
getScale
(
key
)
);
return
new
ImageInfo
(
image:
image
,
scale:
key
.
scale
);
}
/// Converts raw image data from a [
mojo.MojoDataPipeConsumer] data pipe into
///
a decoded
[ui.Image] which can be passed to a [Canvas].
/// Converts raw image data from a [
ByteData] buffer into a decoded
/// [ui.Image] which can be passed to a [Canvas].
///
/// By default, this just uses [decodeImageFrom
DataPipe
]. This method could be
/// By default, this just uses [decodeImageFrom
List
]. This method could be
/// overridden in subclasses (e.g. for testing).
Future
<
ui
.
Image
>
decodeImage
(
mojo
.
MojoDataPipeConsumer
pipe
)
=>
decodeImageFromDataPipe
(
pipe
);
/// Returns the data pipe that contains the image data to decode.
///
/// Must be implemented by subclasses of [DataPipeImageProvider].
@protected
Future
<
mojo
.
MojoDataPipeConsumer
>
loadDataPipe
(
T
key
);
/// Returns the scale to use when creating the [ImageInfo] for the given key.
///
/// Must be implemented by subclasses of [DataPipeImageProvider].
@protected
double
getScale
(
T
key
);
Future
<
ui
.
Image
>
decodeImage
(
ByteData
data
)
{
return
decodeImageFromList
(
data
.
buffer
.
asUint8List
());
}
}
/// Fetches the given URL from the network, associating it with the given scale.
...
...
@@ -345,72 +370,6 @@ class NetworkImage extends ImageProvider<NetworkImage> {
String
toString
()
=>
'
$runtimeType
("
$url
", scale:
$scale
)'
;
}
/// Key for the image obtained by an [AssetImage] or [AssetBundleImageProvider].
///
/// This is used to identify the precise resource in the [imageCache].
class
AssetBundleImageKey
{
/// Creates the key for an [AssetImage] or [AssetBundleImageProvider].
///
/// The arguments must not be null.
const
AssetBundleImageKey
({
@required
this
.
bundle
,
@required
this
.
name
,
@required
this
.
scale
});
/// The bundle from which the image will be obtained.
///
/// The image is obtained by calling [AssetBundle.load] on the given [bundle]
/// using the key given by [name].
final
AssetBundle
bundle
;
/// The key to use to obtain the resource from the [bundle]. This is the
/// argument passed to [AssetBundle.load].
final
String
name
;
/// The scale to place in the [ImageInfo] object of the image.
final
double
scale
;
@override
bool
operator
==(
dynamic
other
)
{
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
final
AssetBundleImageKey
typedOther
=
other
;
return
bundle
==
typedOther
.
bundle
&&
name
==
typedOther
.
name
&&
scale
==
typedOther
.
scale
;
}
@override
int
get
hashCode
=>
hashValues
(
bundle
,
name
,
scale
);
@override
String
toString
()
=>
'
$runtimeType
(bundle:
$bundle
, name:
$name
, scale:
$scale
)'
;
}
/// A subclass of [DataPipeImageProvider] that knows about [AssetBundle]s.
///
/// This factors out the common logic of [AssetBundle]-based [ImageProvider]
/// classes, simplifying what subclasses must implement to just [obtainKey].
abstract
class
AssetBundleImageProvider
extends
DataPipeImageProvider
<
AssetBundleImageKey
>
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
AssetBundleImageProvider
();
@override
Future
<
AssetBundleImageKey
>
obtainKey
(
ImageConfiguration
configuration
);
@override
Future
<
mojo
.
MojoDataPipeConsumer
>
loadDataPipe
(
AssetBundleImageKey
key
)
{
return
key
.
bundle
.
load
(
key
.
name
);
}
@override
double
getScale
(
AssetBundleImageKey
key
)
{
return
key
.
scale
;
}
}
/// Fetches an image from an [AssetBundle], associating it with the given scale.
///
/// This implementation requires an explicit final [name] and [scale] on
...
...
packages/flutter/test/widget/image_resolution_test.dart
View file @
beb8afa4
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
show
Image
;
import
'package:flutter/rendering.dart'
;
...
...
@@ -10,7 +11,6 @@ import 'package:flutter/services.dart';
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:meta/meta.dart'
;
import
'package:mojo/core.dart'
as
mojo
;
class
TestImage
extends
ui
.
Image
{
TestImage
(
this
.
scale
);
...
...
@@ -26,9 +26,12 @@ class TestImage extends ui.Image {
void
dispose
()
{
}
}
class
Test
MojoDataPipeConsumer
extends
mojo
.
MojoDataPipeConsumer
{
Test
MojoDataPipeConsumer
(
this
.
scale
)
:
super
(
null
);
class
Test
ByteData
implements
ByteData
{
Test
ByteData
(
this
.
scale
);
final
double
scale
;
@override
dynamic
noSuchMethod
(
Invocation
invocation
)
=>
null
;
}
String
testManifest
=
'''
...
...
@@ -44,26 +47,26 @@ String testManifest = '''
class
TestAssetBundle
extends
CachingAssetBundle
{
@override
Future
<
mojo
.
MojoDataPipeConsumer
>
load
(
String
key
)
{
mojo
.
MojoDataPipeConsumer
pipe
;
Future
<
ByteData
>
load
(
String
key
)
{
ByteData
data
;
switch
(
key
)
{
case
'assets/image.png'
:
pipe
=
new
TestMojoDataPipeConsumer
(
1.0
);
data
=
new
TestByteData
(
1.0
);
break
;
case
'assets/1.5x/image.png'
:
pipe
=
new
TestMojoDataPipeConsumer
(
1.5
);
data
=
new
TestByteData
(
1.5
);
break
;
case
'assets/2.0x/image.png'
:
pipe
=
new
TestMojoDataPipeConsumer
(
2.0
);
data
=
new
TestByteData
(
2.0
);
break
;
case
'assets/3.0x/image.png'
:
pipe
=
new
TestMojoDataPipeConsumer
(
3.0
);
data
=
new
TestByteData
(
3.0
);
break
;
case
'assets/4.0x/image.png'
:
pipe
=
new
TestMojoDataPipeConsumer
(
4.0
);
data
=
new
TestByteData
(
4.0
);
break
;
}
return
new
SynchronousFuture
<
mojo
.
MojoDataPipeConsumer
>(
pipe
);
return
new
SynchronousFuture
<
ByteData
>(
data
);
}
@override
...
...
@@ -83,9 +86,9 @@ class TestAssetImage extends AssetImage {
@override
Future
<
ImageInfo
>
loadAsync
(
AssetBundleImageKey
key
)
{
ImageInfo
result
;
key
.
bundle
.
load
(
key
.
name
).
then
((
mojo
.
MojoDataPipeConsumer
dataPipe
)
{
decodeImage
(
data
Pipe
).
then
((
ui
.
Image
image
)
{
result
=
new
ImageInfo
(
image:
image
,
scale:
getScale
(
key
)
);
key
.
bundle
.
load
(
key
.
name
).
then
((
ByteData
data
)
{
decodeImage
(
data
).
then
((
ui
.
Image
image
)
{
result
=
new
ImageInfo
(
image:
image
,
scale:
key
.
scale
);
});
});
assert
(
result
!=
null
);
...
...
@@ -93,8 +96,8 @@ class TestAssetImage extends AssetImage {
}
@override
Future
<
ui
.
Image
>
decodeImage
(
@checked
Test
MojoDataPipeConsumer
pipe
)
{
return
new
SynchronousFuture
<
ui
.
Image
>(
new
TestImage
(
pipe
.
scale
));
Future
<
ui
.
Image
>
decodeImage
(
@checked
Test
ByteData
data
)
{
return
new
SynchronousFuture
<
ui
.
Image
>(
new
TestImage
(
data
.
scale
));
}
}
...
...
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