mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

Dart code now supports the full flow that the C++ code used to: version check, download, replace app bundle. Bonus: the Dart code is much easier to follow, thanks to async/await! This is part 2 of a 3-part change. The first part added new mojom interfaces, PathService and UpdateService, to the sky_services package.
106 lines
3.0 KiB
Dart
106 lines
3.0 KiB
Dart
// Copyright 2015 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.
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:mojo/core.dart';
|
|
import 'package:sky/services.dart';
|
|
import 'package:sky_services/updater/update_service.mojom.dart';
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:yaml/yaml.dart' as yaml;
|
|
|
|
import 'version.dart';
|
|
import 'pipe_to_file.dart';
|
|
|
|
const String kManifestFile = 'sky.yaml';
|
|
const String kBundleFile = 'app.skyx';
|
|
|
|
UpdateServiceProxy _initUpdateService() {
|
|
UpdateServiceProxy updateService = new UpdateServiceProxy.unbound();
|
|
shell.requestService(null, updateService);
|
|
return updateService;
|
|
}
|
|
|
|
final UpdateServiceProxy _updateService = _initUpdateService();
|
|
|
|
String cachedDataDir = null;
|
|
Future<String> getDataDir() async {
|
|
if (cachedDataDir == null)
|
|
cachedDataDir = await getAppDataDir();
|
|
return cachedDataDir;
|
|
}
|
|
|
|
class UpdateTask {
|
|
UpdateTask() {}
|
|
|
|
run() async {
|
|
try {
|
|
await _runImpl();
|
|
} catch(e) {
|
|
print('Update failed: $e');
|
|
} finally {
|
|
_updateService.ptr.notifyUpdateCheckComplete();
|
|
}
|
|
}
|
|
|
|
_runImpl() async {
|
|
_dataDir = await getDataDir();
|
|
|
|
await _readLocalManifest();
|
|
yaml.YamlMap remoteManifest = await _fetchManifest();
|
|
if (!_shouldUpdate(remoteManifest)) {
|
|
print('Update skipped. No new version.');
|
|
return;
|
|
}
|
|
MojoResult result = await _fetchBundle();
|
|
if (!result.isOk) {
|
|
print('Update failed while fetching new skyx bundle.');
|
|
return;
|
|
}
|
|
await _replaceBundle();
|
|
print('Update success.');
|
|
}
|
|
|
|
yaml.YamlMap _currentManifest;
|
|
String _dataDir;
|
|
String _tempPath;
|
|
|
|
_readLocalManifest() async {
|
|
String manifestPath = path.join(_dataDir, kManifestFile);
|
|
String manifestData = await new File(manifestPath).readAsString();
|
|
_currentManifest = yaml.loadYaml(manifestData, sourceUrl: manifestPath);
|
|
}
|
|
|
|
Future<yaml.YamlMap> _fetchManifest() async {
|
|
String manifestUrl = _currentManifest['update_url'] + '/' + kManifestFile;
|
|
String manifestData = await fetchString(manifestUrl);
|
|
return yaml.loadYaml(manifestData, sourceUrl: manifestUrl);
|
|
}
|
|
|
|
bool _shouldUpdate(yaml.YamlMap remoteManifest) {
|
|
Version currentVersion = new Version(_currentManifest['version']);
|
|
Version remoteVersion = new Version(remoteManifest['version']);
|
|
return (currentVersion < remoteVersion);
|
|
}
|
|
|
|
Future<MojoResult> _fetchBundle() async {
|
|
// TODO(mpcomplete): Use the cache dir. We need an equivalent of mkstemp().
|
|
_tempPath = path.join(_dataDir, 'tmp.skyx');
|
|
String bundleUrl = _currentManifest['update_url'] + '/' + kBundleFile;
|
|
UrlResponse response = await fetchUrl(bundleUrl);
|
|
return PipeToFile.copyToFile(response.body, _tempPath);
|
|
}
|
|
|
|
_replaceBundle() async {
|
|
String bundlePath = path.join(_dataDir, kBundleFile);
|
|
await new File(_tempPath).rename(bundlePath);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
var task = new UpdateTask();
|
|
task.run();
|
|
}
|