blob: e0fc6e5727a37160bffe91459598dbfd52f1f4b0 [file] [log] [blame]
// Copyright 2021 The Fuchsia 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 'package:fidl_fuchsia_memory/fidl_async.dart';
import 'package:fidl_fuchsia_session/fidl_async.dart' as session;
import 'package:fidl_fuchsia_ui_remotewidgets/fidl_async.dart';
import 'package:flutter/material.dart';
import 'package:fuchsia_logger/logger.dart';
import 'package:fuchsia_services/services.dart' show Incoming;
import 'package:internationalization/strings.dart';
import 'package:quickui/quickui.dart';
import 'memory.dart' as memory;
const licenseUrl =
'fuchsia-pkg://fuchsia.com/license_settings#meta/license_settings.cmx';
const feedbackUrl =
'fuchsia-pkg://fuchsia.com/feedback_settings#meta/feedback_settings.cmx';
// ignore_for_file: prefer_constructors_over_static_methods
/// Defines a [UiSpec] for displaying system information.
class SystemInformation extends UiSpec {
// Localized strings.
static String get _title => Strings.systemInformation;
static String get _memory => Strings.memory;
static String get _view => Strings.view;
static String get _loading => Strings.loading;
static String get _feedback => Strings.feedback;
static String get _openSource => Strings.openSource;
static String get _license => Strings.license;
// Icon for system information title.
static IconValue get _icon =>
IconValue(codePoint: Icons.info_outlined.codePoint);
// Action to launch license.
static int changeAction = QuickAction.details.$value;
// Memory model and variables
late memory.MemoryModel memoryModel;
late String usedMemory;
late String totalMemory;
SystemInformation({required Monitor monitor, WatcherBinding? binding}) {
memoryModel = memory.MemoryModel(
monitor: monitor, binding: binding, onChange: _onChangeMemory);
_onChange();
}
factory SystemInformation.withSvcPath() {
final monitor = MonitorProxy();
Incoming.fromSvcPath().connectToService(monitor);
return SystemInformation(monitor: monitor);
}
void _onChange() async {
spec = await _specForSystemInformation();
}
void _onChangeMemory() async {
usedMemory = (memoryModel.memUsed).toStringAsPrecision(3);
totalMemory = (memoryModel.memTotal).toStringAsPrecision(3);
}
@override
void update(Value value) async {
if (value.$tag == ValueTag.button &&
value.button!.action == QuickAction.cancel.$value) {
spec = await _specForSystemInformation();
} else if (value.$tag == ValueTag.text && value.text!.action > 0) {
if (value.text!.action == changeAction) {
spec = await _specForSystemInformation(changeAction);
} else {
final index = value.text!.action ^ QuickAction.submit.$value;
if (index == 1) {
await launchUrl(feedbackUrl);
}
if (index == 2) {
await launchUrl(licenseUrl);
}
spec = await _specForSystemInformation();
}
}
}
@override
void dispose() {
memoryModel.dispose();
}
Future<void> launchUrl(String url) async {
final proxy = session.ElementManagerProxy();
final elementController = session.ElementControllerProxy();
final incoming = Incoming.fromSvcPath()..connectToService(proxy);
final spec = session.ElementSpec(componentUrl: url);
await proxy
.proposeElement(spec, elementController.ctrl.request())
.catchError((err) {
log.shout('$err: Failed to propose element <$url>');
});
proxy.ctrl.close();
await incoming.close();
}
Future<Spec> _specForSystemInformation([int action = 0]) async {
if (action == 0 || action & QuickAction.cancel.$value > 0) {
return Spec(title: _title, groups: [
Group(title: _title, icon: _icon, values: [
Value.withText(TextValue(
text: _view,
action: changeAction,
)),
Value.withIcon(IconValue(
codePoint: Icons.arrow_right.codePoint,
action: changeAction,
)),
]),
]);
} else if (action == changeAction) {
return Spec(title: _title, groups: [
Group(title: '', values: [
Value.withGrid(GridValue(
columns: 2,
values: [
TextValue(text: '${_memory.toUpperCase()}'),
TextValue(text: '${usedMemory}GB / ${totalMemory}GB'),
TextValue(text: '${_feedback.toUpperCase()}'),
TextValue(
text: '${_view.toUpperCase()}',
action: QuickAction.submit.$value | 1,
),
TextValue(
text: '${_openSource.toUpperCase()} ${_license.toUpperCase()}',
),
TextValue(
text: '${_view.toUpperCase()}',
action: QuickAction.submit.$value | 2,
)
],
)),
]),
]);
} else {
return Spec(title: _title, groups: [
Group(title: _title, values: [
Value.withText(TextValue(text: '$_loading...')),
]),
]);
}
}
}