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'; |
10 | library; |
11 | |
12 | import 'dart:ui' as ui show Brightness; |
13 | |
14 | import 'assertions.dart'; |
15 | import 'memory_allocations.dart'; |
16 | import 'platform.dart'; |
17 | import 'print.dart'; |
18 | |
19 | export 'dart:ui' show Brightness; |
20 | |
21 | export '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. |
36 | bool 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. |
66 | bool 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. |
82 | Future<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 | final Stopwatch stopwatch = |
90 | 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 | try { |
93 | return await action(); |
94 | } finally { |
95 | stopwatch.stop(); |
96 | debugPrint('Action " $description" took ${stopwatch.elapsed}' ); |
97 | } |
98 | } else { |
99 | return action(); |
100 | } |
101 | } |
102 | |
103 | /// Configure [debugFormatDouble] using [num.toStringAsPrecision]. |
104 | /// |
105 | /// Defaults to null, which uses the default logic of [debugFormatDouble]. |
106 | int? debugDoublePrecision; |
107 | |
108 | /// Formats a double to have standard formatting. |
109 | /// |
110 | /// This behavior can be overridden by [debugDoublePrecision]. |
111 | String debugFormatDouble(double? value) { |
112 | if (value == null) { |
113 | return 'null' ; |
114 | } |
115 | if (debugDoublePrecision != null) { |
116 | return value.toStringAsPrecision(debugDoublePrecision!); |
117 | } |
118 | return value.toStringAsFixed(1); |
119 | } |
120 | |
121 | /// A setting that can be used to override the platform [Brightness] exposed |
122 | /// from [BindingBase.platformDispatcher]. |
123 | /// |
124 | /// See also: |
125 | /// |
126 | /// * [WidgetsApp], which uses the [debugBrightnessOverride] setting in debug mode |
127 | /// to construct a [MediaQueryData]. |
128 | ui.Brightness? debugBrightnessOverride; |
129 | |
130 | /// The address for the active DevTools server used for debugging this |
131 | /// application. |
132 | String? activeDevToolsServerAddress; |
133 | |
134 | /// The uri for the connected vm service protocol. |
135 | String? connectedVmServiceUri; |
136 | |
137 | /// If memory allocation tracking is enabled, dispatch Flutter object creation. |
138 | /// |
139 | /// This method is not member of FlutterMemoryAllocations, because |
140 | /// [FlutterMemoryAllocations] should not increase size of the Flutter application |
141 | /// if memory allocations are disabled. |
142 | /// |
143 | /// The [flutterLibrary] argument is the name of the Flutter library where |
144 | /// the object is declared. For example, 'widgets' for widgets.dart. |
145 | /// |
146 | /// Should be called only from within an assert and only inside Flutter Framework. |
147 | /// |
148 | /// Returns true to make it easier to be wrapped into `assert`. |
149 | bool debugMaybeDispatchCreated(String flutterLibrary, String className, Object object) { |
150 | if (kFlutterMemoryAllocationsEnabled) { |
151 | FlutterMemoryAllocations.instance.dispatchObjectCreated( |
152 | library: 'package:flutter/ $flutterLibrary.dart' , |
153 | className: className, |
154 | object: object, |
155 | ); |
156 | } |
157 | return true; |
158 | } |
159 | |
160 | /// If memory allocations tracking is enabled, dispatch object disposal. |
161 | /// |
162 | /// Should be called only from within an assert. |
163 | /// |
164 | /// Returns true to make it easier to be wrapped into `assert`. |
165 | bool debugMaybeDispatchDisposed(Object object) { |
166 | if (kFlutterMemoryAllocationsEnabled) { |
167 | FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: object); |
168 | } |
169 | return true; |
170 | } |
171 | |