Reland "[device_settings] Use fuchsia.update.ChannelControl."
This reverts commit 46f29c0284a4c485558d1aafd80bb0810c374a58.
Reason for revert: fxr/329416 fixed the issue with GetCurrent() that
caused this to be reverted.
Bug: 37233
Test: fx run-host-tests device_settings_tests
Change-Id: Ib59a9e19f64eab6fb4256bf8a1293df6eae8ed78
Original change's description:
> Revert "[device_settings] Use fuchsia.update.ChannelControl."
>
> This reverts commit 2b3c02c8763dd6aa677b4f6523a5bf651180b4bf.
>
> Reason for revert: <INSERT REASONING HERE>
>
> Original change's description:
> > [device_settings] Use fuchsia.update.ChannelControl.
> >
> > Bug: 37233
> > Test: fx run-host-tests device_settings_tests
> >
> > Change-Id: Ia050d51a38d7234f59fc016c09b8e67c7cbd5d53
>
> TBR=ejia@google.com,etryzelaar@google.com,aaronwood@google.com,senj@google.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: 37233
> Change-Id: I2d3fca9b8c266f19c5c8ccc0adac49432631743b
TBR=ejia@google.com,etryzelaar@google.com,aaronwood@google.com,senj@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: Ib59a9e19f64eab6fb4256bf8a1293df6eae8ed78
diff --git a/settings/device/BUILD.gn b/settings/device/BUILD.gn
index 2f94679..7044a00 100644
--- a/settings/device/BUILD.gn
+++ b/settings/device/BUILD.gn
@@ -25,10 +25,9 @@
]
deps = [
- "//sdk/fidl/fuchsia.pkg",
- "//sdk/fidl/fuchsia.pkg.rewrite",
"//sdk/fidl/fuchsia.recovery",
"//sdk/fidl/fuchsia.update",
+ "//sdk/fidl/fuchsia.update.channelcontrol",
"//third_party/dart-pkg/git/flutter/packages/flutter",
"//topaz/lib/settings:lib.settings",
"//topaz/public/dart/fuchsia_logger",
diff --git a/settings/device/lib/model.dart b/settings/device/lib/model.dart
index 80e8f56..3ff035a 100644
--- a/settings/device/lib/model.dart
+++ b/settings/device/lib/model.dart
@@ -4,10 +4,9 @@
import 'dart:async';
-import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_update/fidl_async.dart' as update;
-import 'package:fidl_fuchsia_pkg/fidl_async.dart' as pkg;
-import 'package:fidl_fuchsia_pkg_rewrite/fidl_async.dart' as pkg_rewrite;
+import 'package:fidl_fuchsia_update_channelcontrol/fidl_async.dart'
+ as channelcontrol;
import 'package:fidl_fuchsia_recovery/fidl_async.dart' as recovery;
import 'package:flutter/foundation.dart';
import 'package:fuchsia_logger/logger.dart';
@@ -27,14 +26,11 @@
Future<bool> checkForSystemUpdate();
- Stream<pkg.RepositoryConfig> listRepositories();
+ Future<String> getCurrentChannel();
- Stream<pkg_rewrite.Rule> listRules();
+ Future<void> setTargetChannel(String channel);
- Stream<pkg_rewrite.Rule> listStaticRules();
-
- Future<int> updateRules(
- Iterable<pkg_rewrite.Rule> Function(List<pkg_rewrite.Rule>) action);
+ Future<List<String>> getChannelList();
Future<void> factoryReset();
@@ -45,20 +41,16 @@
/// Controller for the update manager service.
final update.ManagerProxy _updateManager = update.ManagerProxy();
- /// Controller for package repo manager and rewrite engine (our update service).
- final pkg.RepositoryManagerProxy _repositoryManager =
- pkg.RepositoryManagerProxy();
- final pkg_rewrite.EngineProxy _rewriteManager = pkg_rewrite.EngineProxy();
+ /// Controller for the update channel control service.
+ final channelcontrol.ChannelControlProxy _channelControl =
+ channelcontrol.ChannelControlProxy();
/// Controller for the factory reset service.
final recovery.FactoryResetProxy _factoryReset = recovery.FactoryResetProxy();
DefaultSystemInterfaceImpl() {
StartupContext.fromStartupInfo().incoming.connectToService(_updateManager);
- StartupContext.fromStartupInfo()
- .incoming
- .connectToService(_repositoryManager);
- StartupContext.fromStartupInfo().incoming.connectToService(_rewriteManager);
+ StartupContext.fromStartupInfo().incoming.connectToService(_channelControl);
}
@override
@@ -74,65 +66,14 @@
}
@override
- Stream<pkg.RepositoryConfig> listRepositories() async* {
- final iter = pkg.RepositoryIteratorProxy();
- await _repositoryManager.list(iter.ctrl.request());
-
- List<pkg.RepositoryConfig> repos;
- do {
- repos = await iter.next();
- for (var repo in repos) {
- yield repo;
- }
- } while (repos.isNotEmpty);
- }
+ Future<String> getCurrentChannel() => _channelControl.getCurrent();
@override
- Stream<pkg_rewrite.Rule> listRules() {
- return _listRules(_rewriteManager.list);
- }
+ Future<void> setTargetChannel(String channel) =>
+ _channelControl.setTarget(channel);
@override
- Stream<pkg_rewrite.Rule> listStaticRules() {
- return _listRules(_rewriteManager.listStatic);
- }
-
- Future<int> editRuleTransaction(
- Future<void> Function(pkg_rewrite.EditTransaction) action) async {
- // In most cases this loop will only run once, but to be safe against
- // other writers we loop a few times.
- for (var i = 0; i < 10; i++) {
- final transaction = pkg_rewrite.EditTransactionProxy();
- await _rewriteManager.startEditTransaction(transaction.ctrl.request());
- await action(transaction);
- final status = await transaction.commit();
- switch (status) {
- case ZX.OK:
- return ZX.OK;
- case ZX.ERR_UNAVAILABLE:
- continue;
- default:
- return status;
- }
- }
- return ZX.ERR_UNAVAILABLE;
- }
-
- @override
- Future<int> updateRules(
- Iterable<pkg_rewrite.Rule> Function(List<pkg_rewrite.Rule>)
- action) async {
- return editRuleTransaction((tx) async {
- final rules = <pkg_rewrite.Rule>[];
- await _listRules(tx.listDynamic).forEach(rules.add);
-
- await tx.resetAll();
-
- for (var rule in action(rules).toList().reversed) {
- await tx.add(rule);
- }
- });
- }
+ Future<List<String>> getChannelList() => _channelControl.getTargetList();
@override
Future<void> factoryReset() async {
@@ -146,8 +87,7 @@
@override
void dispose() {
_updateManager.ctrl.close();
- _repositoryManager.ctrl.close();
- _rewriteManager.ctrl.close();
+ _channelControl.ctrl.close();
_factoryReset.ctrl.close();
}
}
@@ -179,10 +119,6 @@
ValueNotifier<bool> channelPopupShowing = ValueNotifier<bool>(false);
- final List<pkg.RepositoryConfig> _repos = [];
- final List<pkg_rewrite.Rule> _rules = [];
- final List<pkg_rewrite.Rule> _staticRules = [];
-
bool _isChannelUpdating = false;
SystemInterface _sysInterface;
@@ -194,23 +130,13 @@
DateTime get lastUpdate => _lastUpdate;
- List<pkg.RepositoryConfig> get repos => _repos;
+ String _currentChannel;
- List<pkg_rewrite.Rule> get rules => _rules;
+ String get currentChannel => _currentChannel;
- String get currentChannel {
- final rule =
- rules.firstWhere(_ruleIsFuchsiaReplacement, orElse: () => null);
+ List<String> _channels;
- return rule?.literal?.hostReplacement;
- }
-
- String get defaultChannel {
- final rule =
- _staticRules.firstWhere(_ruleIsFuchsiaReplacement, orElse: () => null);
-
- return rule?.literal?.hostReplacement;
- }
+ List<String> get channels => _channels;
/// Determines whether the confirmation dialog for factory reset should
/// be displayed.
@@ -235,54 +161,12 @@
_lastUpdate = DateTime.now();
}
- Future<void> selectChannel(pkg.RepositoryConfig selectedConfig) async {
- log.info('selecting channel ${selectedConfig.repoUrl}');
+ Future<void> selectChannel(String selectedChannel) async {
+ log.info('selecting channel $selectedChannel');
channelPopupShowing.value = false;
_setChannelState(updating: true);
- final repoUrl = Uri.parse(selectedConfig.repoUrl);
- final pkg_rewrite.Rule selectedRule = pkg_rewrite.Rule.withLiteral(
- pkg_rewrite.LiteralRule(
- hostMatch: 'fuchsia.com',
- hostReplacement: repoUrl.host,
- pathPrefixMatch: '/',
- pathPrefixReplacement: '/'));
-
- final status = await _sysInterface.updateRules((rules) sync* {
- // Find the first fuchsia.com rule. If it doesn't exist, add it to the
- // front of the rule set. Otherwise replace it, and filter out any
- // duplicates.
- final index = rules.indexWhere(_ruleIsFuchsiaReplacement);
- if (index == -1) {
- yield selectedRule;
- yield* rules;
- } else {
- yield* rules.getRange(0, index);
- yield selectedRule;
- yield* rules
- .getRange(index + 1, rules.length)
- .where((rule) => !_ruleIsFuchsiaReplacement(rule));
- }
- });
-
- if (status != ZX.OK) {
- log.severe('error while modifying rewrite rules: $status');
- }
-
- await _update();
- }
-
- Future<void> clearChannel() async {
- log.info('clearing channel');
- channelPopupShowing.value = false;
- _setChannelState(updating: true);
-
- final status = await _sysInterface.updateRules(
- (rules) => rules.where((rule) => !_ruleIsFuchsiaReplacement(rule)));
-
- if (status != ZX.OK) {
- log.severe('error while modifying rewrite rules: $status');
- }
+ await _sysInterface.setTargetChannel(selectedChannel);
await _update();
}
@@ -290,14 +174,9 @@
Future<void> _update() async {
_setChannelState(updating: true);
- _repos.clear();
- await _sysInterface.listRepositories().forEach(_repos.add);
+ _currentChannel = await _sysInterface.getCurrentChannel();
- _rules.clear();
- await _sysInterface.listRules().forEach(_rules.add);
-
- _staticRules.clear();
- await _sysInterface.listStaticRules().forEach(_staticRules.add);
+ _channels = await _sysInterface.getChannelList();
_setChannelState(updating: false);
}
@@ -355,24 +234,3 @@
notifyListeners();
}
}
-
-Stream<pkg_rewrite.Rule> _listRules(
- Future<void> Function(InterfaceRequest<pkg_rewrite.RuleIterator>)
- action) async* {
- final iter = pkg_rewrite.RuleIteratorProxy();
- await action(iter.ctrl.request());
-
- List<pkg_rewrite.Rule> rules;
- do {
- rules = await iter.next();
- for (var rule in rules) {
- yield rule;
- }
- } while (rules.isNotEmpty);
-}
-
-bool _ruleIsFuchsiaReplacement(pkg_rewrite.Rule rule) {
- return rule.literal != null &&
- rule.literal.hostMatch == 'fuchsia.com' &&
- rule.literal.pathPrefixMatch == '/';
-}
diff --git a/settings/device/lib/src/widget.dart b/settings/device/lib/src/widget.dart
index 8648844..80fd5c7 100644
--- a/settings/device/lib/src/widget.dart
+++ b/settings/device/lib/src/widget.dart
@@ -109,25 +109,18 @@
widthFactor: 0.8,
heightFactor: 0.8,
child: SingleChildScrollView(
- physics: BouncingScrollPhysics(),
- padding: EdgeInsets.all(16.0),
- child: SettingsSection(
- title: 'Select channel',
- scale: scale,
- child: Column(
- children: model.repos
- .map((repo) => SettingsButton(
- onTap: () => model.selectChannel(repo),
- scale: scale,
- text: '${repo?.repoUrl ?? 'None'}'))
- .toList()
- ..add(SettingsButton(
- onTap: () => model.clearChannel(),
+ physics: BouncingScrollPhysics(),
+ padding: EdgeInsets.all(16.0),
+ child: SettingsSection(
+ title: 'Select channel',
+ scale: scale,
+ child: Column(
+ children: model.channels
+ .map((channel) => SettingsButton(
+ onTap: () => model.selectChannel(channel),
scale: scale,
- text: model.defaultChannel == null
- ? 'None'
- : 'Default (${model.defaultChannel})')))),
- ),
+ text: '$channel'))
+ .toList()))),
)));
}
diff --git a/settings/device/meta/device_settings.cmx b/settings/device/meta/device_settings.cmx
index a6664c9..455735c 100644
--- a/settings/device/meta/device_settings.cmx
+++ b/settings/device/meta/device_settings.cmx
@@ -15,13 +15,12 @@
"fuchsia.fonts.Provider",
"fuchsia.logger.LogSink",
"fuchsia.modular.Clipboard",
- "fuchsia.pkg.RepositoryManager",
- "fuchsia.pkg.rewrite.Engine",
"fuchsia.recovery.FactoryReset",
"fuchsia.sys.Environment",
"fuchsia.ui.input.ImeService",
"fuchsia.ui.policy.Presenter",
"fuchsia.ui.scenic.Scenic",
+ "fuchsia.update.channelcontrol.ChannelControl",
"fuchsia.update.Manager"
]
}
diff --git a/settings/device/test/device_settings_model_test.dart b/settings/device/test/device_settings_model_test.dart
index f4623dc..10499bc 100644
--- a/settings/device/test/device_settings_model_test.dart
+++ b/settings/device/test/device_settings_model_test.dart
@@ -5,10 +5,10 @@
import 'dart:async';
import 'package:device_settings/model.dart';
-import 'package:fidl_fuchsia_pkg/fidl_async.dart' as pkg;
-import 'package:fidl_fuchsia_pkg_rewrite/fidl_async.dart' as pkg_rewrite;
import 'package:fidl_fuchsia_recovery/fidl_async.dart' as recovery;
import 'package:fidl_fuchsia_update/fidl_async.dart' as update;
+import 'package:fidl_fuchsia_update_channelcontrol/fidl_async.dart'
+ as channelcontrol;
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
@@ -22,11 +22,8 @@
class MockUpdateManager extends Mock implements update.Manager {}
-class MockRepositoryManager extends Mock implements pkg.RepositoryManager {}
-
-class MockRewriteManager extends Mock implements pkg_rewrite.Engine {}
-
-class MockRepositoryIterator extends Mock implements pkg.RepositoryIterator {}
+class MockChannelControl extends Mock implements channelcontrol.ChannelControl {
+}
class MockFactoryReset extends Mock implements recovery.FactoryReset {}
@@ -35,41 +32,33 @@
test('test_start', () async {
final TestSystemInterface sysInterface = TestSystemInterface();
- when(sysInterface.listRepositories())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getCurrentChannel()).thenAnswer((_) => Future.value(''));
- when(sysInterface.listRules()).thenAnswer((_) => Stream.fromIterable([]));
-
- when(sysInterface.listStaticRules())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getChannelList()).thenAnswer((_) => Future.value([]));
final DeviceSettingsModel model = DeviceSettingsModel(sysInterface);
await model.start();
// Ensure resolver is interacted with on the first start.
- verify(sysInterface.listRepositories());
- verify(sysInterface.listRules());
- verify(sysInterface.listStaticRules());
+ verify(sysInterface.getCurrentChannel());
+ verify(sysInterface.getChannelList());
// We should not be waiting on anything in the second start as it should be
// an early return.
await model.start();
// Ensure resolver has not been interacted with since the first start.
- verifyNever(sysInterface.listRepositories());
- verifyNever(sysInterface.listRules());
- verifyNever(sysInterface.listStaticRules());
+ verifyNever(sysInterface.getCurrentChannel());
+ verifyNever(sysInterface.getChannelList());
});
// Ensure checkForSystemUpdate has the intended side effects.
test('test_check_for_updates', () async {
final TestSystemInterface sysInterface = TestSystemInterface();
- when(sysInterface.listRepositories())
- .thenAnswer((_) => Stream.fromIterable([]));
- when(sysInterface.listRules()).thenAnswer((_) => Stream.fromIterable([]));
- when(sysInterface.listStaticRules())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getCurrentChannel()).thenAnswer((_) => Future.value(''));
+
+ when(sysInterface.getChannelList()).thenAnswer((_) => Future.value([]));
when(sysInterface.checkForSystemUpdate())
.thenAnswer((_) => Future.value(true));
@@ -94,25 +83,14 @@
test('test_channel_updating_state', () async {
final TestSystemInterface sysInterface = TestSystemInterface();
- var repoCompleter = Completer();
- var ruleCompleter = Completer();
- var staticRuleCompleter = Completer();
+ var currentChannelCompleter = Completer<String>();
+ var channelListCompleter = Completer<List<String>>();
- when(sysInterface.listRepositories()).thenAnswer((_) async* {
- for (var repo in await repoCompleter.future) {
- yield repo;
- }
- });
- when(sysInterface.listRules()).thenAnswer((_) async* {
- for (var rule in await ruleCompleter.future) {
- yield rule;
- }
- });
- when(sysInterface.listStaticRules()).thenAnswer((_) async* {
- for (var rule in await staticRuleCompleter.future) {
- yield rule;
- }
- });
+ when(sysInterface.getCurrentChannel())
+ .thenAnswer((_) => currentChannelCompleter.future);
+
+ when(sysInterface.getChannelList())
+ .thenAnswer((_) => channelListCompleter.future);
final DeviceSettingsModel model = DeviceSettingsModel(sysInterface);
final Future startFuture = model.start();
@@ -120,28 +98,22 @@
// On start, the model should report it is updating as the proxy has not
// returned
expect(model.channelUpdating, true);
- repoCompleter.complete([]);
- ruleCompleter.complete([]);
- staticRuleCompleter.complete([]);
+ currentChannelCompleter.complete('');
+ channelListCompleter.complete([]);
await startFuture;
expect(model.channelUpdating, false);
// Reset update completer so it can be used in the next step.
- repoCompleter = Completer();
- ruleCompleter = Completer();
- staticRuleCompleter = Completer();
+ currentChannelCompleter = Completer<String>();
+ channelListCompleter = Completer<List<String>>();
- when(sysInterface.updateRules(any)).thenAnswer((_) async {
- return 0;
- });
+ when(sysInterface.setTargetChannel(any)).thenAnswer((_) async {});
// make sure we are also updating when selecting a channel.
- Future selectFuture = model.selectChannel(
- pkg.RepositoryConfig(repoUrl: 'fuchsia-pkg://example.com'));
+ Future selectFuture = model.selectChannel('stable');
expect(model.channelUpdating, true);
- repoCompleter.complete([]);
- ruleCompleter.complete([]);
- staticRuleCompleter.complete([]);
+ currentChannelCompleter.complete('');
+ channelListCompleter.complete([]);
await selectFuture;
expect(model.channelUpdating, false);
});
@@ -150,13 +122,9 @@
test('test_check_for_factory_reset', () async {
final TestSystemInterface sysInterface = TestSystemInterface();
- when(sysInterface.listRepositories())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getCurrentChannel()).thenAnswer((_) => Future.value(''));
- when(sysInterface.listRules()).thenAnswer((_) => Stream.fromIterable([]));
-
- when(sysInterface.listStaticRules())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getChannelList()).thenAnswer((_) => Future.value([]));
final DeviceSettingsModel model = DeviceSettingsModel(sysInterface);
await model.start();
@@ -179,13 +147,9 @@
test('test_check_for_factory_reset', () async {
final TestSystemInterface sysInterface = TestSystemInterface();
- when(sysInterface.listRepositories())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getCurrentChannel()).thenAnswer((_) => Future.value(''));
- when(sysInterface.listRules()).thenAnswer((_) => Stream.fromIterable([]));
-
- when(sysInterface.listStaticRules())
- .thenAnswer((_) => Stream.fromIterable([]));
+ when(sysInterface.getChannelList()).thenAnswer((_) => Future.value([]));
final DeviceSettingsModel model = DeviceSettingsModel(sysInterface);
await model.start();