summaryrefslogtreecommitdiffstats
path: root/views/accessibility/view_accessibility_wrapper.cc
blob: 989c90a6ad75bec5dd4657941df3d55613aad477 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "views/accessibility/view_accessibility_wrapper.h"

#include "base/scoped_variant_win.h"

#include "views/accessibility/view_accessibility.h"

////////////////////////////////////////////////////////////////////////////////
//
// ViewAccessibilityWrapper - constructors, destructors
//
////////////////////////////////////////////////////////////////////////////////

ViewAccessibilityWrapper::ViewAccessibilityWrapper(views::View* view)
    : accessibility_info_(NULL),
      view_(view) {
}

STDMETHODIMP ViewAccessibilityWrapper::CreateDefaultInstance(REFIID iid) {
  if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
    // If there is no instance of ViewAccessibility created, create it
    // now. Otherwise reuse previous instance.
    if (!accessibility_info_) {
      CComObject<ViewAccessibility>* instance = NULL;

      HRESULT hr = CComObject<ViewAccessibility>::CreateInstance(&instance);

      if (!SUCCEEDED(hr) || !instance)
        return E_FAIL;

      ScopedComPtr<IAccessible> accessibility_instance(instance);

      if (!SUCCEEDED(instance->Initialize(view_)))
        return E_FAIL;

      // All is well, assign the temp instance to the class smart pointer.
      accessibility_info_.Attach(accessibility_instance.Detach());
    }
    return S_OK;
  }
  // Interface not supported.
  return E_NOINTERFACE;
}

HRESULT ViewAccessibilityWrapper::Uninitialize() {
  view_ = NULL;
  if (accessibility_info_.get()) {
    accessibility_info_->put_accValue(
        ScopedVariant(kViewsUninitializeAccessibilityInstance), NULL);
    ::CoDisconnectObject(accessibility_info_.get(), 0);
    accessibility_info_ = NULL;
  }

  return S_OK;
}

STDMETHODIMP ViewAccessibilityWrapper::GetInstance(REFIID iid,
                                                   void** interface_ptr) {
  if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
    // If there is no accessibility instance created, create a default now.
    // Otherwise reuse previous instance.
    if (!accessibility_info_) {
      HRESULT hr = CreateDefaultInstance(iid);

      if (hr != S_OK) {
        // Interface creation failed.
        *interface_ptr = NULL;
        return E_NOINTERFACE;
      }
    }
    *interface_ptr = static_cast<IAccessible*>(accessibility_info_);
    return S_OK;
  }
  // No supported interface found, return error.
  *interface_ptr = NULL;
  return E_NOINTERFACE;
}

STDMETHODIMP ViewAccessibilityWrapper::SetInstance(IAccessible* interface_ptr) {
  if (!interface_ptr)
    return E_NOINTERFACE;

  accessibility_info_.Attach(interface_ptr);

  // Paranoia check, to make sure we do have a valid IAccessible pointer stored.
  if (!accessibility_info_)
    return E_FAIL;

  return S_OK;
}