mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add assistiveTechnologyEnabled flag to window (flutter/engine#5740)
This commit is contained in:
parent
9f3465f4c3
commit
71e01bf548
@ -70,6 +70,11 @@ void _updateSemanticsEnabled(bool enabled) {
|
||||
_invoke(window.onSemanticsEnabledChanged, window._onSemanticsEnabledChangedZone);
|
||||
}
|
||||
|
||||
void _updateAssistiveTechnologyEnabled(bool enabled) {
|
||||
window._assistiveTechnologyEnabled = enabled;
|
||||
_invoke(window._onAssistiveTechnologyEnabled, window._onAssistiveTechnologyEnabledZone);
|
||||
}
|
||||
|
||||
void _dispatchPlatformMessage(String name, ByteData data, int responseId) {
|
||||
if (window.onPlatformMessage != null) {
|
||||
_invoke3<String, ByteData, PlatformMessageResponseCallback>(
|
||||
|
||||
@ -637,6 +637,30 @@ class Window {
|
||||
bool get semanticsEnabled => _semanticsEnabled;
|
||||
bool _semanticsEnabled = false;
|
||||
|
||||
/// Whether the user is using assitive technologies to interact with the
|
||||
/// application.
|
||||
///
|
||||
/// This includes screen readers such as TalkBack on Android and VoiceOVer
|
||||
/// on iOS, as well as hardware switches, and more.
|
||||
///
|
||||
/// The [onAssistiveTechnologyEnabled] callback is called whenever this value
|
||||
/// changes.
|
||||
bool get assistiveTechnologyEnabled => _assistiveTechnologyEnabled;
|
||||
bool _assistiveTechnologyEnabled = false;
|
||||
|
||||
/// A callback that is invoked when the value of [assistiveTechnologyEnabled]
|
||||
/// changes.
|
||||
///
|
||||
/// The framework invokes this callback in the same zone in which the callback
|
||||
/// was set.
|
||||
VoidCallback get onAssistiveTechnologyEnabled => _onAssistiveTechnologyEnabled;
|
||||
VoidCallback _onAssistiveTechnologyEnabled;
|
||||
Zone _onAssistiveTechnologyEnabledZone;
|
||||
set onAssistiveTechnologyEnabled(VoidCallback callback) {
|
||||
_onAssistiveTechnologyEnabled = callback;
|
||||
_onAssistiveTechnologyEnabledZone = Zone.current;
|
||||
}
|
||||
|
||||
/// A callback that is invoked when the value of [semanticsEnabled] changes.
|
||||
///
|
||||
/// The framework invokes this callback in the same zone in which the
|
||||
|
||||
@ -199,6 +199,16 @@ void Window::UpdateSemanticsEnabled(bool enabled) {
|
||||
{ToDart(enabled)});
|
||||
}
|
||||
|
||||
void Window::UpdateAssistiveTechnologyEnabled(bool enabled) {
|
||||
tonic::DartState* dart_state = library_.dart_state().get();
|
||||
if (!dart_state)
|
||||
return;
|
||||
tonic::DartState::Scope scope(dart_state);
|
||||
|
||||
DartInvokeField(library_.value(), "_updateAssistiveTechnologyEnabled",
|
||||
{ToDart(enabled)});
|
||||
}
|
||||
|
||||
void Window::DispatchPlatformMessage(fxl::RefPtr<PlatformMessage> message) {
|
||||
tonic::DartState* dart_state = library_.dart_state().get();
|
||||
if (!dart_state)
|
||||
|
||||
@ -54,6 +54,7 @@ class Window final {
|
||||
const std::string& country_code);
|
||||
void UpdateUserSettingsData(const std::string& data);
|
||||
void UpdateSemanticsEnabled(bool enabled);
|
||||
void UpdateAssistiveTechnologyEnabled(bool enabled);
|
||||
void DispatchPlatformMessage(fxl::RefPtr<PlatformMessage> message);
|
||||
void DispatchPointerDataPacket(const PointerDataPacket& packet);
|
||||
void DispatchSemanticsAction(int32_t id,
|
||||
|
||||
@ -122,7 +122,8 @@ std::unique_ptr<RuntimeController> RuntimeController::Clone() const {
|
||||
bool RuntimeController::FlushRuntimeStateToIsolate() {
|
||||
return SetViewportMetrics(window_data_.viewport_metrics) &&
|
||||
SetLocale(window_data_.language_code, window_data_.country_code) &&
|
||||
SetSemanticsEnabled(window_data_.semantics_enabled);
|
||||
SetSemanticsEnabled(window_data_.semantics_enabled) &&
|
||||
SetAssistiveTechnologyEnabled(window_data_.assistive_technology_enabled);
|
||||
}
|
||||
|
||||
bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) {
|
||||
@ -170,6 +171,16 @@ bool RuntimeController::SetSemanticsEnabled(bool enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RuntimeController::SetAssistiveTechnologyEnabled(bool enabled) {
|
||||
window_data_.assistive_technology_enabled = enabled;
|
||||
if (auto window = GetWindowIfAvailable()) {
|
||||
window->UpdateAssistiveTechnologyEnabled(window_data_.assistive_technology_enabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RuntimeController::BeginFrame(fxl::TimePoint frame_time) {
|
||||
if (auto window = GetWindowIfAvailable()) {
|
||||
window->BeginFrame(frame_time);
|
||||
|
||||
@ -47,6 +47,8 @@ class RuntimeController final : public WindowClient {
|
||||
|
||||
bool SetSemanticsEnabled(bool enabled);
|
||||
|
||||
bool SetAssistiveTechnologyEnabled(bool enabled);
|
||||
|
||||
bool BeginFrame(fxl::TimePoint frame_time);
|
||||
|
||||
bool NotifyIdle(int64_t deadline);
|
||||
@ -80,6 +82,7 @@ class RuntimeController final : public WindowClient {
|
||||
std::string country_code;
|
||||
std::string user_settings_data = "{}";
|
||||
bool semantics_enabled = false;
|
||||
bool assistive_technology_enabled = false;
|
||||
};
|
||||
|
||||
RuntimeDelegate& client_;
|
||||
|
||||
@ -339,6 +339,10 @@ void Engine::SetSemanticsEnabled(bool enabled) {
|
||||
runtime_controller_->SetSemanticsEnabled(enabled);
|
||||
}
|
||||
|
||||
void Engine::SetAssistiveTechnologyEnabled(bool enabled) {
|
||||
runtime_controller_->SetAssistiveTechnologyEnabled(enabled);
|
||||
}
|
||||
|
||||
void Engine::StopAnimator() {
|
||||
animator_->Stop();
|
||||
}
|
||||
|
||||
@ -99,6 +99,8 @@ class Engine final : public blink::RuntimeDelegate {
|
||||
|
||||
void SetSemanticsEnabled(bool enabled);
|
||||
|
||||
void SetAssistiveTechnologyEnabled(bool enabled);
|
||||
|
||||
void ScheduleFrame(bool regenerate_layer_tree = true) override;
|
||||
|
||||
// |blink::RuntimeDelegate|
|
||||
|
||||
@ -52,6 +52,10 @@ void PlatformView::SetSemanticsEnabled(bool enabled) {
|
||||
delegate_.OnPlatformViewSetSemanticsEnabled(*this, enabled);
|
||||
}
|
||||
|
||||
void PlatformView::SetAssistiveTechnologyEnabled(bool enabled) {
|
||||
delegate_.OnPlatformViewSetAssistiveTechnologyEnabled(*this, enabled);
|
||||
}
|
||||
|
||||
void PlatformView::SetViewportMetrics(const blink::ViewportMetrics& metrics) {
|
||||
delegate_.OnPlatformViewSetViewportMetrics(*this, metrics);
|
||||
}
|
||||
|
||||
@ -58,6 +58,9 @@ class PlatformView {
|
||||
virtual void OnPlatformViewSetSemanticsEnabled(const PlatformView& view,
|
||||
bool enabled) = 0;
|
||||
|
||||
virtual void OnPlatformViewSetAssistiveTechnologyEnabled(const PlatformView& view,
|
||||
bool enabled) = 0;
|
||||
|
||||
virtual void OnPlatformViewRegisterTexture(
|
||||
const PlatformView& view,
|
||||
std::shared_ptr<flow::Texture> texture) = 0;
|
||||
@ -84,6 +87,8 @@ class PlatformView {
|
||||
|
||||
virtual void SetSemanticsEnabled(bool enabled);
|
||||
|
||||
virtual void SetAssistiveTechnologyEnabled(bool enabled);
|
||||
|
||||
void SetViewportMetrics(const blink::ViewportMetrics& metrics);
|
||||
|
||||
void NotifyCreated();
|
||||
|
||||
@ -574,6 +574,20 @@ void Shell::OnPlatformViewSetSemanticsEnabled(const PlatformView& view,
|
||||
});
|
||||
}
|
||||
|
||||
void Shell::OnPlatformViewSetAssistiveTechnologyEnabled(const PlatformView& view,
|
||||
bool enabled) {
|
||||
FXL_DCHECK(is_setup_);
|
||||
FXL_DCHECK(&view == platform_view_.get());
|
||||
FXL_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
|
||||
|
||||
task_runners_.GetUITaskRunner()->PostTask(
|
||||
[engine = engine_->GetWeakPtr(), enabled] {
|
||||
if (engine) {
|
||||
engine->SetAssistiveTechnologyEnabled(enabled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// |shell::PlatformView::Delegate|
|
||||
void Shell::OnPlatformViewRegisterTexture(
|
||||
const PlatformView& view,
|
||||
|
||||
@ -149,6 +149,10 @@ class Shell final : public PlatformView::Delegate,
|
||||
void OnPlatformViewSetSemanticsEnabled(const PlatformView& view,
|
||||
bool enabled) override;
|
||||
|
||||
// |shell::PlatformView::Delegate|
|
||||
void OnPlatformViewSetAssistiveTechnologyEnabled(const PlatformView& view,
|
||||
bool enabled) override;
|
||||
|
||||
// |shell::PlatformView::Delegate|
|
||||
void OnPlatformViewRegisterTexture(
|
||||
const PlatformView& view,
|
||||
|
||||
@ -669,6 +669,9 @@ public class FlutterView extends SurfaceView
|
||||
|
||||
private static native void nativeSetSemanticsEnabled(long nativePlatformViewAndroid,
|
||||
boolean enabled);
|
||||
|
||||
private static native void nativeSetAssistiveTechnologyEnabled(long nativePlatformViewAndroid,
|
||||
boolean enabled);
|
||||
|
||||
private static native boolean nativeGetIsSoftwareRenderingEnabled();
|
||||
|
||||
@ -812,11 +815,13 @@ public class FlutterView extends SurfaceView
|
||||
if (enabled) {
|
||||
mTouchExplorationEnabled = true;
|
||||
ensureAccessibilityEnabled();
|
||||
nativeSetAssistiveTechnologyEnabled(mNativeView.get(), true);
|
||||
} else {
|
||||
mTouchExplorationEnabled = false;
|
||||
if (mAccessibilityNodeProvider != null) {
|
||||
mAccessibilityNodeProvider.handleTouchExplorationExit();
|
||||
}
|
||||
nativeSetAssistiveTechnologyEnabled(mNativeView.get(), false);
|
||||
}
|
||||
resetWillNotDraw();
|
||||
}
|
||||
|
||||
@ -429,6 +429,13 @@ static void SetSemanticsEnabled(JNIEnv* env,
|
||||
ANDROID_SHELL_HOLDER->GetPlatformView()->SetSemanticsEnabled(enabled);
|
||||
}
|
||||
|
||||
static void SetAssistiveTechnologyEnabled(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong shell_holder,
|
||||
jboolean enabled) {
|
||||
ANDROID_SHELL_HOLDER->GetPlatformView()->SetAssistiveTechnologyEnabled(enabled);
|
||||
}
|
||||
|
||||
static jboolean GetIsSoftwareRendering(JNIEnv* env, jobject jcaller) {
|
||||
return FlutterMain::Get().GetSettings().enable_software_rendering;
|
||||
}
|
||||
@ -600,6 +607,11 @@ bool PlatformViewAndroid::Register(JNIEnv* env) {
|
||||
.signature = "(JZ)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SetSemanticsEnabled),
|
||||
},
|
||||
{
|
||||
.name = "nativeSetAssistiveTechnologyEnabled",
|
||||
.signature = "(JZ)V",
|
||||
.fnPtr = reinterpret_cast<void*>(&shell::SetAssistiveTechnologyEnabled),
|
||||
},
|
||||
{
|
||||
.name = "nativeGetIsSoftwareRenderingEnabled",
|
||||
.signature = "()Z",
|
||||
|
||||
@ -792,16 +792,18 @@ static inline blink::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* to
|
||||
#pragma mark - Accessibility
|
||||
|
||||
- (void)onAccessibilityStatusChanged:(NSNotification*)notification {
|
||||
auto platformView = _shell->GetPlatformView();
|
||||
#if TARGET_OS_SIMULATOR
|
||||
// There doesn't appear to be any way to determine whether the accessibility
|
||||
// inspector is enabled on the simulator. We conservatively always turn on the
|
||||
// accessibility bridge in the simulator.
|
||||
bool enabled = true;
|
||||
// accessibility bridge in the simulator, but never assistive technology.
|
||||
platformView->SetSemanticsEnabled(true);
|
||||
platformView->SetAssistiveTechnologyEnabled(false);
|
||||
#else
|
||||
bool enabled = UIAccessibilityIsVoiceOverRunning() || UIAccessibilityIsSwitchControlRunning() ||
|
||||
UIAccessibilityIsSpeakScreenEnabled();
|
||||
bool enabled = UIAccessibilityIsVoiceOverRunning() || UIAccessibilityIsSwitchControlRunning();
|
||||
platformView->SetSemanticsEnabled(enabled || UIAccessibilityIsSpeakScreenEnabled());
|
||||
platformView->SetAssistiveTechnologyEnabled(enabled);
|
||||
#endif
|
||||
_shell->GetPlatformView()->SetSemanticsEnabled(enabled);
|
||||
}
|
||||
|
||||
#pragma mark - Memory Notifications
|
||||
|
||||
@ -57,6 +57,12 @@ class PlatformViewIOS final : public HeadlessPlatformViewIOS {
|
||||
// |shell::PlatformView|
|
||||
void SetSemanticsEnabled(bool enabled) override;
|
||||
|
||||
// |shell::PlatformView|
|
||||
void SetAssistiveTechnologyEnabled(bool enabled) override;
|
||||
|
||||
// |shell::PlatformView|
|
||||
void HandlePlatformMessage(
|
||||
fxl::RefPtr<blink::PlatformMessage> message) override;
|
||||
|
||||
// |shell::PlatformView|
|
||||
void UpdateSemantics(blink::SemanticsNodeUpdates update,
|
||||
|
||||
@ -67,6 +67,17 @@ void PlatformViewIOS::SetSemanticsEnabled(bool enabled) {
|
||||
PlatformView::SetSemanticsEnabled(enabled);
|
||||
}
|
||||
|
||||
// |shell:PlatformView|
|
||||
void PlatformViewIOS::SetAssistiveTechnologyEnabled(bool enabled) {
|
||||
if (enabled && !accessibility_bridge_) {
|
||||
accessibility_bridge_ = std::make_unique<AccessibilityBridge>(owner_view_, this);
|
||||
}
|
||||
// Note: since the accessibility bridge is needed for both semantics and
|
||||
// assistive technologies, but you cannot have the latter without the
|
||||
// former, we only destroy the bridge in SetSemanticsEnabled and not here.
|
||||
PlatformView::SetAssistiveTechnologyEnabled(enabled);
|
||||
}
|
||||
|
||||
// |shell::PlatformView|
|
||||
void PlatformViewIOS::UpdateSemantics(blink::SemanticsNodeUpdates update,
|
||||
blink::CustomAccessibilityActionUpdates actions) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user