| 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 | // 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]. |
| 107 | int? debugDoublePrecision; |
| 108 | |
| 109 | /// Formats a double to have standard formatting. |
| 110 | /// |
| 111 | /// This behavior can be overridden by [debugDoublePrecision]. |
| 112 | String 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]. |
| 129 | ui.Brightness? debugBrightnessOverride; |
| 130 | |
| 131 | /// The address for the active DevTools server used for debugging this |
| 132 | /// application. |
| 133 | String? activeDevToolsServerAddress; |
| 134 | |
| 135 | /// The uri for the connected vm service protocol. |
| 136 | String? 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`. |
| 150 | bool 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`. |
| 166 | bool debugMaybeDispatchDisposed(Object object) { |
| 167 | if (kFlutterMemoryAllocationsEnabled) { |
| 168 | FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: object); |
| 169 | } |
| 170 | return true; |
| 171 | } |
| 172 | |