Commit 5577792a authored by Matthew Duggan's avatar Matthew Duggan Committed by Commit Bot

Update magnifier focus for focus changes in Arc windows.

This requires intents to ensure the ArcAccessibilityHelperService
is enabled in Android, and the editability of the control to be passed
through to the MagnificationManager.

To work with no other accessibility features are enabled, this also
requires the Android side change: http://ag/12532278

This change will still be safe to merge without that change, as the
intents will just be ignored.

BUG=b:167133958
TEST=Manual (tab around apps and observe magnifier,
enable and disable magnifier and other accessibility features)
R=hirokisato@chromium.org, sarakato@chromium.org
AX-Relnotes: Magnifier now follows focus in Android apps.

Change-Id: I2fd1a7145be3475a9c288715c4d442f6bc035c57
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2389802
Commit-Queue: Matthew Duggan <mduggan@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Reviewed-by: default avatarDavid Jacobo <djacobo@chromium.org>
Reviewed-by: default avatarSara Kato <sarakato@chromium.org>
Reviewed-by: default avatarHiroki Sato <hirokisato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806904}
parent e4eacd09
...@@ -507,9 +507,14 @@ void AccessibilityManager::OnLocaleChanged() { ...@@ -507,9 +507,14 @@ void AccessibilityManager::OnLocaleChanged() {
EnableSpokenFeedback(true); EnableSpokenFeedback(true);
} }
void AccessibilityManager::OnViewFocusedInArc( void AccessibilityManager::OnViewFocusedInArc(const gfx::Rect& bounds_in_screen,
const gfx::Rect& bounds_in_screen) { bool is_editable) {
ash::AccessibilityController::Get()->SetFocusHighlightRect(bounds_in_screen); ash::AccessibilityController::Get()->SetFocusHighlightRect(bounds_in_screen);
MagnificationManager* magnification_manager = MagnificationManager::Get();
if (magnification_manager)
magnification_manager->HandleFocusedRectChangedIfEnabled(bounds_in_screen,
is_editable);
} }
bool AccessibilityManager::PlayEarcon(int sound_key, PlaySoundOption option) { bool AccessibilityManager::PlayEarcon(int sound_key, PlaySoundOption option) {
......
...@@ -253,8 +253,8 @@ class AccessibilityManager ...@@ -253,8 +253,8 @@ class AccessibilityManager
// Play tick sound indicating spoken feedback will be toggled after countdown. // Play tick sound indicating spoken feedback will be toggled after countdown.
bool PlaySpokenFeedbackToggleCountdown(int tick_count); bool PlaySpokenFeedbackToggleCountdown(int tick_count);
// Notify that a view is focused in arc. // Update when a view is focused in ARC++.
void OnViewFocusedInArc(const gfx::Rect& bounds_in_screen); void OnViewFocusedInArc(const gfx::Rect& bounds_in_screen, bool is_editable);
// Plays an earcon. Earcons are brief and distinctive sounds that indicate // Plays an earcon. Earcons are brief and distinctive sounds that indicate
// the their mapped event has occurred. The |sound_key| enums can be found in // the their mapped event has occurred. The |sound_key| enums can be found in
......
...@@ -99,6 +99,15 @@ void MagnificationManager::OnProfileWillBeDestroyed(Profile* profile) { ...@@ -99,6 +99,15 @@ void MagnificationManager::OnProfileWillBeDestroyed(Profile* profile) {
SetProfile(nullptr); SetProfile(nullptr);
} }
void MagnificationManager::HandleFocusedRectChangedIfEnabled(
const gfx::Rect& bounds_in_screen,
bool is_editable) {
if (!fullscreen_magnifier_enabled_ && !IsDockedMagnifierEnabled())
return;
HandleFocusChanged(bounds_in_screen, is_editable);
}
void MagnificationManager::OnViewEvent(views::View* view, void MagnificationManager::OnViewEvent(views::View* view,
ax::mojom::Event event_type) { ax::mojom::Event event_type) {
if (!fullscreen_magnifier_enabled_ && !IsDockedMagnifierEnabled()) if (!fullscreen_magnifier_enabled_ && !IsDockedMagnifierEnabled())
......
...@@ -64,6 +64,10 @@ class MagnificationManager ...@@ -64,6 +64,10 @@ class MagnificationManager
// Loads the Fullscreen magnifier scale from the pref. // Loads the Fullscreen magnifier scale from the pref.
double GetSavedScreenMagnifierScale() const; double GetSavedScreenMagnifierScale() const;
// Updates for a new focus rect (eg, from ARC++) if a magnifier is enabled.
void HandleFocusedRectChangedIfEnabled(const gfx::Rect& bounds_in_screen,
bool is_editable);
// ProfileObserver: // ProfileObserver:
void OnProfileWillBeDestroyed(Profile* profile) override; void OnProfileWillBeDestroyed(Profile* profile) override;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "chrome/browser/chromeos/accessibility/magnification_manager.h"
#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h"
#include "chrome/browser/chromeos/arc/accessibility/geometry_util.h" #include "chrome/browser/chromeos/arc/accessibility/geometry_util.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -96,7 +97,10 @@ void DispatchFocusChange(arc::mojom::AccessibilityNodeInfoData* node_data, ...@@ -96,7 +97,10 @@ void DispatchFocusChange(arc::mojom::AccessibilityNodeInfoData* node_data,
node_data->bounds_in_screen, node_data->bounds_in_screen,
views::Widget::GetWidgetForNativeView(active_window))); views::Widget::GetWidgetForNativeView(active_window)));
accessibility_manager->OnViewFocusedInArc(bounds_in_screen); bool is_editable = arc::GetBooleanProperty(
node_data, arc::mojom::AccessibilityBooleanProperty::EDITABLE);
accessibility_manager->OnViewFocusedInArc(bounds_in_screen, is_editable);
} }
void SetChildAxTreeIDForWindow(aura::Window* window, void SetChildAxTreeIDForWindow(aura::Window* window,
...@@ -613,7 +617,10 @@ arc::mojom::AccessibilityFilterType ...@@ -613,7 +617,10 @@ arc::mojom::AccessibilityFilterType
ArcAccessibilityHelperBridge::GetFilterTypeForProfile(Profile* profile) { ArcAccessibilityHelperBridge::GetFilterTypeForProfile(Profile* profile) {
chromeos::AccessibilityManager* accessibility_manager = chromeos::AccessibilityManager* accessibility_manager =
chromeos::AccessibilityManager::Get(); chromeos::AccessibilityManager::Get();
if (!accessibility_manager) const chromeos::MagnificationManager* magnification_manager =
chromeos::MagnificationManager::Get();
if (!accessibility_manager || !magnification_manager)
return arc::mojom::AccessibilityFilterType::OFF; return arc::mojom::AccessibilityFilterType::OFF;
// TODO(yawano): Support the case where primary user is in background. // TODO(yawano): Support the case where primary user is in background.
...@@ -626,8 +633,12 @@ ArcAccessibilityHelperBridge::GetFilterTypeForProfile(Profile* profile) { ...@@ -626,8 +633,12 @@ ArcAccessibilityHelperBridge::GetFilterTypeForProfile(Profile* profile) {
return arc::mojom::AccessibilityFilterType::ALL; return arc::mojom::AccessibilityFilterType::ALL;
} }
if (accessibility_manager->IsFocusHighlightEnabled()) if (magnification_manager->IsMagnifierEnabled() ||
magnification_manager->IsDockedMagnifierEnabled() ||
accessibility_manager->IsFocusHighlightEnabled()) {
return arc::mojom::AccessibilityFilterType::FOCUS; return arc::mojom::AccessibilityFilterType::FOCUS;
}
return arc::mojom::AccessibilityFilterType::OFF; return arc::mojom::AccessibilityFilterType::OFF;
} }
...@@ -694,7 +705,11 @@ void ArcAccessibilityHelperBridge::OnAccessibilityStatusChanged( ...@@ -694,7 +705,11 @@ void ArcAccessibilityHelperBridge::OnAccessibilityStatusChanged(
event_details.notification_type != event_details.notification_type !=
chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK && chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK &&
event_details.notification_type != event_details.notification_type !=
chromeos::ACCESSIBILITY_TOGGLE_SWITCH_ACCESS) { chromeos::ACCESSIBILITY_TOGGLE_SWITCH_ACCESS &&
event_details.notification_type !=
chromeos::ACCESSIBILITY_TOGGLE_DOCKED_MAGNIFIER &&
event_details.notification_type !=
chromeos::ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFIER) {
return; return;
} }
...@@ -708,27 +723,33 @@ void ArcAccessibilityHelperBridge::OnAccessibilityStatusChanged( ...@@ -708,27 +723,33 @@ void ArcAccessibilityHelperBridge::OnAccessibilityStatusChanged(
} }
void ArcAccessibilityHelperBridge::UpdateEnabledFeature() { void ArcAccessibilityHelperBridge::UpdateEnabledFeature() {
arc::mojom::AccessibilityFilterType new_filter_type_ = arc::mojom::AccessibilityFilterType new_filter_type =
GetFilterTypeForProfile(profile_); GetFilterTypeForProfile(profile_);
// Clear trees when filter type is changed to non-ALL. // Clear trees when filter type is changed to non-ALL.
if (filter_type_ != new_filter_type_ &&
new_filter_type_ != arc::mojom::AccessibilityFilterType::ALL) { if (filter_type_ != new_filter_type &&
new_filter_type != arc::mojom::AccessibilityFilterType::ALL) {
trees_.clear(); trees_.clear();
} }
filter_type_ = new_filter_type_; filter_type_ = new_filter_type;
auto* instance = ARC_GET_INSTANCE_FOR_METHOD( auto* instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->accessibility_helper(), SetFilter); arc_bridge_service_->accessibility_helper(), SetFilter);
if (instance) if (instance)
instance->SetFilter(filter_type_); instance->SetFilter(filter_type_);
chromeos::AccessibilityManager* accessibility_manager = const chromeos::AccessibilityManager* accessibility_manager =
chromeos::AccessibilityManager::Get(); chromeos::AccessibilityManager::Get();
if (!accessibility_manager) const chromeos::MagnificationManager* magnification_manager =
chromeos::MagnificationManager::Get();
if (!accessibility_manager || !magnification_manager)
return; return;
is_focus_highlight_enabled_ = is_focus_event_enabled_ = magnification_manager->IsMagnifierEnabled() ||
magnification_manager->IsDockedMagnifierEnabled() ||
accessibility_manager->IsFocusHighlightEnabled(); accessibility_manager->IsFocusHighlightEnabled();
use_full_focus_mode_ = accessibility_manager->IsSwitchAccessEnabled() || use_full_focus_mode_ = accessibility_manager->IsSwitchAccessEnabled() ||
accessibility_manager->IsSpokenFeedbackEnabled(); accessibility_manager->IsSpokenFeedbackEnabled();
...@@ -923,7 +944,7 @@ void ArcAccessibilityHelperBridge::HandleFilterTypeAllEvent( ...@@ -923,7 +944,7 @@ void ArcAccessibilityHelperBridge::HandleFilterTypeAllEvent(
UpdateWindowProperties(GetActiveWindow()); UpdateWindowProperties(GetActiveWindow());
} }
if (is_focus_highlight_enabled_ && if (is_focus_event_enabled_ &&
event_data->event_type == event_data->event_type ==
arc::mojom::AccessibilityEventType::VIEW_FOCUSED) { arc::mojom::AccessibilityEventType::VIEW_FOCUSED) {
for (size_t i = 0; i < event_data->node_data.size(); ++i) { for (size_t i = 0; i < event_data->node_data.size(); ++i) {
......
...@@ -177,7 +177,7 @@ class ArcAccessibilityHelperBridge ...@@ -177,7 +177,7 @@ class ArcAccessibilityHelperBridge
AXTreeSourceArc* GetFromTreeId(ui::AXTreeID tree_id) const; AXTreeSourceArc* GetFromTreeId(ui::AXTreeID tree_id) const;
bool activation_observer_added_ = false; bool activation_observer_added_ = false;
bool is_focus_highlight_enabled_ = false; bool is_focus_event_enabled_ = false;
bool use_full_focus_mode_ = false; bool use_full_focus_mode_ = false;
Profile* const profile_; Profile* const profile_;
ArcBridgeService* const arc_bridge_service_; ArcBridgeService* const arc_bridge_service_;
......
...@@ -170,6 +170,7 @@ class ArcSettingsServiceImpl ...@@ -170,6 +170,7 @@ class ArcSettingsServiceImpl
void SyncAccessibilityLargeMouseCursorEnabled() const; void SyncAccessibilityLargeMouseCursorEnabled() const;
void SyncAccessibilityVirtualKeyboardEnabled() const; void SyncAccessibilityVirtualKeyboardEnabled() const;
void SyncBackupEnabled() const; void SyncBackupEnabled() const;
void SyncDockedMagnifierEnabled() const;
void SyncFocusHighlightEnabled() const; void SyncFocusHighlightEnabled() const;
void SyncLocale() const; void SyncLocale() const;
void SyncLocationServiceEnabled() const; void SyncLocationServiceEnabled() const;
...@@ -178,6 +179,7 @@ class ArcSettingsServiceImpl ...@@ -178,6 +179,7 @@ class ArcSettingsServiceImpl
void SyncProxySettingsForSystemProxy() const; void SyncProxySettingsForSystemProxy() const;
void SyncReportingConsent(bool initial_sync) const; void SyncReportingConsent(bool initial_sync) const;
void SyncPictureInPictureEnabled() const; void SyncPictureInPictureEnabled() const;
void SyncScreenMagnifierEnabled() const;
void SyncSelectToSpeakEnabled() const; void SyncSelectToSpeakEnabled() const;
void SyncSpokenFeedbackEnabled() const; void SyncSpokenFeedbackEnabled() const;
void SyncSwitchAccessEnabled() const; void SyncSwitchAccessEnabled() const;
...@@ -273,6 +275,8 @@ void ArcSettingsServiceImpl::OnPrefChanged(const std::string& pref_name) const { ...@@ -273,6 +275,8 @@ void ArcSettingsServiceImpl::OnPrefChanged(const std::string& pref_name) const {
SyncFocusHighlightEnabled(); SyncFocusHighlightEnabled();
} else if (pref_name == ash::prefs::kAccessibilityLargeCursorEnabled) { } else if (pref_name == ash::prefs::kAccessibilityLargeCursorEnabled) {
SyncAccessibilityLargeMouseCursorEnabled(); SyncAccessibilityLargeMouseCursorEnabled();
} else if (pref_name == ash::prefs::kAccessibilityScreenMagnifierEnabled) {
SyncScreenMagnifierEnabled();
} else if (pref_name == ash::prefs::kAccessibilitySelectToSpeakEnabled) { } else if (pref_name == ash::prefs::kAccessibilitySelectToSpeakEnabled) {
SyncSelectToSpeakEnabled(); SyncSelectToSpeakEnabled();
} else if (pref_name == ash::prefs::kAccessibilitySpokenFeedbackEnabled) { } else if (pref_name == ash::prefs::kAccessibilitySpokenFeedbackEnabled) {
...@@ -281,6 +285,8 @@ void ArcSettingsServiceImpl::OnPrefChanged(const std::string& pref_name) const { ...@@ -281,6 +285,8 @@ void ArcSettingsServiceImpl::OnPrefChanged(const std::string& pref_name) const {
SyncSwitchAccessEnabled(); SyncSwitchAccessEnabled();
} else if (pref_name == ash::prefs::kAccessibilityVirtualKeyboardEnabled) { } else if (pref_name == ash::prefs::kAccessibilityVirtualKeyboardEnabled) {
SyncAccessibilityVirtualKeyboardEnabled(); SyncAccessibilityVirtualKeyboardEnabled();
} else if (pref_name == ash::prefs::kDockedMagnifierEnabled) {
SyncDockedMagnifierEnabled();
} else if (pref_name == ::language::prefs::kApplicationLocale || } else if (pref_name == ::language::prefs::kApplicationLocale ||
pref_name == ::language::prefs::kPreferredLanguages) { pref_name == ::language::prefs::kPreferredLanguages) {
SyncLocale(); SyncLocale();
...@@ -344,10 +350,12 @@ void ArcSettingsServiceImpl::StartObservingSettingsChanges() { ...@@ -344,10 +350,12 @@ void ArcSettingsServiceImpl::StartObservingSettingsChanges() {
// Keep these lines ordered lexicographically. // Keep these lines ordered lexicographically.
AddPrefToObserve(ash::prefs::kAccessibilityFocusHighlightEnabled); AddPrefToObserve(ash::prefs::kAccessibilityFocusHighlightEnabled);
AddPrefToObserve(ash::prefs::kAccessibilityLargeCursorEnabled); AddPrefToObserve(ash::prefs::kAccessibilityLargeCursorEnabled);
AddPrefToObserve(ash::prefs::kAccessibilityScreenMagnifierEnabled);
AddPrefToObserve(ash::prefs::kAccessibilitySelectToSpeakEnabled); AddPrefToObserve(ash::prefs::kAccessibilitySelectToSpeakEnabled);
AddPrefToObserve(ash::prefs::kAccessibilitySpokenFeedbackEnabled); AddPrefToObserve(ash::prefs::kAccessibilitySpokenFeedbackEnabled);
AddPrefToObserve(ash::prefs::kAccessibilitySwitchAccessEnabled); AddPrefToObserve(ash::prefs::kAccessibilitySwitchAccessEnabled);
AddPrefToObserve(ash::prefs::kAccessibilityVirtualKeyboardEnabled); AddPrefToObserve(ash::prefs::kAccessibilityVirtualKeyboardEnabled);
AddPrefToObserve(ash::prefs::kDockedMagnifierEnabled);
AddPrefToObserve(::prefs::kResolveTimezoneByGeolocationMethod); AddPrefToObserve(::prefs::kResolveTimezoneByGeolocationMethod);
AddPrefToObserve(::prefs::kSystemProxyUserTrafficHostAndPort); AddPrefToObserve(::prefs::kSystemProxyUserTrafficHostAndPort);
AddPrefToObserve(::prefs::kUse24HourClock); AddPrefToObserve(::prefs::kUse24HourClock);
...@@ -390,10 +398,12 @@ void ArcSettingsServiceImpl::SyncBootTimeSettings() const { ...@@ -390,10 +398,12 @@ void ArcSettingsServiceImpl::SyncBootTimeSettings() const {
// Keep these lines ordered lexicographically. // Keep these lines ordered lexicographically.
SyncAccessibilityLargeMouseCursorEnabled(); SyncAccessibilityLargeMouseCursorEnabled();
SyncAccessibilityVirtualKeyboardEnabled(); SyncAccessibilityVirtualKeyboardEnabled();
SyncDockedMagnifierEnabled();
SyncFocusHighlightEnabled(); SyncFocusHighlightEnabled();
SyncProxySettings(); SyncProxySettings();
SyncReportingConsent(/*initial_sync=*/false); SyncReportingConsent(/*initial_sync=*/false);
SyncPictureInPictureEnabled(); SyncPictureInPictureEnabled();
SyncScreenMagnifierEnabled();
SyncSelectToSpeakEnabled(); SyncSelectToSpeakEnabled();
SyncSpokenFeedbackEnabled(); SyncSpokenFeedbackEnabled();
SyncSwitchAccessEnabled(); SyncSwitchAccessEnabled();
...@@ -457,6 +467,18 @@ void ArcSettingsServiceImpl::SyncFocusHighlightEnabled() const { ...@@ -457,6 +467,18 @@ void ArcSettingsServiceImpl::SyncFocusHighlightEnabled() const {
"org.chromium.arc.intent_helper.SET_FOCUS_HIGHLIGHT_ENABLED"); "org.chromium.arc.intent_helper.SET_FOCUS_HIGHLIGHT_ENABLED");
} }
void ArcSettingsServiceImpl::SyncScreenMagnifierEnabled() const {
SendBoolPrefSettingsBroadcast(
ash::prefs::kAccessibilityScreenMagnifierEnabled,
"org.chromium.arc.intent_helper.SET_SCREEN_MAGNIFIER_ENABLED");
}
void ArcSettingsServiceImpl::SyncDockedMagnifierEnabled() const {
SendBoolPrefSettingsBroadcast(
ash::prefs::kDockedMagnifierEnabled,
"org.chromium.arc.intent_helper.SET_DOCKED_MAGNIFIER_ENABLED");
}
void ArcSettingsServiceImpl::SyncLocale() const { void ArcSettingsServiceImpl::SyncLocale() const {
if (IsArcLocaleSyncDisabled()) { if (IsArcLocaleSyncDisabled()) {
VLOG(1) << "Locale sync is disabled."; VLOG(1) << "Locale sync is disabled.";
......
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