1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// @docImport 'dart:developer';
6///
7/// @docImport 'package:flutter/foundation.dart';
8/// @docImport 'package:flutter/rendering.dart';
9/// @docImport 'package:flutter/widgets.dart';
10library;
11
12import 'dart:ui' as ui show Brightness;
13
14import 'assertions.dart';
15import 'memory_allocations.dart';
16import 'platform.dart';
17import 'print.dart';
18
19export 'dart:ui' show Brightness;
20
21export 'print.dart' show DebugPrintCallback;
22
23/// Returns true if none of the foundation library debug variables have been
24/// changed.
25///
26/// This function is used by the test framework to ensure that debug variables
27/// haven't been inadvertently changed.
28///
29/// The `debugPrintOverride` argument can be specified to indicate the expected
30/// value of the [debugPrint] variable. This is useful for test frameworks that
31/// override [debugPrint] themselves and want to check that their own custom
32/// value wasn't overridden by a test.
33///
34/// See [the foundation library](foundation/foundation-library.html)
35/// for a complete list.
36bool debugAssertAllFoundationVarsUnset(
37 String reason, {
38 DebugPrintCallback debugPrintOverride = debugPrintThrottled,
39}) {
40 assert(() {
41 if (debugPrint != debugPrintOverride ||
42 debugDefaultTargetPlatformOverride != null ||
43 debugDoublePrecision != null ||
44 debugBrightnessOverride != null) {
45 throw FlutterError(reason);
46 }
47 return true;
48 }());
49 return true;
50}
51
52/// Boolean value indicating whether [debugInstrumentAction] will instrument
53/// actions in debug builds.
54///
55/// The framework does not use [debugInstrumentAction] internally, so this
56/// does not enable any additional instrumentation for the framework itself.
57///
58/// See also:
59///
60/// * [debugProfileBuildsEnabled], which enables additional tracing of builds
61/// in [Widget]s.
62/// * [debugProfileLayoutsEnabled], which enables additional tracing of layout
63/// events in [RenderObject]s.
64/// * [debugProfilePaintsEnabled], which enables additional tracing of paint
65/// events in [RenderObject]s.
66bool debugInstrumentationEnabled = false;
67
68/// Runs the specified [action], timing how long the action takes in debug
69/// builds when [debugInstrumentationEnabled] is true.
70///
71/// The instrumentation will be printed to the logs using [debugPrint]. In
72/// non-debug builds, or when [debugInstrumentationEnabled] is false, this will
73/// run [action] without any instrumentation.
74///
75/// Returns the result of running [action].
76///
77/// See also:
78///
79/// * [Timeline], which is used to record synchronous tracing events for
80/// visualization in Chrome's tracing format. This method does not
81/// implicitly add any timeline events.
82Future<T> debugInstrumentAction<T>(String description, Future<T> Function() action) async {
83 bool instrument = false;
84 assert(() {
85 instrument = debugInstrumentationEnabled;
86 return true;
87 }());
88 if (instrument) {
89 // dart format off
90 final Stopwatch stopwatch = Stopwatch() ..start(); // flutter_ignore: stopwatch (see analyze.dart)
91 // Ignore context: The framework does not use this function internally so it will not cause flakes.
92 // dart format on
93 try {
94 return await action();
95 } finally {
96 stopwatch.stop();
97 debugPrint('Action "$description" took ${stopwatch.elapsed}');
98 }
99 } else {
100 return action();
101 }
102}
103
104/// Configure [debugFormatDouble] using [num.toStringAsPrecision].
105///
106/// Defaults to null, which uses the default logic of [debugFormatDouble].
107int? debugDoublePrecision;
108
109/// Formats a double to have standard formatting.
110///
111/// This behavior can be overridden by [debugDoublePrecision].
112String debugFormatDouble(double? value) {
113 if (value == null) {
114 return 'null';
115 }
116 if (debugDoublePrecision != null) {
117 return value.toStringAsPrecision(debugDoublePrecision!);
118 }
119 return value.toStringAsFixed(1);
120}
121
122/// A setting that can be used to override the platform [Brightness] exposed
123/// from [BindingBase.platformDispatcher].
124///
125/// See also:
126///
127/// * [WidgetsApp], which uses the [debugBrightnessOverride] setting in debug mode
128/// to construct a [MediaQueryData].
129ui.Brightness? debugBrightnessOverride;
130
131/// The address for the active DevTools server used for debugging this
132/// application.
133String? activeDevToolsServerAddress;
134
135/// The uri for the connected vm service protocol.
136String? connectedVmServiceUri;
137
138/// If memory allocation tracking is enabled, dispatch Flutter object creation.
139///
140/// This method is not member of FlutterMemoryAllocations, because
141/// [FlutterMemoryAllocations] should not increase size of the Flutter application
142/// if memory allocations are disabled.
143///
144/// The [flutterLibrary] argument is the name of the Flutter library where
145/// the object is declared. For example, 'widgets' for widgets.dart.
146///
147/// Should be called only from within an assert and only inside Flutter Framework.
148///
149/// Returns true to make it easier to be wrapped into `assert`.
150bool debugMaybeDispatchCreated(String flutterLibrary, String className, Object object) {
151 if (kFlutterMemoryAllocationsEnabled) {
152 FlutterMemoryAllocations.instance.dispatchObjectCreated(
153 library: 'package:flutter/$flutterLibrary.dart',
154 className: className,
155 object: object,
156 );
157 }
158 return true;
159}
160
161/// If memory allocations tracking is enabled, dispatch object disposal.
162///
163/// Should be called only from within an assert.
164///
165/// Returns true to make it easier to be wrapped into `assert`.
166bool debugMaybeDispatchDisposed(Object object) {
167 if (kFlutterMemoryAllocationsEnabled) {
168 FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: object);
169 }
170 return true;
171}
172