<commit_before>// Copyright (c) 2010 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 <oleacc.h>

#include "app/l10n_util.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"

namespace {

VARIANT id_self = {VT_I4, CHILDID_SELF};

// Dummy class to force creation of ATL module, needed by COM to instantiate
// ViewAccessibility.
class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {};
TestAtlModule test_atl_module_;

class BrowserViewsAccessibilityTest : public InProcessBrowserTest {
 public:
  BrowserViewsAccessibilityTest() {
    ::CoInitialize(NULL);
  }

  ~BrowserViewsAccessibilityTest() {
    ::CoUninitialize();
  }

  // Retrieves an instance of BrowserWindowTesting
  BrowserWindowTesting* GetBrowserWindowTesting() {
    BrowserWindow* browser_window = browser()->window();

    if (!browser_window)
      return NULL;

    return browser_window->GetBrowserWindowTesting();
  }

  // Retrieve an instance of BrowserView
  BrowserView* GetBrowserView() {
    return BrowserView::GetBrowserViewForNativeWindow(
               browser()->window()->GetNativeHandle());
  }

  // Retrieves and initializes an instance of LocationBarView.
  LocationBarView* GetLocationBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return GetBrowserWindowTesting()->GetLocationBarView();
  }

  // Retrieves and initializes an instance of ToolbarView.
  ToolbarView* GetToolbarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetToolbarView();
  }

  // Retrieves and initializes an instance of BookmarkBarView.
  BookmarkBarView* GetBookmarkBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetBookmarkBarView();
  }

  // Retrieves and verifies the accessibility object for the given View.
  void TestViewAccessibilityObject(views::View* view, std::wstring name,
                                   int32 role) {
    ASSERT_TRUE(NULL != view);

    IAccessible* acc_obj = NULL;
    HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance(
        IID_IAccessible, reinterpret_cast<void**>(&acc_obj));
    ASSERT_EQ(S_OK, hr);
    ASSERT_TRUE(NULL != acc_obj);

    TestAccessibilityInfo(acc_obj, name, role);
  }

  // Verifies MSAA Name and Role properties of the given IAccessible.
  void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name,
                             int32 role) {
    // Verify MSAA Name property.
    BSTR acc_name;

    HRESULT hr = acc_obj->get_accName(id_self, &acc_name);
    ASSERT_EQ(S_OK, hr);
    EXPECT_STREQ(acc_name, name.c_str());

    // Verify MSAA Role property.
    VARIANT acc_role;
    ::VariantInit(&acc_role);

    hr = acc_obj->get_accRole(id_self, &acc_role);
    ASSERT_EQ(S_OK, hr);
    EXPECT_EQ(VT_I4, acc_role.vt);
    EXPECT_EQ(role, acc_role.lVal);

    ::VariantClear(&acc_role);
    ::SysFreeString(acc_name);
  }
};

// Retrieve accessibility object for main window and verify accessibility info.
// Fails, http://crbug.com/44486.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       FAILS_TestChromeWindowAccObj) {
  BrowserWindow* browser_window = browser()->window();
  ASSERT_TRUE(NULL != browser_window);

  HWND hwnd = browser_window->GetNativeHandle();
  ASSERT_TRUE(NULL != hwnd);

  // Get accessibility object.
  ScopedComPtr<IAccessible> acc_obj;
  HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                            reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
  std::wstring title =
      l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT,
      ASCIIToWide(chrome::kAboutBlankURL));
  TestAccessibilityInfo(acc_obj, title, ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for non client view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) {
  views::View* non_client_view =
  GetBrowserView()->GetWindow()->GetNonClientView();

  TestViewAccessibilityObject(non_client_view,
      l10n_util::GetString(IDS_PRODUCT_NAME),
      ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for browser root view and verify
// accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBrowserRootViewAccObj) {
  views::View* browser_root_view =
      GetBrowserView()->frame()->GetFrameView()->GetRootView();

  TestViewAccessibilityObject(browser_root_view,
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_APPLICATION);
}

// Retrieve accessibility object for browser view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) {
  // Verify root view MSAA name and role.
  TestViewAccessibilityObject(GetBrowserView(),
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_CLIENT);
}

// Retrieve accessibility object for toolbar view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
  // Verify toolbar MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView(),
                              l10n_util::GetString(IDS_ACCNAME_TOOLBAR),
                              ROLE_SYSTEM_TOOLBAR);
}

// Retrieve accessibility object for Back button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
  // Verify Back button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Forward button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
  // Verify Forward button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Reload button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
  // Verify Reload button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Home button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
  // Verify Home button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Star button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestStarButtonAccObj) {
  // Verify Star button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for location bar view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestLocationBarViewAccObj) {
  // Verify location bar MSAA name and role.
  TestViewAccessibilityObject(GetLocationBarView(),
                              l10n_util::GetString(IDS_ACCNAME_LOCATION),
                              ROLE_SYSTEM_GROUPING);
}

// Retrieve accessibility object for Go button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) {
  // Verify Go button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON),
                              l10n_util::GetString(IDS_ACCNAME_GO),
                              ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Page menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) {
  // Verify Page menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU),
                              l10n_util::GetString(IDS_ACCNAME_PAGE),
                              ROLE_SYSTEM_BUTTONMENU);
}

// Retrieve accessibility object for App menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
  // Verify App menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
                              l10n_util::GetString(IDS_ACCNAME_APP),
                              ROLE_SYSTEM_BUTTONMENU);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBookmarkBarViewAccObj) {
  TestViewAccessibilityObject(GetBookmarkBarView(),
                              l10n_util::GetString(IDS_ACCNAME_BOOKMARKS),
                              ROLE_SYSTEM_TOOLBAR);
}

// Fails, http://crbug.com/44486.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       FAILS_TestAboutChromeViewAccObj) {
  //  Firstly, test that the WindowDelegate got updated.
  views::Window* aboutChromeWindow = GetBrowserView()->ShowAboutChromeDialog();
  EXPECT_STREQ(aboutChromeWindow->GetDelegate()->GetWindowTitle().c_str(),
               l10n_util::GetString(IDS_ABOUT_CHROME_TITLE).c_str());
  EXPECT_EQ(aboutChromeWindow->GetDelegate()->accessible_role(),
            AccessibilityTypes::ROLE_DIALOG);

  // Also test the accessibility object directly.
  IAccessible* acc_obj = NULL;
  HRESULT hr =
    ::AccessibleObjectFromWindow(aboutChromeWindow->GetNativeWindow(),
                                 OBJID_CLIENT,
                                 IID_IAccessible,
                                 reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_ABOUT_CHROME_TITLE),
                        ROLE_SYSTEM_DIALOG);

  acc_obj->Release();
}
}  // Namespace.

<commit_msg>Re-enabling TestAboutChromeViewAccObj.<commit_after>// Copyright (c) 2010 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 <oleacc.h>

#include "app/l10n_util.h"
#include "base/scoped_comptr_win.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "views/accessibility/view_accessibility_wrapper.h"
#include "views/widget/root_view.h"
#include "views/widget/widget_win.h"
#include "views/window/window.h"

namespace {

VARIANT id_self = {VT_I4, CHILDID_SELF};

// Dummy class to force creation of ATL module, needed by COM to instantiate
// ViewAccessibility.
class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {};
TestAtlModule test_atl_module_;

class BrowserViewsAccessibilityTest : public InProcessBrowserTest {
 public:
  BrowserViewsAccessibilityTest() {
    ::CoInitialize(NULL);
  }

  ~BrowserViewsAccessibilityTest() {
    ::CoUninitialize();
  }

  // Retrieves an instance of BrowserWindowTesting
  BrowserWindowTesting* GetBrowserWindowTesting() {
    BrowserWindow* browser_window = browser()->window();

    if (!browser_window)
      return NULL;

    return browser_window->GetBrowserWindowTesting();
  }

  // Retrieve an instance of BrowserView
  BrowserView* GetBrowserView() {
    return BrowserView::GetBrowserViewForNativeWindow(
               browser()->window()->GetNativeHandle());
  }

  // Retrieves and initializes an instance of LocationBarView.
  LocationBarView* GetLocationBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return GetBrowserWindowTesting()->GetLocationBarView();
  }

  // Retrieves and initializes an instance of ToolbarView.
  ToolbarView* GetToolbarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetToolbarView();
  }

  // Retrieves and initializes an instance of BookmarkBarView.
  BookmarkBarView* GetBookmarkBarView() {
    BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting();

    if (!browser_window_testing)
      return NULL;

    return browser_window_testing->GetBookmarkBarView();
  }

  // Retrieves and verifies the accessibility object for the given View.
  void TestViewAccessibilityObject(views::View* view, std::wstring name,
                                   int32 role) {
    ASSERT_TRUE(NULL != view);

    IAccessible* acc_obj = NULL;
    HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance(
        IID_IAccessible, reinterpret_cast<void**>(&acc_obj));
    ASSERT_EQ(S_OK, hr);
    ASSERT_TRUE(NULL != acc_obj);

    TestAccessibilityInfo(acc_obj, name, role);
  }

  // Verifies MSAA Name and Role properties of the given IAccessible.
  void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name,
                             int32 role) {
    // Verify MSAA Name property.
    BSTR acc_name;

    HRESULT hr = acc_obj->get_accName(id_self, &acc_name);
    ASSERT_EQ(S_OK, hr);
    EXPECT_STREQ(acc_name, name.c_str());

    // Verify MSAA Role property.
    VARIANT acc_role;
    ::VariantInit(&acc_role);

    hr = acc_obj->get_accRole(id_self, &acc_role);
    ASSERT_EQ(S_OK, hr);
    EXPECT_EQ(VT_I4, acc_role.vt);
    EXPECT_EQ(role, acc_role.lVal);

    ::VariantClear(&acc_role);
    ::SysFreeString(acc_name);
  }
};

