blob: 9acebbc6afdb2df7507988b4d842f7174ce15287 [file] [log] [blame]
// Copyright 2018 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/fidl.dart';
import 'package:fidl_fuchsia_device_display/fidl.dart';
import 'package:fidl_fuchsia_devicesettings/fidl.dart';
import 'package:fidl_fuchsia_sys/fidl.dart';
import 'package:lib.app.dart/app.dart';
import 'package:lib.app.dart/logging.dart';
/// This class abstracts away the fuchsia.device.display.Manager fidl interface,
class Display extends DeviceSettingsWatcher {
final DeviceSettingsWatcherBinding _deviceSettingsWatcherBinding =
DeviceSettingsWatcherBinding();
final String _brightnessSettingsKey = 'Display.Brightness';
// Used to publish brightness events.
final StreamController<double> _brightnessStreamController =
StreamController.broadcast();
// Used to modify the physical display.
final ManagerProxy _displayManagerService = ManagerProxy();
// Used to store and retrieve user settings.
final DeviceSettingsManagerProxy _deviceSettingsManagerService =
DeviceSettingsManagerProxy();
double _brightness;
// ignore: public_member_api_docs
Display(ServiceProvider services) {
connectToService(services, _displayManagerService.ctrl);
_displayManagerService.ctrl.onConnectionError =
_handleDisplayConnectionError;
_displayManagerService.ctrl.error.then(
(ProxyError error) => _handleDisplayConnectionError(error: error));
connectToService(services, _deviceSettingsManagerService.ctrl);
_deviceSettingsManagerService.ctrl.onConnectionError =
_handleSettingsConnectionError;
_deviceSettingsManagerService.ctrl.error.then(
(ProxyError error) => _handleSettingsConnectionError(error: error));
_deviceSettingsManagerService.watch(
_brightnessSettingsKey, _deviceSettingsWatcherBinding.wrap(this), null);
// Immediately get brightness on construction.
_refreshBrightness();
}
/// Invoked during creation to refresh the internal cached brightness.
void _refreshBrightness([bool force = false]) {
if (brightness != null && !force) {
return;
}
_deviceSettingsManagerService.getString(_brightnessSettingsKey,
(String val, Status status) {
if (status == Status.ok) {
if (val == null || val.isEmpty) {
return;
}
// If previous value exists, restore brightness.
setBrightness(double.parse(val));
} else {
// If no previous value is found, fetch display brightness and set.
// Setting is a noop from the device side, but makes sure our locale
// cache is updated.
_displayManagerService.getBrightness((bool success, double brightness) {
if (success) {
setBrightness(brightness);
}
});
}
});
}
// ignore: public_member_api_docs
void addListener(void onEvent(double brightness)) {
_brightnessStreamController.stream.listen(onEvent);
}
// Cache the brightness so callers can retrieve it without reading the
// device settings or display.
// ignore: public_member_api_docs
double get brightness => _brightness;
/// Sets the brightness to the specified percentage. If specified, the
/// callback will be invoked with the updated backlight brightness value.
Future<bool> setBrightness(double brightness) {
var completer = Completer<bool>();
if (_brightness == brightness || brightness < 0 || brightness > 1) {
completer.complete(false);
return completer.future;
}
_displayManagerService.setBrightness(brightness, (bool success) {
if (success) {
_brightness = brightness;
_deviceSettingsManagerService.setString(
_brightnessSettingsKey, brightness.toString(), (bool result) {
// This is a silent failure. While we couldn't store the brightness,
// it still took effect on the physical display.
if (!result) {
log.warning('Could not persist display brightness');
}
});
_notifyBrightnessChange();
completer.complete(true);
} else {
_displayManagerService
.getBrightness((bool success, double brightnessVal) {
if (success) {
_brightness = brightnessVal;
_notifyBrightnessChange();
}
completer.complete(false);
});
}
});
return completer.future;
}
/// Invoked internally to signal to a registered listener (if set) of a
/// change in brightness.
void _notifyBrightnessChange() {
_brightnessStreamController.add(brightness);
}
/// Handles connection error to the display service.
void _handleDisplayConnectionError({ProxyError error}) {
log.severe('Unable to connect to display service', error);
}
/// Handles connection error to the settings service.
void _handleSettingsConnectionError({ProxyError error}) {
log.severe('Unable to connect to settings service', error);
}
@override
void onChangeSettings(ValueType type) {
_refreshBrightness(true);
}
}