Skip to content

Commit 1faa314

Browse files
committed
Update accessibility_controller.dart
1
1 parent ee63060 commit 1faa314

4 files changed

Lines changed: 82 additions & 2 deletions

File tree

packages/devtools_app/lib/src/screens/accessibility/accessibility_controller.dart

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
44

5+
import 'dart:async';
6+
7+
import 'package:devtools_app_shared/service.dart';
58
import 'package:devtools_app_shared/utils.dart';
69
import 'package:flutter/foundation.dart';
710

11+
import '../../service/service_extensions.dart' as extensions;
812
import '../../shared/framework/screen.dart';
913
import '../../shared/framework/screen_controllers.dart';
14+
import '../../shared/globals.dart';
1015

1116
/// Modes for brightness override in the accessibility controls.
1217
enum BrightnessOverride {
@@ -26,6 +31,12 @@ class AccessibilityController extends DevToolsScreenController
2631
_initListeners();
2732
}
2833

34+
@override
35+
void init() {
36+
super.init();
37+
_initServiceExtensionStates();
38+
}
39+
2940
void _initListeners() {
3041
addAutoDisposeListener(brightness, _onBrightnessChanged);
3142
addAutoDisposeListener(textScale, _onTextScaleChanged);
@@ -34,9 +45,52 @@ class AccessibilityController extends DevToolsScreenController
3445
addAutoDisposeListener(highContrast, _onHighContrastChanged);
3546
}
3647

48+
void _initServiceExtensionStates() {
49+
final state = serviceConnection.serviceManager.serviceExtensionManager
50+
.getServiceExtensionState(extensions.brightnessMode.extension);
51+
52+
void updateFromDeviceState(ServiceExtensionState s) {
53+
final newBrightness = !s.enabled || s.value == null
54+
? BrightnessOverride.system
55+
: switch (s.value) {
56+
'Brightness.light' => BrightnessOverride.light,
57+
'Brightness.dark' => BrightnessOverride.dark,
58+
_ => BrightnessOverride.system,
59+
};
60+
if (brightness.value != newBrightness) {
61+
brightness.value = newBrightness;
62+
}
63+
}
64+
65+
updateFromDeviceState(state.value);
66+
addAutoDisposeListener(
67+
state,
68+
() => updateFromDeviceState(state.value),
69+
);
70+
}
71+
72+
73+
3774
void _onBrightnessChanged() {
38-
// TODO(hannah-hyj): Implement VM service extension call for brightness override.
39-
// e.g. using 'ext.flutter.brightnessOverride'.
75+
final value = brightness.value;
76+
// Values expected by Flutter framework's 'ext.flutter.brightnessOverride':
77+
// - 'Brightness.light': forces light mode
78+
// - 'Brightness.dark': forces dark mode
79+
// - '': any value other than 'Brightness.light' or 'Brightness.dark' clears
80+
// the override and resets to system default.
81+
final paramValue = switch (value) {
82+
BrightnessOverride.light => 'Brightness.light',
83+
BrightnessOverride.dark => 'Brightness.dark',
84+
BrightnessOverride.system => '',
85+
};
86+
unawaited(
87+
serviceConnection.serviceManager.serviceExtensionManager
88+
.setServiceExtensionState(
89+
extensions.brightnessMode.extension,
90+
enabled: value != BrightnessOverride.system,
91+
value: paramValue,
92+
),
93+
);
4094
}
4195

4296
void _onTextScaleChanged() {

packages/devtools_app/lib/src/service/service_extensions.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,21 @@ final togglePlatformMode = ServiceExtensionDescription<String>.from(
379379
tooltip: 'Override Target Platform',
380380
);
381381

382+
/// Service extension description for overriding brightness in accessibility controls.
383+
final brightnessMode = ServiceExtensionDescription<String>.from(
384+
extensions.brightnessMode,
385+
title: 'Override brightness',
386+
iconData: Icons.brightness_6,
387+
displayValues: [
388+
'System Default',
389+
'Light Mode',
390+
'Dark Mode',
391+
],
392+
gaScreenName: gac.accessibility,
393+
gaItem: gac.brightnessOverride,
394+
tooltip: 'Override Brightness',
395+
);
396+
382397
final disableClipLayers = ToggleableServiceExtensionDescription<bool>.from(
383398
extensions.disableClipLayers,
384399
title: 'Render Clip layers',

packages/devtools_app/lib/src/shared/analytics/constants.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ final vmTools = ScreenMetaData.vmTools.id;
4444
const console = 'console';
4545
final simple = ScreenMetaData.simple.id;
4646
final deeplink = ScreenMetaData.deepLinks.id;
47+
final accessibility = ScreenMetaData.accessibility.id;
4748

4849
// GA events not associated with a any screen e.g., hotReload, hotRestart, etc
4950
const devToolsMain = 'main';
@@ -86,6 +87,7 @@ const repaintRainbow = 'repaintRainbow';
8687
const repaintRainbowDocs = 'repaintRainbowDocs';
8788
const debugBanner = 'debugBanner';
8889
const togglePlatform = 'togglePlatform';
90+
const brightnessOverride = 'brightnessOverride';
8991
const highlightOversizedImages = 'highlightOversizedImages';
9092
const highlightOversizedImagesDocs = 'highlightOversizedImagesDocs';
9193
const selectWidgetMode = 'selectWidgetMode';

packages/devtools_app_shared/lib/src/service/service_extensions.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,13 @@ final togglePlatformMode = ServiceExtension<String>(
201201
values: ['iOS', 'android', 'fuchsia', 'macOS', 'linux'],
202202
);
203203

204+
/// Override the platform brightness (light mode, dark mode, or system default).
205+
final brightnessMode = ServiceExtension<String>(
206+
extension:
207+
'$flutterExtensionPrefix${FoundationServiceExtensions.brightnessOverride.name}',
208+
values: ['system', 'Brightness.light', 'Brightness.dark'],
209+
);
210+
204211
/// Toggle whether interacting with the device selects widgets or triggers
205212
/// normal interactions.
206213
final toggleSelectWidgetMode = ToggleableServiceExtension<bool>(
@@ -259,6 +266,7 @@ final _extensionDescriptions = <ServiceExtension<Object>>[
259266
toggleSelectWidgetMode,
260267
countWidgetBuilds,
261268
profilePlatformChannels,
269+
brightnessMode,
262270
];
263271

264272
/// Service extensions that are not safe to call unless a frame has already
@@ -281,6 +289,7 @@ final _unsafeBeforeFirstFrameFlutterExtensions = Set.of(
281289
enableOnDeviceInspector,
282290
togglePlatformMode,
283291
slowAnimations,
292+
brightnessMode,
284293
].map((extension) => extension.extension),
285294
);
286295

0 commit comments

Comments
 (0)