// Retrieve accessibility object for main window and verify accessibility info.
// Fails, http://crbug.com/44486.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       FAILS_TestChromeWindowAccObj) {
  BrowserWindow* browser_window = browser()->window();
  ASSERT_TRUE(NULL != browser_window);

  HWND hwnd = browser_window->GetNativeHandle();
  ASSERT_TRUE(NULL != hwnd);

  // Get accessibility object.
  ScopedComPtr<IAccessible> acc_obj;
  HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                            reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL));
  std::wstring title =
      l10n_util::GetStringF(IDS_BROWSER_WINDOW_TITLE_FORMAT,
      ASCIIToWide(chrome::kAboutBlankURL));
  TestAccessibilityInfo(acc_obj, title, ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for non client view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) {
  views::View* non_client_view =
  GetBrowserView()->GetWindow()->GetNonClientView();

  TestViewAccessibilityObject(non_client_view,
      l10n_util::GetString(IDS_PRODUCT_NAME),
      ROLE_SYSTEM_WINDOW);
}

// Retrieve accessibility object for browser root view and verify
// accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBrowserRootViewAccObj) {
  views::View* browser_root_view =
      GetBrowserView()->frame()->GetFrameView()->GetRootView();

  TestViewAccessibilityObject(browser_root_view,
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_APPLICATION);
}

// Retrieve accessibility object for browser view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) {
  // Verify root view MSAA name and role.
  TestViewAccessibilityObject(GetBrowserView(),
                              l10n_util::GetString(IDS_PRODUCT_NAME),
                              ROLE_SYSTEM_CLIENT);
}

// Retrieve accessibility object for toolbar view and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) {
  // Verify toolbar MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView(),
                              l10n_util::GetString(IDS_ACCNAME_TOOLBAR),
                              ROLE_SYSTEM_TOOLBAR);
}

// Retrieve accessibility object for Back button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) {
  // Verify Back button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Forward button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) {
  // Verify Forward button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN);
}

// Retrieve accessibility object for Reload button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) {
  // Verify Reload button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Home button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) {
  // Verify Home button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Star button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestStarButtonAccObj) {
  // Verify Star button MSAA name and role.
  TestViewAccessibilityObject(
      GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON),
      l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for location bar view and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestLocationBarViewAccObj) {
  // Verify location bar MSAA name and role.
  TestViewAccessibilityObject(GetLocationBarView(),
                              l10n_util::GetString(IDS_ACCNAME_LOCATION),
                              ROLE_SYSTEM_GROUPING);
}

// Retrieve accessibility object for Go button and verify accessibility info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) {
  // Verify Go button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON),
                              l10n_util::GetString(IDS_ACCNAME_GO),
                              ROLE_SYSTEM_PUSHBUTTON);
}

// Retrieve accessibility object for Page menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) {
  // Verify Page menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU),
                              l10n_util::GetString(IDS_ACCNAME_PAGE),
                              ROLE_SYSTEM_BUTTONMENU);
}

// Retrieve accessibility object for App menu button and verify accessibility
// info.
IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) {
  // Verify App menu button MSAA name and role.
  TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU),
                              l10n_util::GetString(IDS_ACCNAME_APP),
                              ROLE_SYSTEM_BUTTONMENU);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestBookmarkBarViewAccObj) {
  TestViewAccessibilityObject(GetBookmarkBarView(),
                              l10n_util::GetString(IDS_ACCNAME_BOOKMARKS),
                              ROLE_SYSTEM_TOOLBAR);
}

IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest,
                       TestAboutChromeViewAccObj) {
  //  Firstly, test that the WindowDelegate got updated.
  views::Window* aboutChromeWindow = GetBrowserView()->ShowAboutChromeDialog();
  EXPECT_STREQ(aboutChromeWindow->GetDelegate()->GetWindowTitle().c_str(),
               l10n_util::GetString(IDS_ABOUT_CHROME_TITLE).c_str());
  EXPECT_EQ(aboutChromeWindow->GetDelegate()->accessible_role(),
            AccessibilityTypes::ROLE_DIALOG);

  // Also test the accessibility object directly.
  IAccessible* acc_obj = NULL;
  HRESULT hr =
    ::AccessibleObjectFromWindow(aboutChromeWindow->GetNativeWindow(),
                                 OBJID_CLIENT,
                                 IID_IAccessible,
                                 reinterpret_cast<void**>(&acc_obj));
  ASSERT_EQ(S_OK, hr);
  ASSERT_TRUE(NULL != acc_obj);

  TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_ABOUT_CHROME_TITLE),
                        ROLE_SYSTEM_DIALOG);

  acc_obj->Release();
}
}  // Namespace.

<|endoftext|>


<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_DIRECTSOUND

#include <system_error>
#include <audiodefs.h>
#include "AudioDeviceDS.hpp"
#include "core/Engine.hpp"
#include "core/Window.hpp"
#include "core/windows/NativeWindowWin.hpp"
#include "utils/Log.hpp"
#include "utils/Utils.hpp"

BOOL CALLBACK enumCallback(LPGUID, LPCWSTR description, LPCWSTR, LPVOID)
{
    int bufferSize = WideCharToMultiByte(CP_UTF8, 0, description, -1, nullptr, 0, nullptr, nullptr);
    if (bufferSize != 0)
    {
        std::vector<char> buffer(bufferSize);
        if (WideCharToMultiByte(CP_UTF8, 0, description, -1, buffer.data(), bufferSize, nullptr, nullptr) != 0)
            ouzel::engine->log(ouzel::Log::Level::INFO) << "Using " << buffer.data() << " for audio";
    }
    return FALSE;
}

namespace ouzel
{
    namespace audio
    {
        class DirectSoundErrorCategory: public std::error_category
        {
        public:
            const char* name() const noexcept override
            {
                return "DirectSound";
            }

            std::string message(int condition) const override
            {
                switch (condition)
                {
                    case DSERR_ACCESSDENIED: return "DSERR_ACCESSDENIED";
                    case DSERR_ALLOCATED: return "DSERR_ALLOCATED";
                    case DSERR_ALREADYINITIALIZED: return "DSERR_ALREADYINITIALIZED";
                    case DSERR_BADFORMAT: return "DSERR_BADFORMAT";
                    case DSERR_BADSENDBUFFERGUID: return "DSERR_BADSENDBUFFERGUID";
                    case DSERR_BUFFERLOST: return "DSERR_BUFFERLOST";
                    case DSERR_BUFFERTOOSMALL: return "DSERR_BUFFERTOOSMALL";
                    case DSERR_CONTROLUNAVAIL: return "DSERR_CONTROLUNAVAIL";
                    case DSERR_DS8_REQUIRED: return "DSERR_DS8_REQUIRED";
                    case DSERR_FXUNAVAILABLE: return "DSERR_FXUNAVAILABLE";
                    case DSERR_GENERIC: return "DSERR_GENERIC";
                    case DSERR_INVALIDCALL: return "DSERR_INVALIDCALL";
                    case DSERR_INVALIDPARAM: return "DSERR_INVALIDPARAM";
                    case DSERR_NOAGGREGATION: return "DSERR_NOAGGREGATION";
                    case DSERR_NODRIVER: return "DSERR_NODRIVER";
                    case DSERR_NOINTERFACE: return "DSERR_NOINTERFACE";
                    case DSERR_OBJECTNOTFOUND: return "DSERR_OBJECTNOTFOUND";
                    case DSERR_OTHERAPPHASPRIO: return "DSERR_OTHERAPPHASPRIO";
                    case DSERR_OUTOFMEMORY: return "DSERR_OUTOFMEMORY";
                    case DSERR_PRIOLEVELNEEDED: return "DSERR_PRIOLEVELNEEDED";
                    case DSERR_SENDLOOP: return "DSERR_SENDLOOP";
                    case DSERR_UNINITIALIZED: return "DSERR_UNINITIALIZED";
                    case DSERR_UNSUPPORTED: return "DSERR_UNSUPPORTED";
                    default: return "Unknown error (" + std::to_string(condition) + ")";
                }
            }
        };

        const DirectSoundErrorCategory directSoundErrorCategory {};

        AudioDeviceDS::AudioDeviceDS(Window* window):
            AudioDevice(Driver::DIRECTSOUND), running(true)
        {
            HRESULT hr;
            if (FAILED(hr = DirectSoundEnumerateW(enumCallback, this)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to enumerate DirectSound 8 devices");

            if (FAILED(hr = DirectSoundCreate8(&DSDEVID_DefaultPlayback, &directSound, nullptr)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound 8 instance");

            NativeWindowWin* windowWin = static_cast<NativeWindowWin*>(window->getNativeWindow());

            if (FAILED(hr = directSound->SetCooperativeLevel(windowWin->getNativeWindow(), DSSCL_PRIORITY)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to set cooperative level for DirectSound 8");

            DSBUFFERDESC primaryBufferDesc;
            primaryBufferDesc.dwSize = sizeof(primaryBufferDesc);
            primaryBufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
            primaryBufferDesc.dwBufferBytes = 0;
            primaryBufferDesc.dwReserved = 0;
            primaryBufferDesc.lpwfxFormat = nullptr;
            primaryBufferDesc.guid3DAlgorithm = GUID_NULL;

            if (FAILED(hr = directSound->CreateSoundBuffer(&primaryBufferDesc, &primaryBuffer, nullptr)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound buffer");

            WAVEFORMATEX waveFormat;
            waveFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
            waveFormat.nChannels = channels;
            waveFormat.nSamplesPerSec = sampleRate;
            waveFormat.wBitsPerSample = 32;
            waveFormat.nBlockAlign = waveFormat.nChannels * (waveFormat.wBitsPerSample / 8);
            waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
            waveFormat.cbSize = 0;

            if (FAILED(hr = primaryBuffer->SetFormat(&waveFormat)))
            {
                waveFormat.wFormatTag = WAVE_FORMAT_PCM;
                waveFormat.wBitsPerSample = 16;

                if (FAILED(hr = primaryBuffer->SetFormat(&waveFormat)))
                    throw std::system_error(hr, directSoundErrorCategory, "Failed to set DirectSound buffer format");

                sampleFormat = SampleFormat::SINT16;
                sampleSize = sizeof(int16_t);
            }
            else
            {
                sampleFormat = SampleFormat::FLOAT32;
                sampleSize = sizeof(float);
            }

            IDirectSoundBuffer* tempBuffer = nullptr;

            DSBUFFERDESC bufferDesc;
            bufferDesc.dwSize = sizeof(bufferDesc);
            bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY;
            bufferDesc.dwBufferBytes = 2 * bufferSize;
            bufferDesc.dwReserved = 0;
            bufferDesc.lpwfxFormat = &waveFormat;
            bufferDesc.guid3DAlgorithm = GUID_NULL;

            if (FAILED(hr = directSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, nullptr)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound buffer");

            if (FAILED(hr = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, reinterpret_cast<void**>(&buffer))))
            {
                tempBuffer->Release();
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound buffer");
            }

            if (FAILED(hr = tempBuffer->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast<void**>(&notify))))
            {
                tempBuffer->Release();
                throw std::system_error(hr, directSoundErrorCategory, "Failed to get DirectSound notify interface");
            }

            tempBuffer->Release();

            uint8_t* bufferPointer;
            DWORD lockedBufferSize;
            if (FAILED(hr = buffer->Lock(0, bufferDesc.dwBufferBytes, reinterpret_cast<void**>(&bufferPointer), &lockedBufferSize, nullptr, 0, 0)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to lock DirectSound buffer");

            getData(lockedBufferSize / (channels * sizeof(int16_t)), data);
            std::copy(data.begin(), data.end(), bufferPointer);

            if (FAILED(hr = buffer->Unlock(bufferPointer, lockedBufferSize, nullptr, 0)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to unlock DirectSound buffer");

            nextBuffer = 0;

            notifyEvents[0] = CreateEvent(nullptr, true, false, nullptr);
            if (!notifyEvents[0])
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to create event");

            notifyEvents[1] = CreateEvent(nullptr, true, false, nullptr);
            if (!notifyEvents[1])
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to create event");

            DSBPOSITIONNOTIFY positionNotifyEvents[2];
            positionNotifyEvents[0].dwOffset = bufferSize - 1;
            positionNotifyEvents[0].hEventNotify = notifyEvents[0];

            positionNotifyEvents[1].dwOffset = 2 * bufferSize - 1;
            positionNotifyEvents[1].hEventNotify = notifyEvents[1];

            if (FAILED(hr = notify->SetNotificationPositions(2, positionNotifyEvents)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to set DirectSound notification positions");

            if (FAILED(hr = buffer->Play(0, 0, DSBPLAY_LOOPING)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to play DirectSound buffer");

            audioThread = std::thread(&AudioDeviceDS::run, this);
        }

        AudioDeviceDS::~AudioDeviceDS()
        {
            running = false;
            for (HANDLE notifyEvent : notifyEvents)
                SetEvent(notifyEvent);

            if (audioThread.joinable()) audioThread.join();

            for (HANDLE notifyEvent : notifyEvents)
                if (notifyEvent) CloseHandle(notifyEvent);

            if (notify) notify->Release();
            if (buffer) buffer->Release();
            if (primaryBuffer) primaryBuffer->Release();
            if (directSound) directSound->Release();
        }

        void AudioDeviceDS::run()
        {
            setCurrentThreadName("Audio");

            while (running)
            {
                try
                {
                    DWORD result;
                    if ((result = WaitForSingleObject(notifyEvents[nextBuffer], INFINITE)) == WAIT_FAILED)
                            throw std::system_error(GetLastError(), std::system_category(), "Failed to wait for event");

                    if (result == WAIT_OBJECT_0)
                    {
                        if (!running) break;

                        if (!ResetEvent(notifyEvents[nextBuffer]))
                            throw std::system_error(GetLastError(), std::system_category(), "Failed to reset event");

                        process();

                        uint8_t* bufferPointer;
                        DWORD lockedBufferSize;
                        HRESULT hr;
                        if (FAILED(hr = buffer->Lock(nextBuffer * bufferSize, bufferSize, reinterpret_cast<void**>(&bufferPointer), &lockedBufferSize, nullptr, 0, 0)))
                            throw std::system_error(hr, directSoundErrorCategory, "Failed to lock DirectSound buffer");

                        getData(lockedBufferSize / (sampleSize * channels), data);

                        std::copy(data.begin(), data.end(), bufferPointer);

                        if (FAILED(hr = buffer->Unlock(bufferPointer, lockedBufferSize, nullptr, 0)))
                            throw std::system_error(hr, directSoundErrorCategory, "Failed to unlock DirectSound buffer");

                        nextBuffer = (nextBuffer + 1) % 2;
                    }
                }
                catch (const std::exception& e)
                {
                    engine->log(Log::Level::ERR) << e.what();
                }
            }
        }
    } // namespace audio
} // namespace ouzel

#endif
<commit_msg>Replace audiodefs.h with mmreg.h<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#include "core/Setup.h"

#if OUZEL_COMPILE_DIRECTSOUND

#include <system_error>
#include <mmreg.h>
#include "AudioDeviceDS.hpp"
#include "core/Engine.hpp"
#include "core/Window.hpp"
#include "core/windows/NativeWindowWin.hpp"
#include "utils/Log.hpp"
#include "utils/Utils.hpp"

BOOL CALLBACK enumCallback(LPGUID, LPCWSTR description, LPCWSTR, LPVOID)
{
    int bufferSize = WideCharToMultiByte(CP_UTF8, 0, description, -1, nullptr, 0, nullptr, nullptr);
    if (bufferSize != 0)
    {
        std::vector<char> buffer(bufferSize);
        if (WideCharToMultiByte(CP_UTF8, 0, description, -1, buffer.data(), bufferSize, nullptr, nullptr) != 0)
            ouzel::engine->log(ouzel::Log::Level::INFO) << "Using " << buffer.data() << " for audio";
    }
    return FALSE;
}

namespace ouzel
{
    namespace audio
    {
        class DirectSoundErrorCategory: public std::error_category
        {
        public:
            const char* name() const noexcept override
            {
                return "DirectSound";
            }

            std::string message(int condition) const override
            {
                switch (condition)
                {
                    case DSERR_ACCESSDENIED: return "DSERR_ACCESSDENIED";
                    case DSERR_ALLOCATED: return "DSERR_ALLOCATED";
                    case DSERR_ALREADYINITIALIZED: return "DSERR_ALREADYINITIALIZED";
                    case DSERR_BADFORMAT: return "DSERR_BADFORMAT";
                    case DSERR_BADSENDBUFFERGUID: return "DSERR_BADSENDBUFFERGUID";
                    case DSERR_BUFFERLOST: return "DSERR_BUFFERLOST";
                    case DSERR_BUFFERTOOSMALL: return "DSERR_BUFFERTOOSMALL";
                    case DSERR_CONTROLUNAVAIL: return "DSERR_CONTROLUNAVAIL";
                    case DSERR_DS8_REQUIRED: return "DSERR_DS8_REQUIRED";
                    case DSERR_FXUNAVAILABLE: return "DSERR_FXUNAVAILABLE";
                    case DSERR_GENERIC: return "DSERR_GENERIC";
                    case DSERR_INVALIDCALL: return "DSERR_INVALIDCALL";
                    case DSERR_INVALIDPARAM: return "DSERR_INVALIDPARAM";
                    case DSERR_NOAGGREGATION: return "DSERR_NOAGGREGATION";
                    case DSERR_NODRIVER: return "DSERR_NODRIVER";
                    case DSERR_NOINTERFACE: return "DSERR_NOINTERFACE";
                    case DSERR_OBJECTNOTFOUND: return "DSERR_OBJECTNOTFOUND";
                    case DSERR_OTHERAPPHASPRIO: return "DSERR_OTHERAPPHASPRIO";
                    case DSERR_OUTOFMEMORY: return "DSERR_OUTOFMEMORY";
                    case DSERR_PRIOLEVELNEEDED: return "DSERR_PRIOLEVELNEEDED";
                    case DSERR_SENDLOOP: return "DSERR_SENDLOOP";
                    case DSERR_UNINITIALIZED: return "DSERR_UNINITIALIZED";
                    case DSERR_UNSUPPORTED: return "DSERR_UNSUPPORTED";
                    default: return "Unknown error (" + std::to_string(condition) + ")";
                }
            }
        };

        const DirectSoundErrorCategory directSoundErrorCategory {};

        AudioDeviceDS::AudioDeviceDS(Window* window):
            AudioDevice(Driver::DIRECTSOUND), running(true)
        {
            HRESULT hr;
            if (FAILED(hr = DirectSoundEnumerateW(enumCallback, this)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to enumerate DirectSound 8 devices");

            if (FAILED(hr = DirectSoundCreate8(&DSDEVID_DefaultPlayback, &directSound, nullptr)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound 8 instance");

            NativeWindowWin* windowWin = static_cast<NativeWindowWin*>(window->getNativeWindow());

            if (FAILED(hr = directSound->SetCooperativeLevel(windowWin->getNativeWindow(), DSSCL_PRIORITY)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to set cooperative level for DirectSound 8");

            DSBUFFERDESC primaryBufferDesc;
            primaryBufferDesc.dwSize = sizeof(primaryBufferDesc);
            primaryBufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
            primaryBufferDesc.dwBufferBytes = 0;
            primaryBufferDesc.dwReserved = 0;
            primaryBufferDesc.lpwfxFormat = nullptr;
            primaryBufferDesc.guid3DAlgorithm = GUID_NULL;

            if (FAILED(hr = directSound->CreateSoundBuffer(&primaryBufferDesc, &primaryBuffer, nullptr)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound buffer");

            WAVEFORMATEX waveFormat;
            waveFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
            waveFormat.nChannels = channels;
            waveFormat.nSamplesPerSec = sampleRate;
            waveFormat.wBitsPerSample = 32;
            waveFormat.nBlockAlign = waveFormat.nChannels * (waveFormat.wBitsPerSample / 8);
            waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
            waveFormat.cbSize = 0;

            if (FAILED(hr = primaryBuffer->SetFormat(&waveFormat)))
            {
                waveFormat.wFormatTag = WAVE_FORMAT_PCM;
                waveFormat.wBitsPerSample = 16;

                if (FAILED(hr = primaryBuffer->SetFormat(&waveFormat)))
                    throw std::system_error(hr, directSoundErrorCategory, "Failed to set DirectSound buffer format");

                sampleFormat = SampleFormat::SINT16;
                sampleSize = sizeof(int16_t);
            }
            else
            {
                sampleFormat = SampleFormat::FLOAT32;
                sampleSize = sizeof(float);
            }

            IDirectSoundBuffer* tempBuffer = nullptr;

            DSBUFFERDESC bufferDesc;
            bufferDesc.dwSize = sizeof(bufferDesc);
            bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY;
            bufferDesc.dwBufferBytes = 2 * bufferSize;
            bufferDesc.dwReserved = 0;
            bufferDesc.lpwfxFormat = &waveFormat;
            bufferDesc.guid3DAlgorithm = GUID_NULL;

            if (FAILED(hr = directSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, nullptr)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound buffer");

            if (FAILED(hr = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, reinterpret_cast<void**>(&buffer))))
            {
                tempBuffer->Release();
                throw std::system_error(hr, directSoundErrorCategory, "Failed to create DirectSound buffer");
            }

            if (FAILED(hr = tempBuffer->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast<void**>(&notify))))
            {
                tempBuffer->Release();
                throw std::system_error(hr, directSoundErrorCategory, "Failed to get DirectSound notify interface");
            }

            tempBuffer->Release();

            uint8_t* bufferPointer;
            DWORD lockedBufferSize;
            if (FAILED(hr = buffer->Lock(0, bufferDesc.dwBufferBytes, reinterpret_cast<void**>(&bufferPointer), &lockedBufferSize, nullptr, 0, 0)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to lock DirectSound buffer");

            getData(lockedBufferSize / (channels * sizeof(int16_t)), data);
            std::copy(data.begin(), data.end(), bufferPointer);

            if (FAILED(hr = buffer->Unlock(bufferPointer, lockedBufferSize, nullptr, 0)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to unlock DirectSound buffer");

            nextBuffer = 0;

            notifyEvents[0] = CreateEvent(nullptr, true, false, nullptr);
            if (!notifyEvents[0])
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to create event");

            notifyEvents[1] = CreateEvent(nullptr, true, false, nullptr);
            if (!notifyEvents[1])
                    throw std::system_error(GetLastError(), std::system_category(), "Failed to create event");

            DSBPOSITIONNOTIFY positionNotifyEvents[2];
            positionNotifyEvents[0].dwOffset = bufferSize - 1;
            positionNotifyEvents[0].hEventNotify = notifyEvents[0];

            positionNotifyEvents[1].dwOffset = 2 * bufferSize - 1;
            positionNotifyEvents[1].hEventNotify = notifyEvents[1];

            if (FAILED(hr = notify->SetNotificationPositions(2, positionNotifyEvents)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to set DirectSound notification positions");

            if (FAILED(hr = buffer->Play(0, 0, DSBPLAY_LOOPING)))
                throw std::system_error(hr, directSoundErrorCategory, "Failed to play DirectSound buffer");

            audioThread = std::thread(&AudioDeviceDS::run, this);
        }

        AudioDeviceDS::~AudioDeviceDS()
        {
            running = false;
            for (HANDLE notifyEvent : notifyEvents)
                SetEvent(notifyEvent);

            if (audioThread.joinable()) audioThread.join();

            for (HANDLE notifyEvent : notifyEvents)
                if (notifyEvent) CloseHandle(notifyEvent);

            if (notify) notify->Release();
            if (buffer) buffer->Release();
            if (primaryBuffer) primaryBuffer->Release();
            if (directSound) directSound->Release();
        }

        void AudioDeviceDS::run()
        {
            setCurrentThreadName("Audio");

            while (running)
            {
                try
                {
                    DWORD result;
                    if ((result = WaitForSingleObject(notifyEvents[nextBuffer], INFINITE)) == WAIT_FAILED)
                            throw std::system_error(GetLastError(), std::system_category(), "Failed to wait for event");

                    if (result == WAIT_OBJECT_0)
                    {
                        if (!running) break;

                        if (!ResetEvent(notifyEvents[nextBuffer]))
                            throw std::system_error(GetLastError(), std::system_category(), "Failed to reset event");

                        process();

                        uint8_t* bufferPointer;
                        DWORD lockedBufferSize;
                        HRESULT hr;
                        if (FAILED(hr = buffer->Lock(nextBuffer * bufferSize, bufferSize, reinterpret_cast<void**>(&bufferPointer), &lockedBufferSize, nullptr, 0, 0)))
                            throw std::system_error(hr, directSoundErrorCategory, "Failed to lock DirectSound buffer");

                        getData(lockedBufferSize / (sampleSize * channels), data);

                        std::copy(data.begin(), data.end(), bufferPointer);

                        if (FAILED(hr = buffer->Unlock(bufferPointer, lockedBufferSize, nullptr, 0)))
                            throw std::system_error(hr, directSoundErrorCategory, "Failed to unlock DirectSound buffer");

                        nextBuffer = (nextBuffer + 1) % 2;
                    }
                }
                catch (const std::exception& e)
                {
                    engine->log(Log::Level::ERR) << e.what();
                }
            }
        }
    } // namespace audio
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>/*
  ==============================================================================

    This file was auto-generated by the Introjucer!

    It contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================

// Default parameter values
const float defaultFilterType = SVFLowpass;
const float defaultCutoff = 40.0f;
const float defaultResonance = 0.5f;
const float defaultShelfGain = 0.0f;

//==============================================================================
VAStateVariableFilterProcessor::VAStateVariableFilterProcessor()
{
    addParameter(filterType = new FilterTypeParam{ svfFilter, defaultFilterType, "Filter Type" });
    addParameter(cutoff = new CutoffPitchParam{ svfFilter, defaultCutoff, "Cutoff Pitch" });
    addParameter(resonance = new ResonanceParam{ svfFilter, defaultResonance, "Resonance" });
    addParameter(shelfGain = new ShelfGainParam{ svfFilter, defaultShelfGain, "Shelf Gain" });

    lastUIWidth = 500;
    lastUIHeight = 200;
}

VAStateVariableFilterProcessor::~VAStateVariableFilterProcessor()
{
}

//==============================================================================
const String VAStateVariableFilterProcessor::getInputChannelName (int channelIndex) const
{
    return String (channelIndex + 1);
}

const String VAStateVariableFilterProcessor::getOutputChannelName (int channelIndex) const
{
    return String (channelIndex + 1);
}

#if (_MSC_VER)         // Check MSC version
#pragma warning(push)
#pragma warning(disable: 4100) // Disable unreferenced parameter
#endif

bool VAStateVariableFilterProcessor::isInputChannelStereoPair (int index) const
{
    return true;
}

bool VAStateVariableFilterProcessor::isOutputChannelStereoPair (int index) const
{
    return true;
}

#if (_MSC_VER)         // Check MSC version
#pragma warning(pop)           // Re-enable previous disabled warning
#endif

bool VAStateVariableFilterProcessor::acceptsMidi() const
{
   #if JucePlugin_WantsMidiInput
    return true;
   #else
    return false;
   #endif
}

bool VAStateVariableFilterProcessor::producesMidi() const
{
   #if JucePlugin_ProducesMidiOutput
    return true;
   #else
    return false;
   #endif
}

bool VAStateVariableFilterProcessor::silenceInProducesSilenceOut() const
{
    return false;
}

double VAStateVariableFilterProcessor::getTailLengthSeconds() const
{
    return 0.0;
}

//==============================================================================
#if (_MSC_VER)                  // Check if Visual Studio
#pragma warning(push)
#pragma warning(disable: 4100)  // disable warning
#endif

void VAStateVariableFilterProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
    // Use this method as the place to do any pre-playback
    // initialization that you need..
    svfFilter.setSampleRate(static_cast<float>(sampleRate));
}

void VAStateVariableFilterProcessor::releaseResources()
{
}

void VAStateVariableFilterProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    const int numSamples = buffer.getNumSamples();

    // This is the place where you'd normally do the guts of your plugin's
    // audio processing...
    for (int channel = 0; channel < getNumInputChannels(); ++channel) {

        float* channelData = buffer.getWritePointer(channel);

        // Process audio sample block through filter
        svfFilter.processAudioBlock(channelData, numSamples, channel);
    }

    // In case we have more outputs than inputs, this code clears any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
        buffer.clear(i, 0, buffer.getNumSamples());
}

#if (_MSC_VER)                  // Check if Visual Studio
#pragma warning(pop)            // Re-enable previous disabled warning
#endif

//==============================================================================
AudioProcessorEditor* VAStateVariableFilterProcessor::createEditor()
{
    return new VAStateVariableFilterProcessorEditor (*this);
}

//==============================================================================
void VAStateVariableFilterProcessor::getStateInformation (MemoryBlock& destData)
{
    // You should use this method to store your parameters in the memory block.
    // Here's an example of how you can use XML to make it easy and more robust:

    // Create an outer XML element..
    XmlElement xml("MYPLUGINSETTINGS");

    // add some attributes to it..
    xml.setAttribute("uiWidth", lastUIWidth);
    xml.setAttribute("uiHeight", lastUIHeight);
    xml.setAttribute("filterType", filterType->getValue());
    xml.setAttribute("cutoff", cutoff->getValue());
    xml.setAttribute("resonance", resonance->getValue());
    xml.setAttribute("shelfGain", shelfGain->getValue());

    // then use this helper function to stuff it into the binary blob and return it..
    copyXmlToBinary(xml, destData);
}

void VAStateVariableFilterProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    // You should use this method to restore your parameters from this memory block,
    // whose contents will have been created by the getStateInformation() call.

    // This getXmlFromBinary() helper function retrieves our XML from the binary blob..
    ScopedPointer<XmlElement> xmlState{ getXmlFromBinary(data, sizeInBytes) };

    if (xmlState != nullptr) {
        // make sure that it's actually our type of XML object..
        if (xmlState->hasTagName("MYPLUGINSETTINGS")) {
            // ok, now pull out our parameters..
            lastUIWidth = xmlState->getIntAttribute("uiWidth", lastUIWidth);
            lastUIHeight = xmlState->getIntAttribute("uiHeight", lastUIHeight);
            filterType->setValue((float)xmlState->getDoubleAttribute("filterType", filterType->getValue()));
            cutoff->setValue((float)xmlState->getDoubleAttribute("cutoff", cutoff->getValue()));
            resonance->setValue((float)xmlState->getDoubleAttribute("resonance", resonance->getValue()));
            shelfGain->setValue((float)xmlState->getDoubleAttribute("shelfGain", shelfGain->getValue()));
        }
    }
}

//==============================================================================
// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
    return new VAStateVariableFilterProcessor();
}
<commit_msg>Erase Visual Studio warning suppressor macros<commit_after>/*
  ==============================================================================

    This file was auto-generated by the Introjucer!

    It contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================

// Default parameter values
const float defaultFilterType = SVFLowpass;
const float defaultCutoff = 40.0f;
const float defaultResonance = 0.5f;
const float defaultShelfGain = 0.0f;

//==============================================================================
VAStateVariableFilterProcessor::VAStateVariableFilterProcessor()
{
    addParameter(filterType = new FilterTypeParam{ svfFilter, defaultFilterType, "Filter Type" });
    addParameter(cutoff = new CutoffPitchParam{ svfFilter, defaultCutoff, "Cutoff Pitch" });
    addParameter(resonance = new ResonanceParam{ svfFilter, defaultResonance, "Resonance" });
    addParameter(shelfGain = new ShelfGainParam{ svfFilter, defaultShelfGain, "Shelf Gain" });

    lastUIWidth = 500;
    lastUIHeight = 200;
}

VAStateVariableFilterProcessor::~VAStateVariableFilterProcessor()
{
}

//==============================================================================
const String VAStateVariableFilterProcessor::getInputChannelName (int channelIndex) const
{
    return String (channelIndex + 1);
}

const String VAStateVariableFilterProcessor::getOutputChannelName (int channelIndex) const
{
    return String (channelIndex + 1);
}

bool VAStateVariableFilterProcessor::isInputChannelStereoPair (int index) const
{
    return true;
}

bool VAStateVariableFilterProcessor::isOutputChannelStereoPair (int index) const
{
    return true;
}

bool VAStateVariableFilterProcessor::acceptsMidi() const
{
   #if JucePlugin_WantsMidiInput
    return true;
   #else
    return false;
   #endif
}

bool VAStateVariableFilterProcessor::producesMidi() const
{
   #if JucePlugin_ProducesMidiOutput
    return true;
   #else
    return false;
   #endif
}

bool VAStateVariableFilterProcessor::silenceInProducesSilenceOut() const
{
    return false;
}

double VAStateVariableFilterProcessor::getTailLengthSeconds() const
{
    return 0.0;
}

//==============================================================================

void VAStateVariableFilterProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
    // Use this method as the place to do any pre-playback
    // initialization that you need..
    svfFilter.setSampleRate(static_cast<float>(sampleRate));
}

void VAStateVariableFilterProcessor::releaseResources()
{
}

void VAStateVariableFilterProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    const int numSamples = buffer.getNumSamples();

    // This is the place where you'd normally do the guts of your plugin's
    // audio processing...
    for (int channel = 0; channel < getNumInputChannels(); ++channel) {

        float* channelData = buffer.getWritePointer(channel);

        // Process audio sample block through filter
        svfFilter.processAudioBlock(channelData, numSamples, channel);
    }

    // In case we have more outputs than inputs, this code clears any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
        buffer.clear(i, 0, buffer.getNumSamples());
}

//==============================================================================
AudioProcessorEditor* VAStateVariableFilterProcessor::createEditor()
{
    return new VAStateVariableFilterProcessorEditor (*this);
}

//==============================================================================
void VAStateVariableFilterProcessor::getStateInformation (MemoryBlock& destData)
{
    // You should use this method to store your parameters in the memory block.
    // Here's an example of how you can use XML to make it easy and more robust:

    // Create an outer XML element..
    XmlElement xml("MYPLUGINSETTINGS");

    // add some attributes to it..
    xml.setAttribute("uiWidth", lastUIWidth);
    xml.setAttribute("uiHeight", lastUIHeight);
    xml.setAttribute("filterType", filterType->getValue());
    xml.setAttribute("cutoff", cutoff->getValue());
    xml.setAttribute("resonance", resonance->getValue());
    xml.setAttribute("shelfGain", shelfGain->getValue());

    // then use this helper function to stuff it into the binary blob and return it..
    copyXmlToBinary(xml, destData);
}

void VAStateVariableFilterProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    // You should use this method to restore your parameters from this memory block,
    // whose contents will have been created by the getStateInformation() call.

    // This getXmlFromBinary() helper function retrieves our XML from the binary blob..
    ScopedPointer<XmlElement> xmlState{ getXmlFromBinary(data, sizeInBytes) };

    if (xmlState != nullptr) {
        // make sure that it's actually our type of XML object..
        if (xmlState->hasTagName("MYPLUGINSETTINGS")) {
            // ok, now pull out our parameters..
            lastUIWidth = xmlState->getIntAttribute("uiWidth", lastUIWidth);
            lastUIHeight = xmlState->getIntAttribute("uiHeight", lastUIHeight);
            filterType->setValue((float)xmlState->getDoubleAttribute("filterType", filterType->getValue()));
            cutoff->setValue((float)xmlState->getDoubleAttribute("cutoff", cutoff->getValue()));
            resonance->setValue((float)xmlState->getDoubleAttribute("resonance", resonance->getValue()));
            shelfGain->setValue((float)xmlState->getDoubleAttribute("shelfGain", shelfGain->getValue()));
        }
    }
}

//==============================================================================
// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
    return new VAStateVariableFilterProcessor();
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "chrome/renderer/extensions/extension_resource_request_policy.h"

#include "base/logging.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
#include "googleurl/src/gurl.h"

// static
bool ExtensionResourceRequestPolicy::CanRequestResource(
    const GURL& resource_url,
    const GURL& frame_url,
    const ExtensionSet* loaded_extensions) {
  CHECK(resource_url.SchemeIs(chrome::kExtensionScheme));

  const Extension* extension = loaded_extensions->GetByURL(resource_url);
  if (!extension) {
    // Allow the load in the case of a non-existent extension. We'll just get a
    // 404 from the browser process.
    return true;
  }

  // Disallow loading of packaged resources for hosted apps. We don't allow
  // hybrid hosted/packaged apps. The one exception is access to icons, since
  // some extensions want to be able to do things like create their own
  // launchers.
  std::string resource_root_relative_path =
      resource_url.path().empty() ? "" : resource_url.path().substr(1);
  if (extension && extension->is_hosted_app() &&
      !extension->icons().ContainsPath(resource_root_relative_path)) {
    LOG(ERROR) << "Denying load of " << resource_url.spec() << " from "
               << "hosted app.";
    return false;
  }

  return true;
}

ExtensionResourceRequestPolicy::ExtensionResourceRequestPolicy() {
}
<commit_msg>Coverity: Remove an unneeded check.<commit_after>// Copyright (c) 2011 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 "chrome/renderer/extensions/extension_resource_request_policy.h"

#include "base/logging.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
#include "googleurl/src/gurl.h"

// static
bool ExtensionResourceRequestPolicy::CanRequestResource(
    const GURL& resource_url,
    const GURL& frame_url,
    const ExtensionSet* loaded_extensions) {
  CHECK(resource_url.SchemeIs(chrome::kExtensionScheme));

  const Extension* extension = loaded_extensions->GetByURL(resource_url);
  if (!extension) {
    // Allow the load in the case of a non-existent extension. We'll just get a
    // 404 from the browser process.
    return true;
  }

  // Disallow loading of packaged resources for hosted apps. We don't allow
  // hybrid hosted/packaged apps. The one exception is access to icons, since
  // some extensions want to be able to do things like create their own
  // launchers.
  std::string resource_root_relative_path =
      resource_url.path().empty() ? "" : resource_url.path().substr(1);
  if (extension->is_hosted_app() &&
      !extension->icons().ContainsPath(resource_root_relative_path)) {
    LOG(ERROR) << "Denying load of " << resource_url.spec() << " from "
               << "hosted app.";
    return false;
  }

  return true;
}

ExtensionResourceRequestPolicy::ExtensionResourceRequestPolicy() {
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/Setup.h"

#if OUZEL_COMPILE_OPENAL

#include "AudioDeviceAL.hpp"
#include "core/Engine.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace audio
    {
        bool AudioDeviceAL::checkALCError(bool logError)
        {
            ALCenum error = alcGetError(device);

            if (error != ALC_NO_ERROR)
            {
                if (logError)
                {
                    const char* errorStr = "Unknown error";

                    switch (error)
                    {
                        case ALC_INVALID_DEVICE: errorStr = "ALC_INVALID_DEVICE"; break;
                        case ALC_INVALID_CONTEXT: errorStr = "ALC_INVALID_CONTEXT"; break;
                        case ALC_INVALID_ENUM: errorStr = "ALC_INVALID_ENUM"; break;
                        case ALC_INVALID_VALUE: errorStr = "ALC_INVALID_VALUE"; break;
                        case ALC_OUT_OF_MEMORY: errorStr = "ALC_OUT_OF_MEMORY"; break;
                    }

                    Log(Log::Level::ERR) << "OpenAL error: " << errorStr << "(" << error << ")";
                }

                return true;
            }

            return false;
        }

        bool AudioDeviceAL::checkOpenALError(bool logError)
        {
            ALenum error = alGetError();

            if (error != AL_NO_ERROR)
            {
                if (logError)
                {
                    const char* errorStr;

                    switch (error)
                    {
                        case AL_INVALID_NAME: errorStr = "AL_INVALID_NAME"; break;
                        case AL_INVALID_ENUM: errorStr = "AL_INVALID_ENUM"; break;
                        case AL_INVALID_VALUE: errorStr = "AL_INVALID_VALUE"; break;
                        case AL_INVALID_OPERATION: errorStr = "AL_INVALID_OPERATION"; break;
                        case AL_OUT_OF_MEMORY: errorStr = "AL_OUT_OF_MEMORY"; break;
                        default: errorStr = "Unknown error"; break;
                    }

                    Log(Log::Level::ERR) << "OpenAL error: " << errorStr << " (" << error << ")";
                }

                return true;
            }

            return false;
        }

        AudioDeviceAL::AudioDeviceAL():
            AudioDevice(Audio::Driver::OPENAL)
        {
#if OUZEL_MULTITHREADED
            running = false;
#endif

            std::fill(std::begin(buffers), std::end(buffers), 0);
        }

        AudioDeviceAL::~AudioDeviceAL()
        {
#if OUZEL_MULTITHREADED
            running = false;
            if (audioThread.joinable()) audioThread.join();
#endif

            if (sourceId)
            {
                alSourceStop(sourceId);
                alSourcei(sourceId, AL_BUFFER, 0);
                alDeleteSources(1, &sourceId);

                if (checkOpenALError())
                {
                    Log(Log::Level::ERR) << "Failed to delete OpenAL source";
                }
            }

            for (ALuint buffer : buffers)
            {
                if (buffer)
                {
                    alDeleteBuffers(1, &buffer);

                    if (checkOpenALError())
                    {
                        Log(Log::Level::ERR) << "Failed to delete OpenAL buffer";
                    }
                }
            }

            if (context)
            {
                alcMakeContextCurrent(nullptr);
                alcDestroyContext(context);
            }

            if (device)
            {
                alcCloseDevice(device);
            }
        }

        bool AudioDeviceAL::init(bool debugAudio)
        {
            if (!AudioDevice::init(debugAudio))
            {
                return false;
            }

            const ALCchar* deviceName = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);

            if (deviceName)
            {
                Log(Log::Level::INFO) << "Using " << deviceName << " for audio";
            }

            device = alcOpenDevice(deviceName);

            if (!device || checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL device";
                return false;
            }

            int capabilities[] =
            {
                ALC_FREQUENCY, 44100,
                ALC_STEREO_SOURCES, 4,
                0, 0
            };

            context = alcCreateContext(device, capabilities);

            if (checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL context";
                return false;
            }

            alcMakeContextCurrent(context);

            if (checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to make OpenAL context current";
                return false;
            }

            format40 = alGetEnumValue("AL_FORMAT_QUAD16");
            format51 = alGetEnumValue("AL_FORMAT_51CHN16");
            format61 = alGetEnumValue("AL_FORMAT_61CHN16");
            format71 = alGetEnumValue("AL_FORMAT_71CHN16");

            if (checkOpenALError())
            {
                Log(Log::Level::WARN) << "Failed to get OpenAL enum values";
            }

            alGenSources(1, &sourceId);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL source";
                return false;
            }

            alGenBuffers(2, buffers);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL buffers";
                return false;
            }

            switch (channels)
            {
                case 1: sampleFormat = AL_FORMAT_MONO16; break;
                case 2: sampleFormat = AL_FORMAT_STEREO16; break;
                case 4: sampleFormat = format40; break;
                case 6: sampleFormat = format51; break;
                case 7: sampleFormat = format61; break;
                case 8: sampleFormat = format71; break;
                default:
                {
                    Log(Log::Level::ERR) << "Invalid channel count";
                    return false;
                }
            }

            format = Audio::Format::SINT16;

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            alBufferData(buffers[0], sampleFormat,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            alBufferData(buffers[1], sampleFormat,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            nextBuffer = 0;

            alSourceQueueBuffers(sourceId, 2, buffers);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to queue OpenAL buffers";
                return false;
            }

            alSourcePlay(sourceId);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to play OpenAL source";
                return false;
            }

#if OUZEL_MULTITHREADED
            running = true;
            audioThread = std::thread(&AudioDeviceAL::run, this);
#endif

            return true;
        }

        bool AudioDeviceAL::process()
        {
            if (!AudioDevice::process())
            {
                return false;
            }

            alcMakeContextCurrent(context);

            if (checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to make OpenAL context current";
                return false;
            }

            ALint buffersProcessed;
            alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &buffersProcessed);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to get processed buffer count";
                return false;
            }

            // requeue all processed buffers
            for (; buffersProcessed > 0; --buffersProcessed)
            {
                alSourceUnqueueBuffers(sourceId, 1, &buffers[nextBuffer]);

                if (checkOpenALError())
                {
                    Log(Log::Level::ERR) << "Failed to unqueue OpenAL buffer";
                    return false;
                }

                if (!getData(bufferSize / (channels * sizeof(int16_t)), data))
                {
                    return false;
                }

                alBufferData(buffers[nextBuffer], sampleFormat,
                             data.data(),
                             static_cast<ALsizei>(data.size()),
                             static_cast<ALsizei>(sampleRate));

                alSourceQueueBuffers(sourceId, 1, &buffers[nextBuffer]);

                if (checkOpenALError())
                {
                    Log(Log::Level::ERR) << "Failed to queue OpenAL buffer";
                    return false;
                }

                ALint state;
                alGetSourcei(sourceId, AL_SOURCE_STATE, &state);
                if (state != AL_PLAYING)
                {
                    alSourcePlay(sourceId);

                    if (checkOpenALError())
                    {
                        Log(Log::Level::ERR) << "Failed to play OpenAL source";
                        return false;
                    }
                }

                // swap the buffer
                nextBuffer = (nextBuffer + 1) % 2;
            }

            return true;
        }

        void AudioDeviceAL::run()
        {
#if OUZEL_MULTITHREADED
            sharedEngine->setCurrentThreadName("Audio");

            while (running)
            {
                if (!process())
                {
                    break;
                }
            }
#endif
        }
    } // namespace audio
} // namespace ouzel

#endif
<commit_msg>Don't request OpenAL enum values on Emscripten<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/Setup.h"

#if OUZEL_COMPILE_OPENAL

#include "AudioDeviceAL.hpp"
#include "core/Engine.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace audio
    {
        bool AudioDeviceAL::checkALCError(bool logError)
        {
            ALCenum error = alcGetError(device);

            if (error != ALC_NO_ERROR)
            {
                if (logError)
                {
                    const char* errorStr = "Unknown error";

                    switch (error)
                    {
                        case ALC_INVALID_DEVICE: errorStr = "ALC_INVALID_DEVICE"; break;
                        case ALC_INVALID_CONTEXT: errorStr = "ALC_INVALID_CONTEXT"; break;
                        case ALC_INVALID_ENUM: errorStr = "ALC_INVALID_ENUM"; break;
                        case ALC_INVALID_VALUE: errorStr = "ALC_INVALID_VALUE"; break;
                        case ALC_OUT_OF_MEMORY: errorStr = "ALC_OUT_OF_MEMORY"; break;
                    }

                    Log(Log::Level::ERR) << "OpenAL error: " << errorStr << "(" << error << ")";
                }

                return true;
            }

            return false;
        }

        bool AudioDeviceAL::checkOpenALError(bool logError)
        {
            ALenum error = alGetError();

            if (error != AL_NO_ERROR)
            {
                if (logError)
                {
                    const char* errorStr;

                    switch (error)
                    {
                        case AL_INVALID_NAME: errorStr = "AL_INVALID_NAME"; break;
                        case AL_INVALID_ENUM: errorStr = "AL_INVALID_ENUM"; break;
                        case AL_INVALID_VALUE: errorStr = "AL_INVALID_VALUE"; break;
                        case AL_INVALID_OPERATION: errorStr = "AL_INVALID_OPERATION"; break;
                        case AL_OUT_OF_MEMORY: errorStr = "AL_OUT_OF_MEMORY"; break;
                        default: errorStr = "Unknown error"; break;
                    }

                    Log(Log::Level::ERR) << "OpenAL error: " << errorStr << " (" << error << ")";
                }

                return true;
            }

            return false;
        }

        AudioDeviceAL::AudioDeviceAL():
            AudioDevice(Audio::Driver::OPENAL)
        {
#if OUZEL_MULTITHREADED
            running = false;
#endif

            std::fill(std::begin(buffers), std::end(buffers), 0);
        }

        AudioDeviceAL::~AudioDeviceAL()
        {
#if OUZEL_MULTITHREADED
            running = false;
            if (audioThread.joinable()) audioThread.join();
#endif

            if (sourceId)
            {
                alSourceStop(sourceId);
                alSourcei(sourceId, AL_BUFFER, 0);
                alDeleteSources(1, &sourceId);

                if (checkOpenALError())
                {
                    Log(Log::Level::ERR) << "Failed to delete OpenAL source";
                }
            }

            for (ALuint buffer : buffers)
            {
                if (buffer)
                {
                    alDeleteBuffers(1, &buffer);

                    if (checkOpenALError())
                    {
                        Log(Log::Level::ERR) << "Failed to delete OpenAL buffer";
                    }
                }
            }

            if (context)
            {
                alcMakeContextCurrent(nullptr);
                alcDestroyContext(context);
            }

            if (device)
            {
                alcCloseDevice(device);
            }
        }

        bool AudioDeviceAL::init(bool debugAudio)
        {
            if (!AudioDevice::init(debugAudio))
            {
                return false;
            }

            const ALCchar* deviceName = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);

            if (deviceName)
            {
                Log(Log::Level::INFO) << "Using " << deviceName << " for audio";
            }

            device = alcOpenDevice(deviceName);

            if (!device || checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL device";
                return false;
            }

            int capabilities[] =
            {
                ALC_FREQUENCY, 44100,
                ALC_STEREO_SOURCES, 4,
                0, 0
            };

            context = alcCreateContext(device, capabilities);

            if (checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL context";
                return false;
            }

            alcMakeContextCurrent(context);

            if (checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to make OpenAL context current";
                return false;
            }

#if !OUZEL_PLATFORM_EMSCRIPTEN
            format40 = alGetEnumValue("AL_FORMAT_QUAD16");
            format51 = alGetEnumValue("AL_FORMAT_51CHN16");
            format61 = alGetEnumValue("AL_FORMAT_61CHN16");
            format71 = alGetEnumValue("AL_FORMAT_71CHN16");
#endif

            if (checkOpenALError())
            {
                Log(Log::Level::WARN) << "Failed to get OpenAL enum values";
            }

            alGenSources(1, &sourceId);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL source";
                return false;
            }

            alGenBuffers(2, buffers);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to create OpenAL buffers";
                return false;
            }

            switch (channels)
            {
                case 1: sampleFormat = AL_FORMAT_MONO16; break;
                case 2: sampleFormat = AL_FORMAT_STEREO16; break;
                case 4: sampleFormat = format40; break;
                case 6: sampleFormat = format51; break;
                case 7: sampleFormat = format61; break;
                case 8: sampleFormat = format71; break;
                default:
                {
                    Log(Log::Level::ERR) << "Invalid channel count";
                    return false;
                }
            }

            format = Audio::Format::SINT16;

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            alBufferData(buffers[0], sampleFormat,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            getData(bufferSize / (channels * sizeof(int16_t)), data);

            alBufferData(buffers[1], sampleFormat,
                         data.data(),
                         static_cast<ALsizei>(data.size()),
                         static_cast<ALsizei>(sampleRate));

            nextBuffer = 0;

            alSourceQueueBuffers(sourceId, 2, buffers);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to queue OpenAL buffers";
                return false;
            }

            alSourcePlay(sourceId);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to play OpenAL source";
                return false;
            }

#if OUZEL_MULTITHREADED
            running = true;
            audioThread = std::thread(&AudioDeviceAL::run, this);
#endif

            return true;
        }

        bool AudioDeviceAL::process()
        {
            if (!AudioDevice::process())
            {
                return false;
            }

            alcMakeContextCurrent(context);

            if (checkALCError())
            {
                Log(Log::Level::ERR) << "Failed to make OpenAL context current";
                return false;
            }

            ALint buffersProcessed;
            alGetSourcei(sourceId, AL_BUFFERS_PROCESSED, &buffersProcessed);

            if (checkOpenALError())
            {
                Log(Log::Level::ERR) << "Failed to get processed buffer count";
                return false;
            }

            // requeue all processed buffers
            for (; buffersProcessed > 0; --buffersProcessed)
            {
                alSourceUnqueueBuffers(sourceId, 1, &buffers[nextBuffer]);

                if (checkOpenALError())
                {
                    Log(Log::Level::ERR) << "Failed to unqueue OpenAL buffer";
                    return false;
                }

                if (!getData(bufferSize / (channels * sizeof(int16_t)), data))
                {
                    return false;
                }

                alBufferData(buffers[nextBuffer], sampleFormat,
                             data.data(),
                             static_cast<ALsizei>(data.size()),
                             static_cast<ALsizei>(sampleRate));

                alSourceQueueBuffers(sourceId, 1, &buffers[nextBuffer]);

                if (checkOpenALError())
                {
                    Log(Log::Level::ERR) << "Failed to queue OpenAL buffer";
                    return false;
                }

                ALint state;
                alGetSourcei(sourceId, AL_SOURCE_STATE, &state);
                if (state != AL_PLAYING)
                {
                    alSourcePlay(sourceId);

                    if (checkOpenALError())
                    {
                        Log(Log::Level::ERR) << "Failed to play OpenAL source";
                        return false;
                    }
                }

                // swap the buffer
                nextBuffer = (nextBuffer + 1) % 2;
            }

            return true;
        }

        void AudioDeviceAL::run()
        {
#if OUZEL_MULTITHREADED
            sharedEngine->setCurrentThreadName("Audio");

            while (running)
            {
                if (!process())
                {
                    break;
                }
            }
#endif
        }
    } // namespace audio
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/session.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("auto_manage_prefer_seeds", &session_settings::auto_manage_prefer_seeds)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("auto_scraped_interval", &session_settings::auto_scrape_interval)
        .def_readwrite("peer_tos", &session_settings::peer_tos)
        .def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
        .def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
        .def_readwrite("cache_size", &session_settings::cache_size)
        .def_readwrite("cache_expiry", &session_settings::cache_expiry)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;
    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}
<commit_msg>Update python bindings session_settings<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/session.hpp>

using namespace boost::python;
using namespace libtorrent;

void bind_session_settings()
{
    class_<session_settings>("session_settings")
        .def_readwrite("user_agent", &session_settings::user_agent)
        .def_readwrite("tracker_completion_timeout", &session_settings::tracker_completion_timeout)
        .def_readwrite("tracker_receive_timeout", &session_settings::tracker_receive_timeout)
        .def_readwrite("stop_tracker_timeout", &session_settings::stop_tracker_timeout)
        .def_readwrite("tracker_maximum_response_length", &session_settings::tracker_maximum_response_length)
        .def_readwrite("piece_timeout", &session_settings::piece_timeout)
        .def_readwrite("request_timeout", &session_settings::request_timeout)
        .def_readwrite("request_queue_time", &session_settings::request_queue_time)
        .def_readwrite("max_allowed_in_request_queue", &session_settings::max_allowed_in_request_queue)
        .def_readwrite("max_out_request_queue", &session_settings::max_out_request_queue)
        .def_readwrite("whole_pieces_threshold", &session_settings::whole_pieces_threshold)
        .def_readwrite("peer_timeout", &session_settings::peer_timeout)
        .def_readwrite("urlseed_timeout", &session_settings::urlseed_timeout)
        .def_readwrite("urlseed_pipeline_size", &session_settings::urlseed_pipeline_size)
        .def_readwrite("urlseed_wait_retry", &session_settings::urlseed_wait_retry)
        .def_readwrite("file_pool_size", &session_settings::file_pool_size)
        .def_readwrite("allow_multiple_connections_per_ip", &session_settings::allow_multiple_connections_per_ip)
        .def_readwrite("max_failcount", &session_settings::max_failcount)
        .def_readwrite("min_reconnect_time", &session_settings::min_reconnect_time)
        .def_readwrite("peer_connect_timeout", &session_settings::peer_connect_timeout)
        .def_readwrite("ignore_limits_on_local_network", &session_settings::ignore_limits_on_local_network)
        .def_readwrite("connection_speed", &session_settings::connection_speed)
        .def_readwrite("send_redundant_have", &session_settings::send_redundant_have)
        .def_readwrite("lazy_bitfields", &session_settings::lazy_bitfields)
        .def_readwrite("inactivity_timeout", &session_settings::inactivity_timeout)
        .def_readwrite("unchoke_interval", &session_settings::unchoke_interval)
        .def_readwrite("optimistic_unchoke_multiplier", &session_settings::optimistic_unchoke_multiplier)
        .def_readwrite("num_want", &session_settings::num_want)
        .def_readwrite("initial_picker_threshold", &session_settings::initial_picker_threshold)
        .def_readwrite("allowed_fast_set_size", &session_settings::allowed_fast_set_size)
        .def_readwrite("max_outstanding_disk_bytes_per_connection", &session_settings::max_outstanding_disk_bytes_per_connection)
        .def_readwrite("handshake_timeout", &session_settings::handshake_timeout)
#ifndef TORRENT_DISABLE_DHT
        .def_readwrite("use_dht_as_fallback", &session_settings::use_dht_as_fallback)
#endif
        .def_readwrite("free_torrent_hashes", &session_settings::free_torrent_hashes)
        .def_readwrite("upnp_ignore_nonrouters", &session_settings::upnp_ignore_nonrouters)
        .def_readwrite("send_buffer_watermark", &session_settings::send_buffer_watermark)
        .def_readwrite("auto_upload_slots", &session_settings::auto_upload_slots)
        .def_readwrite("auto_upload_slots_rate_based", &session_settings::auto_upload_slots_rate_based)
        .def_readwrite("use_parole_mode", &session_settings::use_parole_mode)
        .def_readwrite("cache_size", &session_settings::cache_size)
        .def_readwrite("cache_buffer_chunk_size", &session_settings::cache_buffer_chunk_size)
        .def_readwrite("cache_expiry", &session_settings::cache_expiry)
        .def_readwrite("use_read_cache", &session_settings::use_read_cache)
        .def_readwrite("disk_io_write_mode", &session_settings::disk_io_write_mode)
        .def_readwrite("disk_io_read_mode", &session_settings::disk_io_read_mode)
        .def_readwrite("coalesce_reads", &session_settings::coalesce_reads)
        .def_readwrite("coalesce_writes", &session_settings:coalesce_writes)
        .def_readwrite("outgoing_ports", &session_settings::outgoing_ports)
        .def_readwrite("peer_tos", &session_settings::peer_tos)
        .def_readwrite("active_downloads", &session_settings::active_downloads)
        .def_readwrite("active_seeds", &session_settings::active_seeds)
        .def_readwrite("active_limit", &session_settings::active_limit)
        .def_readwrite("auto_manage_prefer_seeds", &session_settings::automanaged_prefer_seeds)
        .def_readwrite("dont_count_slow_torrents", &session_settings::dont_count_slow_torrents)
        .def_readwrite("auto_manage_interval", &session_settings::auto_manage_interval)
        .def_readwrite("share_ratio_limit", &session_settings::share_ratio_limit)
        .def_readwrite("seed_time_ratio_limit", &session_settings::seed_time_ratio_limit)
        .def_readwrite("seed_time_limit", &session_settings::seed_time_limit)
        .def_readwrite("peer_turnover", &session_settings::peer_turnover)
        .def_readwrite("peer_turnover_cutoff", &session_settings::peer_turnover_cutoff)
        .def_readwrite("close_redundant_connections", &session_settings::close_redundant_connections)
        .def_readwrite("auto_scrape_interval", &session_settings::auto_scrape_interval)
        .def_readwrite("auto_scrape_min_interval", &session_settings::auto_scrape_min_interval)
        .def_readwrite("max_peerlist_size", &session_settings::max_peerlist_size)
        .def_readwrite("max_paused_peerlist_size", &session_settings::max_paused_peerlist_size)
        .def_readwrite("min_announce_interval", &session_settings::min_announce_interval)
        .def_readwrite("prioritize_partial_pieces", &session_settings::prioritize_partial_pieces)
        .def_readwrite("auto_manage_startup", &session_settings::auto_manage_startup)
        .def_readwrite("rate_limit_ip_overhead", &session_settings::rate_limit_ip_overhead)
        .def_readwrite("announce_to_all_trackers", &session_settings::announce_to_all_trackers)
        .def_readwrite("prefer_udp_trackers", &session_settings::prefer_udp_trackers)
        .def_readwrite("strict_super_seeding", &session_settings::strict_super_seeding)
        .def_readwrite("seeding_piece_quota", &session_settings::seeding_piece_quota)
        .def_readwrite("max_sparse_regions", &session_settings::max_sparse_regions)
#ifndef TORRENT_DISABLE_MLOCK
        .def_readwrite("lock_disk_cache", &session_settings::lock_disk_cache)
#endif
        .def_readwrite("max_rejects", &session_settings::max_rejects)
        .def_readwrite("recv_socket_buffer_size", &session_settings::recv_socket_buffer_size)
        .def_readwrite("send_socket_buffer_size", &session_settings::send_socket_buffer_size)
        .def_readwrite("optimize_hashing_for_speed", &session_settings::optimize_hashing_for_speed)
        .def_readwrite("file_checks_delay_per_block", &session_settings::file_checks_delay_per_block)
        .def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
        .def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
        .def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
    ;

    enum_<proxy_settings::proxy_type>("proxy_type")
        .value("none", proxy_settings::none)
        .value("socks4", proxy_settings::socks4)
        .value("socks5", proxy_settings::socks5)
        .value("socks5_pw", proxy_settings::socks5_pw)
        .value("http", proxy_settings::http)
        .value("http_pw", proxy_settings::http_pw)
    ;

    enum_<session_settings::disk_cache_algo_t("disk_cache_algo_t")
        .value("lru", session_settings::disk_cache_algo_t::lru)
        .value("largest_contiguous", session_settings::disk_cache_algo_t::largest_contiguous)
    ;

    enum_<session_settings::io_buffer_mode_t("io_buffer_mode_t")
        .value("enable_os_cache", session_settings::io_buffer_mode_t::enable_os_cache)
        .value("disable_os_cache_for_aligned_files", session_settings::io_buffer_mode_t:disable_os_cache_for_aligned_files)
        .value("disable_os_cache", session_settings::io_buffer_mode_t::disable_os_cache)
    ;

    class_<proxy_settings>("proxy_settings")
        .def_readwrite("hostname", &proxy_settings::hostname)
        .def_readwrite("port", &proxy_settings::port)
        .def_readwrite("password", &proxy_settings::password)
        .def_readwrite("username", &proxy_settings::username)
        .def_readwrite("type", &proxy_settings::type)
    ;

#ifndef TORRENT_DISABLE_DHT
    class_<dht_settings>("dht_settings")
        .def_readwrite("max_peers_reply", dht_settings::max_peers_reply)
        .def_readwrite("search_branching", dht_settings::search_branching)
        .def_readwrite("service_port", dht_settings::service_port)
        .def_readwrite("max_fail_count", dht_settings::max_fail_count)
    ;
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION
    enum_<pe_settings::enc_policy>("enc_policy")
        .value("forced", pe_settings::forced)
        .value("enabled", pe_settings::enabled)
        .value("disabled", pe_settings::disabled)
    ;

    enum_<pe_settings::enc_level>("enc_level")
        .value("rc4", pe_settings::rc4)
        .value("plaintext", pe_settings::plaintext)
        .value("both", pe_settings::both)
    ;

    class_<pe_settings>("pe_settings")
        .def_readwrite("out_enc_policy", &pe_settings::out_enc_policy)
        .def_readwrite("in_enc_policy", &pe_settings::in_enc_policy)
        .def_readwrite("allowed_enc_level", &pe_settings::allowed_enc_level)
        .def_readwrite("prefer_rc4", &pe_settings::prefer_rc4)
    ;
#endif

}
<|endoftext|>