Unverified Commit 23d258df authored by Alex Wallen's avatar Alex Wallen Committed by GitHub

Remove deprecated `updateSemantics` API usage. (#113382)

parent 671c5320
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:developer';
import 'dart:ui' as ui show SemanticsUpdate;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
......@@ -31,6 +32,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
_pipelineOwner = PipelineOwner(
onNeedVisualUpdate: ensureVisualUpdate,
onSemanticsOwnerCreated: _handleSemanticsOwnerCreated,
onSemanticsUpdate: _handleSemanticsUpdate,
onSemanticsOwnerDisposed: _handleSemanticsOwnerDisposed,
);
platformDispatcher
......@@ -367,6 +369,10 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
renderView.scheduleInitialSemantics();
}
void _handleSemanticsUpdate(ui.SemanticsUpdate update) {
renderView.updateSemantics(update);
}
void _handleSemanticsOwnerDisposed() {
renderView.clearSemantics();
}
......
......@@ -4,6 +4,7 @@
import 'dart:developer';
import 'dart:ui' as ui show PictureRecorder;
import 'dart:ui';
import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart';
......@@ -894,6 +895,7 @@ class PipelineOwner {
PipelineOwner({
this.onNeedVisualUpdate,
this.onSemanticsOwnerCreated,
this.onSemanticsUpdate,
this.onSemanticsOwnerDisposed,
});
......@@ -912,6 +914,12 @@ class PipelineOwner {
/// semantics tree.
final VoidCallback? onSemanticsOwnerCreated;
/// Called whenever this pipeline owner's semantics owner emits a [SemanticsUpdate].
///
/// Typical implementations will delegate the [SemanticsUpdate] to a [FlutterView]
/// that can handle the [SemanticsUpdate].
final SemanticsUpdateCallback? onSemanticsUpdate;
/// Called whenever this pipeline owner disposes its semantics owner.
///
/// Typical implementations will tear down the semantics tree.
......@@ -1183,7 +1191,8 @@ class PipelineOwner {
_outstandingSemanticsHandles += 1;
if (_outstandingSemanticsHandles == 1) {
assert(_semanticsOwner == null);
_semanticsOwner = SemanticsOwner();
assert(onSemanticsUpdate != null, 'Attempted to open a semantics handle without an onSemanticsUpdate callback.');
_semanticsOwner = SemanticsOwner(onSemanticsUpdate: onSemanticsUpdate!);
onSemanticsOwnerCreated?.call();
}
return SemanticsHandle._(this, listener);
......
......@@ -4,7 +4,7 @@
import 'dart:developer';
import 'dart:io' show Platform;
import 'dart:ui' as ui show FlutterView, Scene, SceneBuilder;
import 'dart:ui' as ui show FlutterView, Scene, SceneBuilder, SemanticsUpdate;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
......@@ -247,6 +247,15 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
}
}
/// Sends the provided [SemanticsUpdate] to the [FlutterView] associated with
/// this [RenderView].
///
/// A [SemanticsUpdate] is produced by a [SemanticsOwner] during the
/// [EnginePhase.flushSemantics] phase.
void updateSemantics(ui.SemanticsUpdate update) {
_window.updateSemantics(update);
}
void _updateSystemChrome() {
// Take overlay style from the place where a system status bar and system
// navigation bar are placed to update system style overlay.
......
......@@ -48,6 +48,11 @@ typedef SetTextHandler = void Function(String text);
/// Returned by [SemanticsConfiguration.getActionHandler].
typedef SemanticsActionHandler = void Function(Object? args);
/// Signature for a function that receives a semantics update and returns no result.
///
/// Used by [SemanticsOwner.onSemanticsUpdate].
typedef SemanticsUpdateCallback = void Function(ui.SemanticsUpdate update);
/// A tag for a [SemanticsNode].
///
/// Tags can be interpreted by the parent of a [SemanticsNode]
......@@ -3052,6 +3057,19 @@ class _TraversalSortNode implements Comparable<_TraversalSortNode> {
/// obtain a [SemanticsHandle]. This will create a [SemanticsOwner] if
/// necessary.
class SemanticsOwner extends ChangeNotifier {
/// Creates a [SemanticsOwner] that manages zero or more [SemanticsNode] objects.
SemanticsOwner({
required this.onSemanticsUpdate,
});
/// The [onSemanticsUpdate] callback is expected to dispatch [SemanticsUpdate]s
/// to the [FlutterView] that is associated with this [PipelineOwner] and/or
/// [SemanticsOwner].
///
/// A [SemanticsOwner] calls [onSemanticsUpdate] during [sendSemanticsUpdate]
/// after the [SemanticsUpdate] has been build, but before the [SemanticsOwner]'s
/// listeners have been notified.
final SemanticsUpdateCallback onSemanticsUpdate;
final Set<SemanticsNode> _dirtyNodes = <SemanticsNode>{};
final Map<int, SemanticsNode> _nodes = <int, SemanticsNode>{};
final Set<SemanticsNode> _detachedNodes = <SemanticsNode>{};
......@@ -3069,7 +3087,7 @@ class SemanticsOwner extends ChangeNotifier {
super.dispose();
}
/// Update the semantics using [dart:ui.PlatformDispatcher.updateSemantics].
/// Update the semantics using [onSemanticsUpdate].
void sendSemanticsUpdate() {
if (_dirtyNodes.isEmpty) {
return;
......@@ -3118,9 +3136,7 @@ class SemanticsOwner extends ChangeNotifier {
final CustomSemanticsAction action = CustomSemanticsAction.getAction(actionId)!;
builder.updateCustomAction(id: actionId, label: action.label, hint: action.hint, overrideId: action.action?.index ?? -1);
}
// TODO(a-wallen): https://github.com/flutter/flutter/issues/112221
// ignore: deprecated_member_use
SemanticsBinding.instance.platformDispatcher.updateSemantics(builder.build());
onSemanticsUpdate(builder.build());
notifyListeners();
}
......
......@@ -18,9 +18,12 @@ void main() {
// Initialize all bindings because owner.flushSemantics() requires a window
final TestRenderObject renderObject = TestRenderObject();
int onNeedVisualUpdateCallCount = 0;
final PipelineOwner owner = PipelineOwner(onNeedVisualUpdate: () {
onNeedVisualUpdateCallCount +=1;
});
final PipelineOwner owner = PipelineOwner(
onNeedVisualUpdate: () {
onNeedVisualUpdateCallCount +=1;
},
onSemanticsUpdate: (ui.SemanticsUpdate update) {}
);
owner.ensureSemantics();
renderObject.attach(owner);
renderObject.layout(const BoxConstraints.tightForFinite()); // semantics are only calculated if layout information is up to date.
......@@ -31,6 +34,49 @@ void main() {
expect(onNeedVisualUpdateCallCount, 2);
});
test('onSemanticsUpdate is called during flushSemantics.', () {
int onSemanticsUpdateCallCount = 0;
final PipelineOwner owner = PipelineOwner(
onSemanticsUpdate: (ui.SemanticsUpdate update) {
onSemanticsUpdateCallCount += 1;
},
);
owner.ensureSemantics();
expect(onSemanticsUpdateCallCount, 0);
final TestRenderObject renderObject = TestRenderObject();
renderObject.attach(owner);
renderObject.layout(const BoxConstraints.tightForFinite());
owner.flushSemantics();
expect(onSemanticsUpdateCallCount, 1);
});
test('Enabling semantics without configuring onSemanticsUpdate is invalid.', () {
final PipelineOwner pipelineOwner = PipelineOwner();
expect(() => pipelineOwner.ensureSemantics(), throwsAssertionError);
});
test('onSemanticsUpdate during sendSemanticsUpdate.', () {
int onSemanticsUpdateCallCount = 0;
final SemanticsOwner owner = SemanticsOwner(
onSemanticsUpdate: (ui.SemanticsUpdate update) {
onSemanticsUpdateCallCount += 1;
},
);
final SemanticsNode node = SemanticsNode.root(owner: owner);
node.rect = Rect.largest;
expect(onSemanticsUpdateCallCount, 0);
owner.sendSemanticsUpdate();
expect(onSemanticsUpdateCallCount, 1);
});
test('detached RenderObject does not do semantics', () {
final TestRenderObject renderObject = TestRenderObject();
expect(renderObject.attached, isFalse);
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math_64.dart';
......@@ -698,7 +700,9 @@ void main() {
});
test('Semantics id does not repeat', () {
final SemanticsOwner owner = SemanticsOwner();
final SemanticsOwner owner = SemanticsOwner(
onSemanticsUpdate: (SemanticsUpdate update) {},
);
const int expectId = 1400;
SemanticsNode? nodeToRemove;
for (int i = 0; i < kMaxFrameworkAccessibilityIdentifier; i++) {
......
......@@ -463,11 +463,6 @@ class TestWindow implements ui.SingletonFlutterWindow {
platformDispatcher.onAccessibilityFeaturesChanged = callback;
}
@override
void updateSemantics(ui.SemanticsUpdate update) {
platformDispatcher.updateSemantics(update);
}
@override
void setIsolateDebugName(String name) {
platformDispatcher.setIsolateDebugName(name);
......@@ -851,13 +846,6 @@ class TestPlatformDispatcher implements ui.PlatformDispatcher {
_platformDispatcher.onAccessibilityFeaturesChanged = callback;
}
@override
void updateSemantics(ui.SemanticsUpdate update) {
// TODO(a-wallen): https://github.com/flutter/flutter/issues/112221
// ignore: deprecated_member_use
_platformDispatcher.updateSemantics(update);
}
@override
void setIsolateDebugName(String name) {
_platformDispatcher.setIsolateDebugName(name);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment