Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(541)

Unified Diff: ui/views/accessibility/native_view_accessibility_win.cc

Issue 266963002: Expose an accessible relation between the main window and active alert. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ia2_1-3
Patch Set: Address feedback Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/views/accessibility/native_view_accessibility_win.cc
diff --git a/ui/views/accessibility/native_view_accessibility_win.cc b/ui/views/accessibility/native_view_accessibility_win.cc
index 10c17ff3d6d636f153644cf34b0ece332e4d2a6a..241087d84f54fc19ac0b7e2891cd6715b90da306 100644
--- a/ui/views/accessibility/native_view_accessibility_win.cc
+++ b/ui/views/accessibility/native_view_accessibility_win.cc
@@ -189,6 +189,7 @@ void AccessibleWebViewRegistry::QueryIAccessible2Interface(View* web_view) {
long NativeViewAccessibilityWin::next_unique_id_ = 1;
int NativeViewAccessibilityWin::view_storage_ids_[kMaxViewStorageIds] = {0};
int NativeViewAccessibilityWin::next_view_storage_id_index_ = 0;
+std::vector<int> NativeViewAccessibilityWin::alert_target_view_storage_ids_;
// static
NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
@@ -210,6 +211,7 @@ NativeViewAccessibilityWin::NativeViewAccessibilityWin()
}
NativeViewAccessibilityWin::~NativeViewAccessibilityWin() {
+ RemoveAlertTarget();
}
void NativeViewAccessibilityWin::NotifyAccessibilityEvent(
@@ -236,6 +238,10 @@ void NativeViewAccessibilityWin::NotifyAccessibilityEvent(
::NotifyWinEvent(MSAAEvent(event_type), hwnd, OBJID_CLIENT, child_id);
next_view_storage_id_index_ =
(next_view_storage_id_index_ + 1) % kMaxViewStorageIds;
+
+ // Keep track of views that are a target of an alert event.
+ if (event_type == ui::AX_EVENT_ALERT)
+ AddAlertTarget();
}
gfx::NativeViewAccessible NativeViewAccessibilityWin::GetNativeObject() {
@@ -865,6 +871,59 @@ STDMETHODIMP NativeViewAccessibilityWin::get_windowHandle(HWND* window_handle) {
return *window_handle ? S_OK : S_FALSE;
}
+STDMETHODIMP NativeViewAccessibilityWin::get_relationTargetsOfType(
+ BSTR type_bstr,
+ long max_targets,
+ IUnknown ***targets,
+ long *n_targets) {
+ if (!view_)
+ return E_FAIL;
+
+ if (!targets || !n_targets)
+ return E_INVALIDARG;
+
+ *n_targets = 0;
+ *targets = NULL;
+
+ // Only respond to requests for relations of type "alerts" on the
+ // root view.
+ base::string16 type(type_bstr);
+ if (type != L"alerts" || view_->parent())
+ return S_FALSE;
+
+ // Collect all of the alert views that are still valid.
+ std::vector<View*> alert_views;
+ ViewStorage* view_storage = ViewStorage::GetInstance();
+ for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) {
+ int view_storage_id = alert_target_view_storage_ids_[i];
+ View* view = view_storage->RetrieveView(view_storage_id);
+ if (!view || !view_->Contains(view))
+ continue;
+ alert_views.push_back(view);
+ }
+
+ long count = alert_views.size();
+ if (count == 0)
+ return S_FALSE;
+
+ // Don't return more targets than max_targets - but note that the caller
+ // is allowed to specify max_targets=0 to mean no limit.
+ if (max_targets > 0 && count > max_targets)
+ count = max_targets;
+
+ // Return the number of targets.
+ *n_targets = count;
+
+ // Allocate COM memory for the result array and populate it.
+ *targets = static_cast<IUnknown**>(
+ CoTaskMemAlloc(count * sizeof(IUnknown*)));
+ for (long i = 0; i < count; ++i) {
+ (*targets)[i] = alert_views[i]->GetNativeViewAccessible();
+ (*targets)[i]->AddRef();
+ }
+ return S_OK;
+}
+
//
// IAccessibleText
//
@@ -1071,11 +1130,12 @@ STDMETHODIMP NativeViewAccessibilityWin::QueryService(
if (!view_)
return E_FAIL;
- if (riid == IID_IAccessible2)
+ if (riid == IID_IAccessible2 || riid == IID_IAccessible2_2)
AccessibleWebViewRegistry::GetInstance()->EnableIAccessible2Support();
if (guidService == IID_IAccessible ||
guidService == IID_IAccessible2 ||
+ guidService == IID_IAccessible2_2 ||
guidService == IID_IAccessibleText) {
return QueryInterface(riid, object);
}
@@ -1412,4 +1472,32 @@ void NativeViewAccessibilityWin::PopulateChildWidgetVector(
}
}
+void NativeViewAccessibilityWin::AddAlertTarget() {
+ ViewStorage* view_storage = ViewStorage::GetInstance();
+ for (size_t i = 0; i < alert_target_view_storage_ids_.size(); ++i) {
+ int view_storage_id = alert_target_view_storage_ids_[i];
+ View* view = view_storage->RetrieveView(view_storage_id);
+ if (view == view_)
+ return;
+ }
+ int view_storage_id = view_storage->CreateStorageID();
+ view_storage->StoreView(view_storage_id, view_);
+ alert_target_view_storage_ids_.push_back(view_storage_id);
+}
+
+void NativeViewAccessibilityWin::RemoveAlertTarget() {
+ ViewStorage* view_storage = ViewStorage::GetInstance();
+ size_t i = 0;
+ while (i < alert_target_view_storage_ids_.size()) {
+ int view_storage_id = alert_target_view_storage_ids_[i];
+ View* view = view_storage->RetrieveView(view_storage_id);
+ if (view == NULL || view == view_) {
+ alert_target_view_storage_ids_.erase(
+ alert_target_view_storage_ids_.begin() + i);
+ } else {
+ ++i;
+ }
+ }
+}
+
} // namespace views

Powered by Google App Engine
This is Rietveld 408576698