1// Copyright 2013 The Flutter Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5part of engine; 6 7/// This class downloads assets over the network. 8/// 9/// The assets are resolved relative to [assetsDir]. 10class AssetManager { 11 static const String _defaultAssetsDir = 'assets'; 12 13 /// The directory containing the assets. 14 final String assetsDir; 15 16 const AssetManager({this.assetsDir = _defaultAssetsDir}); 17 18 String getAssetUrl(String asset) { 19 final Uri assetUri = Uri.parse(asset); 20 21 String url; 22 23 if (assetUri.hasScheme) { 24 url = asset; 25 } else { 26 url = '$assetsDir/$asset'; 27 } 28 29 return url; 30 } 31 32 Future<ByteData> load(String asset) async { 33 final String url = getAssetUrl(asset); 34 try { 35 final html.HttpRequest request = 36 await html.HttpRequest.request(url, responseType: 'arraybuffer'); 37 38 final ByteBuffer response = request.response; 39 return response.asByteData(); 40 } on html.ProgressEvent catch (e) { 41 final html.EventTarget target = e.target; 42 if (target is html.HttpRequest) { 43 if (target.status == 404 && asset == 'AssetManifest.json') { 44 html.window.console 45 .warn('Asset manifest does not exist at `$url` – ignoring.'); 46 return Uint8List.fromList(utf8.encode('{}')).buffer.asByteData(); 47 } 48 throw AssetManagerException(url, target.status); 49 } 50 51 rethrow; 52 } 53 } 54} 55 56class AssetManagerException implements Exception { 57 final String url; 58 final int httpStatus; 59 60 AssetManagerException(this.url, this.httpStatus); 61 62 @override 63 String toString() => 'Failed to load asset at "$url" ($httpStatus)'; 64} 65 66/// An asset manager that gives fake empty responses for assets. 67class WebOnlyMockAssetManager implements AssetManager { 68 String defaultAssetsDir = ''; 69 String defaultAssetManifest = '{}'; 70 String defaultFontManifest = '[]'; 71 72 @override 73 String get assetsDir => defaultAssetsDir; 74 75 @override 76 String getAssetUrl(String asset) => '$asset'; 77 78 @override 79 Future<ByteData> load(String asset) { 80 if (asset == getAssetUrl('AssetManifest.json')) { 81 return Future<ByteData>.value( 82 _toByteData(utf8.encode(defaultAssetManifest))); 83 } 84 if (asset == getAssetUrl('FontManifest.json')) { 85 return Future<ByteData>.value( 86 _toByteData(utf8.encode(defaultFontManifest))); 87 } 88 throw AssetManagerException(asset, 404); 89 } 90 91 ByteData _toByteData(List<int> bytes) { 92 final ByteData byteData = ByteData(bytes.length); 93 for (int i = 0; i < bytes.length; i++) { 94 byteData.setUint8(i, bytes[i]); 95 } 96 return byteData; 97 } 98} 99