Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
dc36195c
Unverified
Commit
dc36195c
authored
Oct 23, 2018
by
Michael Goderbauer
Committed by
GitHub
Oct 23, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reland "Remove all service extensions from release mode (#23038)" (#23291)
parent
a6a16078
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
212 additions
and
155 deletions
+212
-155
binding.dart
packages/flutter/lib/src/foundation/binding.dart
+69
-23
binding.dart
packages/flutter/lib/src/rendering/binding.dart
+38
-23
binding.dart
packages/flutter/lib/src/scheduler/binding.dart
+11
-7
binding.dart
packages/flutter/lib/src/services/binding.dart
+15
-11
binding.dart
packages/flutter/lib/src/widgets/binding.dart
+50
-45
widget_inspector.dart
packages/flutter/lib/src/widgets/widget_inspector.dart
+28
-33
service_extensions_test.dart
...ages/flutter/test/foundation/service_extensions_test.dart
+1
-9
vmservice.dart
packages/flutter_tools/lib/src/vmservice.dart
+0
-4
No files found.
packages/flutter/lib/src/foundation/binding.dart
View file @
dc36195c
...
...
@@ -93,9 +93,7 @@ abstract class BindingBase {
/// Implementations of this method must call their superclass
/// implementation.
///
/// Service extensions are only exposed when the observatory is
/// included in the build, which should only happen in checked mode
/// and in profile mode.
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
///
/// See also:
///
...
...
@@ -104,18 +102,23 @@ abstract class BindingBase {
@mustCallSuper
void
initServiceExtensions
()
{
assert
(!
_debugServiceExtensionsRegistered
);
registerSignalServiceExtension
(
name:
'reassemble'
,
callback:
reassembleApplication
,
);
registerSignalServiceExtension
(
name:
'exit'
,
callback:
_exitApplication
,
);
registerSignalServiceExtension
(
name:
'frameworkPresent'
,
callback:
()
=>
Future
<
void
>.
value
(),
);
assert
(()
{
registerSignalServiceExtension
(
name:
'reassemble'
,
callback:
reassembleApplication
,
);
return
true
;
}());
const
bool
isReleaseMode
=
bool
.
fromEnvironment
(
'dart.vm.product'
);
if
(!
isReleaseMode
)
{
registerSignalServiceExtension
(
name:
'exit'
,
callback:
_exitApplication
,
);
}
assert
(()
{
registerServiceExtension
(
name:
'platformOverride'
,
...
...
@@ -239,6 +242,8 @@ abstract class BindingBase {
/// no value.
///
/// Calls the `callback` callback when the service extension is called.
///
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void
registerSignalServiceExtension
({
@required
String
name
,
...
...
@@ -267,6 +272,8 @@ abstract class BindingBase {
///
/// Calls the `setter` callback with the new value when the
/// service extension method is called with a new value.
///
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void
registerBoolServiceExtension
({
@required
String
name
,
...
...
@@ -297,6 +304,8 @@ abstract class BindingBase {
///
/// Calls the `setter` callback with the new value when the
/// service extension method is called with a new value.
///
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void
registerNumericServiceExtension
({
@required
String
name
,
...
...
@@ -326,6 +335,8 @@ abstract class BindingBase {
///
/// Calls the `setter` callback with the new value when the
/// service extension method is called with a new value.
///
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void
registerStringServiceExtension
({
@required
String
name
,
...
...
@@ -345,16 +356,51 @@ abstract class BindingBase {
);
}
/// Registers a service extension method with the given name (full
/// name "ext.flutter.name"). The given callback is called when the
/// extension method is called. The callback must return a [Future]
/// that either eventually completes to a return value in the form
/// of a name/value map where the values can all be converted to
/// JSON using `json.encode()` (see [JsonEncoder]), or fails. In case of failure, the
/// failure is reported to the remote caller and is dumped to the
/// logs.
/// Registers a service extension method with the given name (full name
/// "ext.flutter.name").
///
/// The given callback is called when the extension method is called. The
/// callback must return a [Future] that either eventually completes to a
/// return value in the form of a name/value map where the values can all be
/// converted to JSON using `json.encode()` (see [JsonEncoder]), or fails. In
/// case of failure, the failure is reported to the remote caller and is
/// dumped to the logs.
///
/// The returned map will be mutated.
///
/// {@template flutter.foundation.bindingBase.registerServiceExtension}
/// A registered service extension can only be activated if the vm-service
/// is included in the build, which only happens in debug and profile mode.
/// Although a service extension cannot be used in release mode its code may
/// still be included in the Dart snapshot and blow up binary size if it is
/// not wrapped in a guard that allows the tree shaker to remove it (see
/// sample code below).
///
/// ## Sample Code
///
/// The following code registers a service extension that is only included in
/// debug builds:
///
/// ```dart
/// assert(() {
/// // Register your service extension here.
/// return true;
/// }());
///
/// ```
///
/// A service extension registered with the following code snippet is
/// available in debug and profile mode:
///
/// ```dart
/// if (!const bool.fromEnvironment('dart.vm.product')) {
// // Register your service extension here.
// }
/// ```
///
/// Both guards ensure that Dart's tree shaker can remove the code for the
/// service extension in release builds.
/// {@endTemplate}
@protected
void
registerServiceExtension
({
@required
String
name
,
...
...
packages/flutter/lib/src/rendering/binding.dart
View file @
dc36195c
...
...
@@ -51,7 +51,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
super
.
initServiceExtensions
();
assert
(()
{
// these service extensions only work in
checked
mode
// these service extensions only work in
debug
mode
registerBoolServiceExtension
(
name:
'debugPaint'
,
getter:
()
async
=>
debugPaintSizeEnabled
,
...
...
@@ -60,17 +60,17 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
return
Future
<
void
>.
value
();
debugPaintSizeEnabled
=
value
;
return
_forceRepaint
();
}
}
,
);
registerBoolServiceExtension
(
name:
'debugPaintBaselinesEnabled'
,
getter:
()
async
=>
debugPaintBaselinesEnabled
,
setter:
(
bool
value
)
{
name:
'debugPaintBaselinesEnabled'
,
getter:
()
async
=>
debugPaintBaselinesEnabled
,
setter:
(
bool
value
)
{
if
(
debugPaintBaselinesEnabled
==
value
)
return
Future
<
void
>.
value
();
debugPaintBaselinesEnabled
=
value
;
return
_forceRepaint
();
}
}
,
);
registerBoolServiceExtension
(
name:
'repaintRainbow'
,
...
...
@@ -83,28 +83,43 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Semanti
return
Future
<
void
>.
value
();
},
);
registerSignalServiceExtension
(
name:
'debugDumpLayerTree'
,
callback:
()
{
debugDumpLayerTree
();
return
debugPrintDone
;
},
);
return
true
;
}());
registerSignalServiceExtension
(
name:
'debugDumpRenderTree'
,
callback:
()
{
debugDumpRenderTree
();
return
debugPrintDone
;
}
);
registerSignalServiceExtension
(
name:
'debugDumpLayerTree'
,
callback:
()
{
debugDumpLayerTree
();
return
debugPrintDone
;
}
);
const
bool
isReleaseMode
=
bool
.
fromEnvironment
(
'dart.vm.product'
);
if
(!
isReleaseMode
)
{
// these service extensions work in debug or profile mode
registerSignalServiceExtension
(
name:
'debugDumpRenderTree'
,
callback:
()
{
debugDumpRenderTree
();
return
debugPrintDone
;
},
);
registerSignalServiceExtension
(
name:
'debugDumpSemanticsTreeInTraversalOrder'
,
callback:
()
{
debugDumpSemanticsTree
(
DebugSemanticsDumpOrder
.
traversalOrder
);
return
debugPrintDone
;
}
);
registerSignalServiceExtension
(
name:
'debugDumpSemanticsTreeInTraversalOrder'
,
callback:
()
{
debugDumpSemanticsTree
(
DebugSemanticsDumpOrder
.
traversalOrder
);
return
debugPrintDone
;
},
);
registerSignalServiceExtension
(
name:
'debugDumpSemanticsTreeInInverseHitTestOrder'
,
callback:
()
{
debugDumpSemanticsTree
(
DebugSemanticsDumpOrder
.
inverseHitTest
);
return
debugPrintDone
;
}
);
registerSignalServiceExtension
(
name:
'debugDumpSemanticsTreeInInverseHitTestOrder'
,
callback:
()
{
debugDumpSemanticsTree
(
DebugSemanticsDumpOrder
.
inverseHitTest
);
return
debugPrintDone
;
},
);
}
}
/// Creates a [RenderView] object to be the root of the
...
...
packages/flutter/lib/src/scheduler/binding.dart
View file @
dc36195c
...
...
@@ -203,13 +203,17 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
@override
void
initServiceExtensions
()
{
super
.
initServiceExtensions
();
registerNumericServiceExtension
(
name:
'timeDilation'
,
getter:
()
async
=>
timeDilation
,
setter:
(
double
value
)
async
{
timeDilation
=
value
;
}
);
const
bool
isReleaseMode
=
bool
.
fromEnvironment
(
'dart.vm.product'
);
if
(!
isReleaseMode
)
{
registerNumericServiceExtension
(
name:
'timeDilation'
,
getter:
()
async
=>
timeDilation
,
setter:
(
double
value
)
async
{
timeDilation
=
value
;
},
);
}
}
/// Whether the application is visible, and if so, whether it is currently
...
...
packages/flutter/lib/src/services/binding.dart
View file @
dc36195c
...
...
@@ -86,17 +86,21 @@ mixin ServicesBinding on BindingBase {
@override
void
initServiceExtensions
()
{
super
.
initServiceExtensions
();
registerStringServiceExtension
(
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from
// the rootBundle cache and cause the entire image cache to be cleared.
// This is used by hot reload mode to clear out the cache of resources
// that have changed.
name:
'evict'
,
getter:
()
async
=>
''
,
setter:
(
String
value
)
async
{
evict
(
value
);
}
);
assert
(()
{
registerStringServiceExtension
(
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from
// the rootBundle cache and cause the entire image cache to be cleared.
// This is used by hot reload mode to clear out the cache of resources
// that have changed.
name:
'evict'
,
getter:
()
async
=>
''
,
setter:
(
String
value
)
async
{
evict
(
value
);
},
);
return
true
;
}());
}
/// Called in response to the `ext.flutter.evict` service extension.
...
...
packages/flutter/lib/src/widgets/binding.dart
View file @
dc36195c
...
...
@@ -265,37 +265,41 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
void
initServiceExtensions
()
{
super
.
initServiceExtensions
();
registerSignalServiceExtension
(
name:
'debugDumpApp'
,
callback:
()
{
debugDumpApp
();
return
debugPrintDone
;
}
);
registerBoolServiceExtension
(
name:
'showPerformanceOverlay'
,
getter:
()
=>
Future
<
bool
>.
value
(
WidgetsApp
.
showPerformanceOverlayOverride
),
setter:
(
bool
value
)
{
if
(
WidgetsApp
.
showPerformanceOverlayOverride
==
value
)
return
Future
<
void
>.
value
();
WidgetsApp
.
showPerformanceOverlayOverride
=
value
;
return
_forceRebuild
();
}
);
registerBoolServiceExtension
(
name:
'debugAllowBanner'
,
getter:
()
=>
Future
<
bool
>.
value
(
WidgetsApp
.
debugAllowBannerOverride
),
setter:
(
bool
value
)
{
if
(
WidgetsApp
.
debugAllowBannerOverride
==
value
)
return
Future
<
void
>.
value
();
WidgetsApp
.
debugAllowBannerOverride
=
value
;
return
_forceRebuild
();
}
);
const
bool
isReleaseMode
=
bool
.
fromEnvironment
(
'dart.vm.product'
);
if
(!
isReleaseMode
)
{
registerSignalServiceExtension
(
name:
'debugDumpApp'
,
callback:
()
{
debugDumpApp
();
return
debugPrintDone
;
},
);
registerBoolServiceExtension
(
name:
'showPerformanceOverlay'
,
getter:
()
=>
Future
<
bool
>.
value
(
WidgetsApp
.
showPerformanceOverlayOverride
),
setter:
(
bool
value
)
{
if
(
WidgetsApp
.
showPerformanceOverlayOverride
==
value
)
return
Future
<
void
>.
value
();
WidgetsApp
.
showPerformanceOverlayOverride
=
value
;
return
_forceRebuild
();
},
);
}
assert
(()
{
registerBoolServiceExtension
(
name:
'debugAllowBanner'
,
getter:
()
=>
Future
<
bool
>.
value
(
WidgetsApp
.
debugAllowBannerOverride
),
setter:
(
bool
value
)
{
if
(
WidgetsApp
.
debugAllowBannerOverride
==
value
)
return
Future
<
void
>.
value
();
WidgetsApp
.
debugAllowBannerOverride
=
value
;
return
_forceRebuild
();
},
);
// Expose the ability to send Widget rebuilds as [Timeline] events.
registerBoolServiceExtension
(
name:
'profileWidgetBuilds'
,
...
...
@@ -303,25 +307,26 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
setter:
(
bool
value
)
async
{
if
(
debugProfileBuildsEnabled
!=
value
)
debugProfileBuildsEnabled
=
value
;
}
}
,
);
return
true
;
}());
// This service extension is deprecated and will be removed by 7
/1/2018.
// Use ext.flutter.inspector.show instead.
registerBoolServiceExtension
(
name:
'debugWidgetInspector'
,
getter:
()
async
=>
WidgetsApp
.
debugShowWidgetInspectorOverride
,
setter:
(
bool
value
)
{
if
(
WidgetsApp
.
debugShowWidgetInspectorOverride
==
value
)
return
Future
<
void
>.
value
();
WidgetsApp
.
debugShowWidgetInspectorOverride
=
value
;
return
_forceRebuild
();
}
);
// This service extension is deprecated and will be removed by 12
/1/2018.
// Use ext.flutter.inspector.show instead.
registerBoolServiceExtension
(
name:
'debugWidgetInspector'
,
getter:
()
async
=>
WidgetsApp
.
debugShowWidgetInspectorOverride
,
setter:
(
bool
value
)
{
if
(
WidgetsApp
.
debugShowWidgetInspectorOverride
==
value
)
return
Future
<
void
>.
value
();
WidgetsApp
.
debugShowWidgetInspectorOverride
=
value
;
return
_forceRebuild
();
}
);
WidgetInspectorService
.
instance
.
initServiceExtensions
(
registerServiceExtension
);
WidgetInspectorService
.
instance
.
initServiceExtensions
(
registerServiceExtension
);
return
true
;
}());
}
Future
<
void
>
_forceRebuild
()
{
...
...
packages/flutter/lib/src/widgets/widget_inspector.dart
View file @
dc36195c
...
...
@@ -917,13 +917,11 @@ mixin WidgetInspectorService {
/// Called to register service extensions.
///
/// Service extensions are only exposed when the observatory is
/// included in the build, which should only happen in checked mode
/// and in profile mode.
///
/// See also:
///
/// * <https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses>
/// * [BindingBase.initServiceExtensions], which explains when service
/// extensions can be used.
void
initServiceExtensions
(
_RegisterServiceExtensionCallback
registerServiceExtensionCallback
)
{
_registerServiceExtensionCallback
=
registerServiceExtensionCallback
;
...
...
@@ -1023,36 +1021,33 @@ mixin WidgetInspectorService {
name:
'isWidgetCreationTracked'
,
callback:
isWidgetCreationTracked
,
);
assert
(()
{
registerServiceExtension
(
name:
'screenshot'
,
callback:
(
Map
<
String
,
String
>
parameters
)
async
{
assert
(
parameters
.
containsKey
(
'id'
));
assert
(
parameters
.
containsKey
(
'width'
));
assert
(
parameters
.
containsKey
(
'height'
));
final
ui
.
Image
image
=
await
screenshot
(
toObject
(
parameters
[
'id'
]),
width:
double
.
parse
(
parameters
[
'width'
]),
height:
double
.
parse
(
parameters
[
'height'
]),
margin:
parameters
.
containsKey
(
'margin'
)
?
double
.
parse
(
parameters
[
'margin'
])
:
0.0
,
maxPixelRatio:
parameters
.
containsKey
(
'maxPixelRatio'
)
?
double
.
parse
(
parameters
[
'maxPixelRatio'
])
:
1.0
,
debugPaint:
parameters
[
'debugPaint'
]
==
'true'
,
);
if
(
image
==
null
)
{
return
<
String
,
Object
>{
'result'
:
null
};
}
final
ByteData
byteData
=
await
image
.
toByteData
(
format:
ui
.
ImageByteFormat
.
png
);
registerServiceExtension
(
name:
'screenshot'
,
callback:
(
Map
<
String
,
String
>
parameters
)
async
{
assert
(
parameters
.
containsKey
(
'id'
));
assert
(
parameters
.
containsKey
(
'width'
));
assert
(
parameters
.
containsKey
(
'height'
));
final
ui
.
Image
image
=
await
screenshot
(
toObject
(
parameters
[
'id'
]),
width:
double
.
parse
(
parameters
[
'width'
]),
height:
double
.
parse
(
parameters
[
'height'
]),
margin:
parameters
.
containsKey
(
'margin'
)
?
double
.
parse
(
parameters
[
'margin'
])
:
0.0
,
maxPixelRatio:
parameters
.
containsKey
(
'maxPixelRatio'
)
?
double
.
parse
(
parameters
[
'maxPixelRatio'
])
:
1.0
,
debugPaint:
parameters
[
'debugPaint'
]
==
'true'
,
);
if
(
image
==
null
)
{
return
<
String
,
Object
>{
'result'
:
null
};
}
final
ByteData
byteData
=
await
image
.
toByteData
(
format:
ui
.
ImageByteFormat
.
png
);
return
<
String
,
Object
>{
'result'
:
base64
.
encoder
.
convert
(
Uint8List
.
view
(
byteData
.
buffer
)),
};
},
);
return
true
;
}());
return
<
String
,
Object
>{
'result'
:
base64
.
encoder
.
convert
(
Uint8List
.
view
(
byteData
.
buffer
)),
};
},
);
}
/// Clear all InspectorService object references.
...
...
packages/flutter/test/foundation/service_extensions_test.dart
View file @
dc36195c
...
...
@@ -359,13 +359,6 @@ void main() {
expect
(
binding
.
extensions
.
containsKey
(
'exit'
),
isTrue
);
});
test
(
'Service extensions - frameworkPresent'
,
()
async
{
Map
<
String
,
dynamic
>
result
;
result
=
await
binding
.
testExtension
(
'frameworkPresent'
,
<
String
,
String
>{});
expect
(
result
,
<
String
,
String
>{});
});
test
(
'Service extensions - platformOverride'
,
()
async
{
Map
<
String
,
dynamic
>
result
;
...
...
@@ -491,7 +484,6 @@ void main() {
test
(
'Service extensions - debugWidgetInspector'
,
()
async
{
Map
<
String
,
dynamic
>
result
;
expect
(
binding
.
frameScheduled
,
isFalse
);
expect
(
WidgetsApp
.
debugShowWidgetInspectorOverride
,
false
);
result
=
await
binding
.
testExtension
(
'debugWidgetInspector'
,
<
String
,
String
>{});
...
...
@@ -541,7 +533,7 @@ void main() {
// If you add a service extension... TEST IT! :-)
// ...then increment this number.
expect
(
binding
.
extensions
.
length
,
3
9
);
expect
(
binding
.
extensions
.
length
,
3
8
);
expect
(
console
,
isEmpty
);
debugPrint
=
debugPrintThrottled
;
...
...
packages/flutter_tools/lib/src/vmservice.dart
View file @
dc36195c
...
...
@@ -1296,10 +1296,6 @@ class Isolate extends ServiceObjectOwner {
);
}
Future
<
bool
>
flutterFrameworkPresent
()
async
{
return
await
invokeFlutterExtensionRpcRaw
(
'ext.flutter.frameworkPresent'
)
!=
null
;
}
Future
<
Map
<
String
,
dynamic
>>
uiWindowScheduleFrame
()
async
{
return
await
invokeFlutterExtensionRpcRaw
(
'ext.ui.window.scheduleFrame'
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment