<commit_before>//=============================================================================================================
/**
* @file     layoutloader.cpp
* @author   Lorenz Esch <lorenz.esch@tu-ilmenau.de>;
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
* @version  1.0
* @date     September, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Lorenz Esch, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Implementation of the LayoutLoader class
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "layoutloader.h"

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace UTILSLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

LayoutLoader::LayoutLoader()
{
}

//*************************************************************************************************************

bool LayoutLoader::readAsaElcFile(QString path, QStringList &channelNames, QVector<QVector<double> > &location3D, QVector<QVector<double> > &location2D, QString &unit)
{
    //Open .elc file
    if(!path.contains(".elc"))
        return false;

    QFile file(path);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug()<<"Error opening elc file";
        return false;
    }

    //Start reading from file
    double numberElectrodes;
    QTextStream in(&file);
    bool read2D = false;

    while(!in.atEnd())
    {
        QString line = in.readLine();

        QStringList fields = line.split(QRegExp("\\s+"));

        //Delete last element if it is a blank character
        if(fields.at(fields.size()-1) == "")
            fields.removeLast();

        if(!line.contains("#")) //Skip commented areas in file
        {
            //Read number of electrodes
            if(line.contains("NumberPositions"))
                numberElectrodes = fields.at(1).toDouble();

            //Read the unit of the position values
            if(line.contains("UnitPosition"))
                unit = fields.at(1);

            //Read actual electrode positions
            if(line.contains("Positions2D"))
                read2D = true;

            if(line.contains(":") && !read2D) //Read 3D positions
            {
                channelNames.push_back(fields.at(0));
                QVector<double> posTemp;

                posTemp.push_back(fields.at(fields.size()-3).toDouble());    //x
                posTemp.push_back(fields.at(fields.size()-2).toDouble());    //y
                posTemp.push_back(fields.at(fields.size()-1).toDouble());    //z

                location3D.push_back(posTemp);
            }

            if(line.contains(":") && read2D) //Read 2D positions
            {
                QVector<double> posTemp;
                posTemp.push_back(fields.at(fields.size()-2).toDouble());    //x
                posTemp.push_back(fields.at(fields.size()-1).toDouble());    //y
                location2D.push_back(posTemp);
            }

            //Read channel names
            if(line.contains("Labels"))
            {
                line = in.readLine();
                fields = line.split(QRegExp("\\s+"));

                //Delete last element if it is a blank character
                if(fields.at(fields.size()-1) == "")
                    fields.removeLast();

                channelNames = fields;
            }
        }
    }

    Q_UNUSED(numberElectrodes);

    file.close();

    return true;
}

//*************************************************************************************************************

bool LayoutLoader::readMNELoutFile(QString path, QMap<QString, QPointF> &channelData)
{
    //Open .elc file
    if(!path.contains(".lout"))
        return false;

    channelData.clear();

    QFile file(path);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug()<<"Error opening mne lout file";
        return false;
    }

    //Start reading from file
    QTextStream in(&file);

    //skip first line
    in.readLine();

    while(!in.atEnd()) {
        QString line = in.readLine();

        QStringList fields = line.split(QRegExp("\\s+"));

        //Delete last element if it is a blank character
        if(fields.at(fields.size()-1) == "")
            fields.removeLast();

        QPointF posTemp;
        posTemp.setX(fields.at(1).toDouble());      //x
        posTemp.setY(fields.at(2).toDouble());      //y

        //Create channel data map entry
        QString key = QString("%1 %2").arg(fields.at(fields.size()-2)).arg(fields.at(fields.size()-1));
        channelData.insert(key, posTemp);
    }

    file.close();

    return true;
}
<commit_msg>missing unix include<commit_after>//=============================================================================================================
/**
* @file     layoutloader.cpp
* @author   Lorenz Esch <lorenz.esch@tu-ilmenau.de>;
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
* @version  1.0
* @date     September, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Lorenz Esch, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Implementation of the LayoutLoader class
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "layoutloader.h"

//*************************************************************************************************************
//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QPointF>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace UTILSLIB;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

LayoutLoader::LayoutLoader()
{
}

//*************************************************************************************************************

bool LayoutLoader::readAsaElcFile(QString path, QStringList &channelNames, QVector<QVector<double> > &location3D, QVector<QVector<double> > &location2D, QString &unit)
{
    //Open .elc file
    if(!path.contains(".elc"))
        return false;

    QFile file(path);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug()<<"Error opening elc file";
        return false;
    }

    //Start reading from file
    double numberElectrodes;
    QTextStream in(&file);
    bool read2D = false;

    while(!in.atEnd())
    {
        QString line = in.readLine();

        QStringList fields = line.split(QRegExp("\\s+"));

        //Delete last element if it is a blank character
        if(fields.at(fields.size()-1) == "")
            fields.removeLast();

        if(!line.contains("#")) //Skip commented areas in file
        {
            //Read number of electrodes
            if(line.contains("NumberPositions"))
                numberElectrodes = fields.at(1).toDouble();

            //Read the unit of the position values
            if(line.contains("UnitPosition"))
                unit = fields.at(1);

            //Read actual electrode positions
            if(line.contains("Positions2D"))
                read2D = true;

            if(line.contains(":") && !read2D) //Read 3D positions
            {
                channelNames.push_back(fields.at(0));
                QVector<double> posTemp;

                posTemp.push_back(fields.at(fields.size()-3).toDouble());    //x
                posTemp.push_back(fields.at(fields.size()-2).toDouble());    //y
                posTemp.push_back(fields.at(fields.size()-1).toDouble());    //z

                location3D.push_back(posTemp);
            }

            if(line.contains(":") && read2D) //Read 2D positions
            {
                QVector<double> posTemp;
                posTemp.push_back(fields.at(fields.size()-2).toDouble());    //x
                posTemp.push_back(fields.at(fields.size()-1).toDouble());    //y
                location2D.push_back(posTemp);
            }

            //Read channel names
            if(line.contains("Labels"))
            {
                line = in.readLine();
                fields = line.split(QRegExp("\\s+"));

                //Delete last element if it is a blank character
                if(fields.at(fields.size()-1) == "")
                    fields.removeLast();

                channelNames = fields;
            }
        }
    }

    Q_UNUSED(numberElectrodes);

    file.close();

    return true;
}

//*************************************************************************************************************

bool LayoutLoader::readMNELoutFile(QString path, QMap<QString, QPointF> &channelData)
{
    //Open .elc file
    if(!path.contains(".lout"))
        return false;

    channelData.clear();

    QFile file(path);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug()<<"Error opening mne lout file";
        return false;
    }

    //Start reading from file
    QTextStream in(&file);

    //skip first line
    in.readLine();

    while(!in.atEnd()) {
        QString line = in.readLine();

        QStringList fields = line.split(QRegExp("\\s+"));

        //Delete last element if it is a blank character
        if(fields.at(fields.size()-1) == "")
            fields.removeLast();

        QPointF posTemp;
        posTemp.setX(fields.at(1).toDouble());      //x
        posTemp.setY(fields.at(2).toDouble());      //y

        //Create channel data map entry
        QString key = QString("%1 %2").arg(fields.at(fields.size()-2)).arg(fields.at(fields.size()-1));
        channelData.insert(key, posTemp);
    }

    file.close();

    return true;
}
<|endoftext|>


<commit_before><commit_msg>fixed warnings<commit_after><|endoftext|>


<commit_before>#include "dreal/api/api.h"

#include <gtest/gtest.h>

#include "dreal/solver/formula_evaluator.h"

namespace dreal {
namespace {

class ApiTest : public ::testing::Test {
 protected:
  const Variable x_{"x", Variable::Type::CONTINUOUS};
  const Variable y_{"y", Variable::Type::CONTINUOUS};
  const Variable z_{"z", Variable::Type::CONTINUOUS};
};

::testing::AssertionResult CheckSolution(const Formula& f,
                                         const Box& solution) {
  FormulaEvaluator formula_evaluator{
      make_relational_formula_evaluator(f, solution.variables())};
  const FormulaEvaluationResult formula_evaluation_result{
      formula_evaluator(solution)};
  if (formula_evaluation_result.type() ==
      FormulaEvaluationResult::Type::UNSAT) {
    return ::testing::AssertionFailure() << "UNSAT detected!";
  }
  if (!formula_evaluation_result.evaluation().contains(0.0)) {
    return ::testing::AssertionFailure() << "The interval evaluation indicates "
                                            "that the solution does not "
                                            "satisfy the constraint.";
  }
  return ::testing::AssertionSuccess();
}

// Tests CheckSatisfiability (δ-SAT case).
TEST_F(ApiTest, CheckSatisfiability_DeltaSat) {
  // 0 ≤ x ≤ 5
  // 0 ≤ y ≤ 5
  // 0 ≤ z ≤ 5
  // 2x + y = z
  const Formula f1{0 <= x_ && x_ <= 5};
  const Formula f2{0 <= y_ && y_ <= 5};
  const Formula f3{0 <= z_ && z_ <= 5};
  const Formula f4{2 * x_ + y_ == z_};

  // Checks the API returning an optional.
  {
    auto result = CheckSatisfiability(f1 && f2 && f3 && f4, 0.001);
    ASSERT_TRUE(result);
    EXPECT_TRUE(CheckSolution(f4, *result));
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result{CheckSatisfiability(f1 && f2 && f3 && f4, 0.001, &b)};
    ASSERT_TRUE(result);
    EXPECT_TRUE(CheckSolution(f4, b));
  }
}

// Tests CheckSatisfiability (UNSAT case).
TEST_F(ApiTest, CheckSatisfiability_Unsat) {
  // 2x² + 6x + 5 < 0
  // -10 ≤ x ≤ 10
  const Formula f1{2 * x_ * x_ + 6 * x_ + 5 < 0};
  const Formula f2{-10 <= x_ && x_ <= 10};

  // Checks the API returning an optional.
  {
    auto result = CheckSatisfiability(f1 && f2, 0.001);
    EXPECT_FALSE(result);
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result{CheckSatisfiability(f1 && f2, 0.001, &b)};
    EXPECT_FALSE(result);
  }
}

TEST_F(ApiTest, Minimize1) {
  // minimize 2x² + 6x + 5 s.t. -4 ≤ x ≤ 0
  const Expression objective{2 * x_ * x_ + 6 * x_ + 5};
  const Formula constraint{-10 <= x_ && x_ <= 10};
  const double delta{0.01};
  const double known_minimum = 0.5;

  // Checks the API returning an optional.
  {
    const auto result = Minimize(objective, constraint, delta);
    ASSERT_TRUE(result);
    const double x = (*result)[x_].mid();
    EXPECT_TRUE(-10 <= x && x <= 10);
    EXPECT_LT(2 * x * x + 6 * x + 5, known_minimum + delta);
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result = Minimize(objective, constraint, delta, &b);
    ASSERT_TRUE(result);
    const double x = b[x_].mid();
    EXPECT_TRUE(-10 <= x && x <= 10);
    EXPECT_LT(2 * x * x + 6 * x + 5, known_minimum + delta);
  }
}

TEST_F(ApiTest, Minimize2) {
  // minimize sin(3x) - 2cos(x) s.t. -3 ≤ x ≤ 3
  const Expression objective{sin(3 * x_) - 2 * cos(x_)};
  const Formula constraint{-3 <= x_ && x_ <= 3};
  const double delta{0.001};
  const double known_minimum = -2.77877;

  // Checks the API returning an optional.
  {
    const auto result = Minimize(objective, constraint, delta);
    ASSERT_TRUE(result);
    const double x = (*result)[x_].mid();
    EXPECT_TRUE(-3 <= x && x <= 3);
    EXPECT_LT(sin(3 * x) - 2 * cos(x), known_minimum + delta);
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result = Minimize(objective, constraint, delta, &b);
    ASSERT_TRUE(result);
    const double x = b[x_].mid();
    EXPECT_TRUE(-3 <= x && x <= 3);
    EXPECT_LT(sin(3 * x) - 2 * cos(x), known_minimum + delta);
  }
}

}  // namespace
}  // namespace dreal
<commit_msg>test(api/api_test.cc): Add CheckSatisfiabilityMixedBooleanAndContinuous<commit_after>#include "dreal/api/api.h"

#include <cmath>
#include <gtest/gtest.h>

#include "dreal/solver/formula_evaluator.h"

namespace dreal {
namespace {

class ApiTest : public ::testing::Test {
 protected:
  const Variable x_{"x", Variable::Type::CONTINUOUS};
  const Variable y_{"y", Variable::Type::CONTINUOUS};
  const Variable z_{"z", Variable::Type::CONTINUOUS};
};

::testing::AssertionResult CheckSolution(const Formula& f,
                                         const Box& solution) {
  FormulaEvaluator formula_evaluator{
      make_relational_formula_evaluator(f, solution.variables())};
  const FormulaEvaluationResult formula_evaluation_result{
      formula_evaluator(solution)};
  if (formula_evaluation_result.type() ==
      FormulaEvaluationResult::Type::UNSAT) {
    return ::testing::AssertionFailure() << "UNSAT detected!";
  }
  if (!formula_evaluation_result.evaluation().contains(0.0)) {
    return ::testing::AssertionFailure() << "The interval evaluation indicates "
                                            "that the solution does not "
                                            "satisfy the constraint.";
  }
  return ::testing::AssertionSuccess();
}

// Tests CheckSatisfiability (δ-SAT case).
TEST_F(ApiTest, CheckSatisfiabilityMixedBooleanAndContinuous) {
  const Variable b1{"b1", Variable::Type::BOOLEAN};
  const Variable b2{"b2", Variable::Type::BOOLEAN};
  const auto result = CheckSatisfiability(
      !b1 && b2 && (sin(x_) == 1) && x_ > 0 && x_ < 2 * 3.141592, 0.001);
  ASSERT_TRUE(result);
  EXPECT_EQ((*result)[b1], 0.0);
  EXPECT_EQ((*result)[b2], 1.0);
  EXPECT_NEAR(std::sin((*result)[x_].mid()), 1.0, 0.001);
}

// Tests CheckSatisfiability (δ-SAT case).
TEST_F(ApiTest, CheckSatisfiabilityDeltaSat) {
  // 0 ≤ x ≤ 5
  // 0 ≤ y ≤ 5
  // 0 ≤ z ≤ 5
  // 2x + y = z
  const Formula f1{0 <= x_ && x_ <= 5};
  const Formula f2{0 <= y_ && y_ <= 5};
  const Formula f3{0 <= z_ && z_ <= 5};
  const Formula f4{2 * x_ + y_ == z_};

  // Checks the API returning an optional.
  {
    auto result = CheckSatisfiability(f1 && f2 && f3 && f4, 0.001);
    ASSERT_TRUE(result);
    EXPECT_TRUE(CheckSolution(f4, *result));
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result{CheckSatisfiability(f1 && f2 && f3 && f4, 0.001, &b)};
    ASSERT_TRUE(result);
    EXPECT_TRUE(CheckSolution(f4, b));
  }
}

// Tests CheckSatisfiability (UNSAT case).
TEST_F(ApiTest, CheckSatisfiabilityUnsat) {
  // 2x² + 6x + 5 < 0
  // -10 ≤ x ≤ 10
  const Formula f1{2 * x_ * x_ + 6 * x_ + 5 < 0};
  const Formula f2{-10 <= x_ && x_ <= 10};

  // Checks the API returning an optional.
  {
    auto result = CheckSatisfiability(f1 && f2, 0.001);
    EXPECT_FALSE(result);
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result{CheckSatisfiability(f1 && f2, 0.001, &b)};
    EXPECT_FALSE(result);
  }
}

TEST_F(ApiTest, Minimize1) {
  // minimize 2x² + 6x + 5 s.t. -4 ≤ x ≤ 0
  const Expression objective{2 * x_ * x_ + 6 * x_ + 5};
  const Formula constraint{-10 <= x_ && x_ <= 10};
  const double delta{0.01};
  const double known_minimum = 0.5;

  // Checks the API returning an optional.
  {
    const auto result = Minimize(objective, constraint, delta);
    ASSERT_TRUE(result);
    const double x = (*result)[x_].mid();
    EXPECT_TRUE(-10 <= x && x <= 10);
    EXPECT_LT(2 * x * x + 6 * x + 5, known_minimum + delta);
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result = Minimize(objective, constraint, delta, &b);
    ASSERT_TRUE(result);
    const double x = b[x_].mid();
    EXPECT_TRUE(-10 <= x && x <= 10);
    EXPECT_LT(2 * x * x + 6 * x + 5, known_minimum + delta);
  }
}

TEST_F(ApiTest, Minimize2) {
  // minimize sin(3x) - 2cos(x) s.t. -3 ≤ x ≤ 3
  const Expression objective{sin(3 * x_) - 2 * cos(x_)};
  const Formula constraint{-3 <= x_ && x_ <= 3};
  const double delta{0.001};
  const double known_minimum = -2.77877;

  // Checks the API returning an optional.
  {
    const auto result = Minimize(objective, constraint, delta);
    ASSERT_TRUE(result);
    const double x = (*result)[x_].mid();
    EXPECT_TRUE(-3 <= x && x <= 3);
    EXPECT_LT(sin(3 * x) - 2 * cos(x), known_minimum + delta);
  }

  // Checks the API returning a bool.
  {
    Box b;
    const bool result = Minimize(objective, constraint, delta, &b);
    ASSERT_TRUE(result);
    const double x = b[x_].mid();
    EXPECT_TRUE(-3 <= x && x <= 3);
    EXPECT_LT(sin(3 * x) - 2 * cos(x), known_minimum + delta);
  }
}

}  // namespace
}  // namespace dreal
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "content/browser/accessibility/browser_accessibility_manager.h"

#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/common/accessibility_messages.h"

namespace content {

BrowserAccessibility* BrowserAccessibilityFactory::Create() {
  return BrowserAccessibility::Create();
}

// Start child IDs at -1 and decrement each time, because clients use
// child IDs of 1, 2, 3, ... to access the children of an object by
// index, so we use negative IDs to clearly distinguish between indices
// and unique IDs.
// static
int32 BrowserAccessibilityManager::next_child_id_ = -1;

#if !defined(OS_MACOSX) && \
    !(defined(OS_WIN) && !defined(USE_AURA)) && \
    !defined(TOOLKIT_GTK)
// We have subclassess of BrowserAccessibilityManager on Mac, Linux/GTK,
// and non-Aura Win. For any other platform, instantiate the base class.
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    gfx::NativeView parent_view,
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManager(
      parent_view, src, delegate, factory);
}
#endif

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::CreateEmptyDocument(
    gfx::NativeView parent_view,
    AccessibilityNodeData::State state,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  // Use empty document to process notifications
  AccessibilityNodeData empty_document;
  empty_document.id = 0;
  empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;
  empty_document.state = state | (1 << AccessibilityNodeData::STATE_READONLY);
  return BrowserAccessibilityManager::Create(
      parent_view, empty_document, delegate, factory);
}

BrowserAccessibilityManager::BrowserAccessibilityManager(
    gfx::NativeView parent_view,
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : parent_view_(parent_view),
      delegate_(delegate),
      factory_(factory),
      root_(NULL),
      focus_(NULL),
      osk_state_(OSK_ALLOWED) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(src);
  if (!UpdateNodes(nodes))
    return;
  if (!focus_)
    SetFocus(root_, false);
}

// static
int32 BrowserAccessibilityManager::GetNextChildID() {
  // Get the next child ID, and wrap around when we get near the end
  // of a 32-bit integer range. It's okay to wrap around; we just want
  // to avoid it as long as possible because clients may cache the ID of
  // an object for a while to determine if they've seen it before.
  next_child_id_--;
  if (next_child_id_ == -2000000000)
    next_child_id_ = -1;

  return next_child_id_;
}

BrowserAccessibilityManager::~BrowserAccessibilityManager() {
  if (root_)
    root_->Destroy();
}

BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
  return root_;
}

BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID(
    int32 child_id) {
  base::hash_map<int32, BrowserAccessibility*>::iterator iter =
      child_id_map_.find(child_id);
  if (iter != child_id_map_.end()) {
    return iter->second;
  } else {
    return NULL;
  }
}

BrowserAccessibility* BrowserAccessibilityManager::GetFromRendererID(
    int32 renderer_id) {
  base::hash_map<int32, int32>::iterator iter =
      renderer_id_to_child_id_map_.find(renderer_id);
  if (iter == renderer_id_to_child_id_map_.end())
    return NULL;

  int32 child_id = iter->second;
  return GetFromChildID(child_id);
}

void BrowserAccessibilityManager::GotFocus(bool touch_event_context) {
  if (!touch_event_context)
    osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED;

  if (!focus_)
    return;

  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

void BrowserAccessibilityManager::WasHidden() {
  osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_HIDDEN;
}

void BrowserAccessibilityManager::GotMouseDown() {
  osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

bool BrowserAccessibilityManager::IsOSKAllowed(const gfx::Rect& bounds) {
  if (!delegate_ || !delegate_->HasFocus())
    return false;

  gfx::Point touch_point = delegate_->GetLastTouchEventLocation();
  return bounds.Contains(touch_point);
}

void BrowserAccessibilityManager::Remove(BrowserAccessibility* node) {
  if (node == focus_)
    SetFocus(root_, false);
  int child_id = node->child_id();
  int renderer_id = node->renderer_id();
  child_id_map_.erase(child_id);
  DCHECK(renderer_id_to_child_id_map_[renderer_id] == child_id);
  // Make sure we don't overwrite a newer entry (see UpdateNode for a possible
  // corner case).
  if (renderer_id_to_child_id_map_[renderer_id] == child_id)
    renderer_id_to_child_id_map_.erase(renderer_id);
}

void BrowserAccessibilityManager::OnAccessibilityNotifications(
    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
  for (uint32 index = 0; index < params.size(); index++) {
    const AccessibilityHostMsg_NotificationParams& param = params[index];

    // Update nodes that changed.
    if (!UpdateNodes(param.nodes))
      return;

    // Find the node corresponding to the id that's the target of the
    // notification (which may not be the root of the update tree).
    BrowserAccessibility* node = GetFromRendererID(param.id);
    if (!node)
      continue;

    int notification_type = param.notification_type;
    if (notification_type == AccessibilityNotificationFocusChanged ||
        notification_type == AccessibilityNotificationBlur) {
      SetFocus(node, false);

      if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
          osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
        osk_state_ = OSK_ALLOWED;

      // Don't send a native focus event if the window itself doesn't
      // have focus.
      if (delegate_ && !delegate_->HasFocus())
        continue;
    }

    // Send the notification event to the operating system.
    NotifyAccessibilityEvent(notification_type, node);

    // Set initial focus when a page is loaded.
    if (notification_type == AccessibilityNotificationLoadComplete) {
      if (!focus_)
        SetFocus(root_, false);
      if (!delegate_ || delegate_->HasFocus())
        NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
    }
  }
}

gfx::NativeView BrowserAccessibilityManager::GetParentView() {
  return parent_view_;
}

BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
    BrowserAccessibility* root) {
  if (focus_ && (!root || focus_->IsDescendantOf(root)))
    return focus_;

  return NULL;
}

void BrowserAccessibilityManager::SetFocus(
    BrowserAccessibility* node, bool notify) {
  if (focus_ != node)
    focus_ = node;

  if (notify && node && delegate_)
    delegate_->SetAccessibilityFocus(node->renderer_id());
}

void BrowserAccessibilityManager::DoDefaultAction(
    const BrowserAccessibility& node) {
  if (delegate_)
    delegate_->AccessibilityDoDefaultAction(node.renderer_id());
}

void BrowserAccessibilityManager::ScrollToMakeVisible(
    const BrowserAccessibility& node, gfx::Rect subfocus) {
  if (delegate_) {
    delegate_->AccessibilityScrollToMakeVisible(node.renderer_id(), subfocus);
  }
}

void BrowserAccessibilityManager::ScrollToPoint(
    const BrowserAccessibility& node, gfx::Point point) {
  if (delegate_) {
    delegate_->AccessibilityScrollToPoint(node.renderer_id(), point);
  }
}

void BrowserAccessibilityManager::SetTextSelection(
    const BrowserAccessibility& node, int start_offset, int end_offset) {
  if (delegate_) {
    delegate_->AccessibilitySetTextSelection(
        node.renderer_id(), start_offset, end_offset);
  }
}

gfx::Rect BrowserAccessibilityManager::GetViewBounds() {
  if (delegate_)
    return delegate_->GetViewBounds();
  return gfx::Rect();
}

void BrowserAccessibilityManager::UpdateNodesForTesting(
    const AccessibilityNodeData& node1,
    const AccessibilityNodeData& node2 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node3 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node4 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node5 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node6 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node7 /* = AccessibilityNodeData() */) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(node1);
  if (node2.id != AccessibilityNodeData().id)
    nodes.push_back(node2);
  if (node3.id != AccessibilityNodeData().id)
    nodes.push_back(node3);
  if (node4.id != AccessibilityNodeData().id)
    nodes.push_back(node4);
  if (node5.id != AccessibilityNodeData().id)
    nodes.push_back(node5);
  if (node6.id != AccessibilityNodeData().id)
    nodes.push_back(node6);
  if (node7.id != AccessibilityNodeData().id)
    nodes.push_back(node7);
  UpdateNodes(nodes);
}

bool BrowserAccessibilityManager::UpdateNodes(
    const std::vector<AccessibilityNodeData>& nodes) {
  bool success = true;

  // First, update all of the nodes in the tree.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    if (!UpdateNode(nodes[i]))
      success = false;
  }

  // In a second pass, call PostInitialize on each one - this must
  // be called after all of each node's children are initialized too.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    BrowserAccessibility* instance = GetFromRendererID(nodes[i].id);
    if (instance) {
      instance->PostInitialize();
    } else {
      success = false;
    }
  }

  if (!success) {
    // A bad accessibility tree could lead to memory corruption.
    // Ask the delegate to crash the renderer, or if not available,
    // crash the browser.
    if (delegate_)
      delegate_->FatalAccessibilityTreeError();
    else
      CHECK(false);
  }

  return success;
}

BrowserAccessibility* BrowserAccessibilityManager::CreateNode(
    BrowserAccessibility* parent,
    int32 renderer_id,
    int32 index_in_parent) {
  BrowserAccessibility* instance = factory_->Create();
  int32 child_id = GetNextChildID();
  instance->InitializeTreeStructure(
      this, parent, child_id, renderer_id, index_in_parent);
  child_id_map_[child_id] = instance;
  renderer_id_to_child_id_map_[renderer_id] = child_id;
  return instance;
}

bool BrowserAccessibilityManager::UpdateNode(const AccessibilityNodeData& src) {
  // This method updates one node in the tree based on serialized data
  // received from the renderer. First, look up the node by id. If it's
  // not found, then either the root of the tree is being swapped, or
  // we're out of sync with the renderer and this is a serious error.
  BrowserAccessibility* instance = GetFromRendererID(src.id);
  if (!instance) {
    if (src.role != AccessibilityNodeData::ROLE_ROOT_WEB_AREA)
      return false;
    instance = CreateNode(NULL, src.id, 0);
  }

  // Update all of the node-specific data, like its role, state, name, etc.
  instance->InitializeData(src);

  //
  // Update the children in three steps:
  //
  // 1. Iterate over the old children and delete nodes that are no longer
  //    in the tree.
  // 2. Build up a vector of new children, reusing children that haven't
  //    changed (but may have been reordered) and adding new empty
  //    objects for new children.
  // 3. Swap in the new children vector for the old one.

  // Delete any previous children of this instance that are no longer
  // children first. We make a deletion-only pass first to prevent a
  // node that's being reparented from being the child of both its old
  // parent and new parent, which could lead to a double-free.
  // If a node is reparented, the renderer will always send us a fresh
  // copy of the node.
  std::set<int32> new_child_ids;
  for (size_t i = 0; i < src.child_ids.size(); ++i) {
    if (new_child_ids.find(src.child_ids[i]) != new_child_ids.end())
      return false;
    new_child_ids.insert(src.child_ids[i]);
  }
  const std::vector<BrowserAccessibility*>& old_children = instance->children();
  for (size_t i = 0; i < old_children.size(); ++i) {
    int old_id = old_children[i]->renderer_id();
    if (new_child_ids.find(old_id) == new_child_ids.end())
      old_children[i]->Destroy();
  }

  // Now build a vector of new children, reusing objects that were already
  // children of this node before.
  std::vector<BrowserAccessibility*> new_children;
  for (size_t i = 0; i < src.child_ids.size(); i++) {
    int32 child_renderer_id = src.child_ids[i];
    int32 index_in_parent = static_cast<int32>(i);
    BrowserAccessibility* child = GetFromRendererID(child_renderer_id);
    if (child) {
      if (child->parent() != instance) {
        instance->SwapChildren(new_children);
        return false;
      }
      child->UpdateParent(instance, index_in_parent);
    } else {
      child = CreateNode(instance, child_renderer_id, index_in_parent);
    }
    new_children.push_back(child);
  }

  // Finally, swap in the new children vector for the old.
  instance->SwapChildren(new_children);

  // Handle the case where this node is the new root of the tree.
  if (src.role == AccessibilityNodeData::ROLE_ROOT_WEB_AREA &&
      (!root_ || root_->renderer_id() != src.id)) {
    if (root_)
      root_->Destroy();
    if (focus_ == root_)
      focus_ = instance;
    root_ = instance;
  }

  // Keep track of what node is focused.
  if ((src.state >> AccessibilityNodeData::STATE_FOCUSED) & 1)
    SetFocus(instance, false);

  return true;
}

}  // namespace content
<commit_msg>Fix memory leak in BrowserAccessibilityManager::UpdateNode.<commit_after>// Copyright (c) 2012 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 "content/browser/accessibility/browser_accessibility_manager.h"

#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/common/accessibility_messages.h"

namespace content {

BrowserAccessibility* BrowserAccessibilityFactory::Create() {
  return BrowserAccessibility::Create();
}

// Start child IDs at -1 and decrement each time, because clients use
// child IDs of 1, 2, 3, ... to access the children of an object by
// index, so we use negative IDs to clearly distinguish between indices
// and unique IDs.
// static
int32 BrowserAccessibilityManager::next_child_id_ = -1;

#if !defined(OS_MACOSX) && \
    !(defined(OS_WIN) && !defined(USE_AURA)) && \
    !defined(TOOLKIT_GTK)
// We have subclassess of BrowserAccessibilityManager on Mac, Linux/GTK,
// and non-Aura Win. For any other platform, instantiate the base class.
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
    gfx::NativeView parent_view,
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  return new BrowserAccessibilityManager(
      parent_view, src, delegate, factory);
}
#endif

// static
BrowserAccessibilityManager* BrowserAccessibilityManager::CreateEmptyDocument(
    gfx::NativeView parent_view,
    AccessibilityNodeData::State state,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory) {
  // Use empty document to process notifications
  AccessibilityNodeData empty_document;
  empty_document.id = 0;
  empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;
  empty_document.state = state | (1 << AccessibilityNodeData::STATE_READONLY);
  return BrowserAccessibilityManager::Create(
      parent_view, empty_document, delegate, factory);
}

BrowserAccessibilityManager::BrowserAccessibilityManager(
    gfx::NativeView parent_view,
    const AccessibilityNodeData& src,
    BrowserAccessibilityDelegate* delegate,
    BrowserAccessibilityFactory* factory)
    : parent_view_(parent_view),
      delegate_(delegate),
      factory_(factory),
      root_(NULL),
      focus_(NULL),
      osk_state_(OSK_ALLOWED) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(src);
  if (!UpdateNodes(nodes))
    return;
  if (!focus_)
    SetFocus(root_, false);
}

// static
int32 BrowserAccessibilityManager::GetNextChildID() {
  // Get the next child ID, and wrap around when we get near the end
  // of a 32-bit integer range. It's okay to wrap around; we just want
  // to avoid it as long as possible because clients may cache the ID of
  // an object for a while to determine if they've seen it before.
  next_child_id_--;
  if (next_child_id_ == -2000000000)
    next_child_id_ = -1;

  return next_child_id_;
}

BrowserAccessibilityManager::~BrowserAccessibilityManager() {
  if (root_)
    root_->Destroy();
}

BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
  return root_;
}

BrowserAccessibility* BrowserAccessibilityManager::GetFromChildID(
    int32 child_id) {
  base::hash_map<int32, BrowserAccessibility*>::iterator iter =
      child_id_map_.find(child_id);
  if (iter != child_id_map_.end()) {
    return iter->second;
  } else {
    return NULL;
  }
}

BrowserAccessibility* BrowserAccessibilityManager::GetFromRendererID(
    int32 renderer_id) {
  base::hash_map<int32, int32>::iterator iter =
      renderer_id_to_child_id_map_.find(renderer_id);
  if (iter == renderer_id_to_child_id_map_.end())
    return NULL;

  int32 child_id = iter->second;
  return GetFromChildID(child_id);
}

void BrowserAccessibilityManager::GotFocus(bool touch_event_context) {
  if (!touch_event_context)
    osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED;

  if (!focus_)
    return;

  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

void BrowserAccessibilityManager::WasHidden() {
  osk_state_ = OSK_DISALLOWED_BECAUSE_TAB_HIDDEN;
}

void BrowserAccessibilityManager::GotMouseDown() {
  osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
  NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
}

bool BrowserAccessibilityManager::IsOSKAllowed(const gfx::Rect& bounds) {
  if (!delegate_ || !delegate_->HasFocus())
    return false;

  gfx::Point touch_point = delegate_->GetLastTouchEventLocation();
  return bounds.Contains(touch_point);
}

void BrowserAccessibilityManager::Remove(BrowserAccessibility* node) {
  if (node == focus_)
    SetFocus(root_, false);
  int child_id = node->child_id();
  int renderer_id = node->renderer_id();
  child_id_map_.erase(child_id);
  DCHECK(renderer_id_to_child_id_map_[renderer_id] == child_id);
  // Make sure we don't overwrite a newer entry (see UpdateNode for a possible
  // corner case).
  if (renderer_id_to_child_id_map_[renderer_id] == child_id)
    renderer_id_to_child_id_map_.erase(renderer_id);
}

void BrowserAccessibilityManager::OnAccessibilityNotifications(
    const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
  for (uint32 index = 0; index < params.size(); index++) {
    const AccessibilityHostMsg_NotificationParams& param = params[index];

    // Update nodes that changed.
    if (!UpdateNodes(param.nodes))
      return;

    // Find the node corresponding to the id that's the target of the
    // notification (which may not be the root of the update tree).
    BrowserAccessibility* node = GetFromRendererID(param.id);
    if (!node)
      continue;

    int notification_type = param.notification_type;
    if (notification_type == AccessibilityNotificationFocusChanged ||
        notification_type == AccessibilityNotificationBlur) {
      SetFocus(node, false);

      if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
          osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
        osk_state_ = OSK_ALLOWED;

      // Don't send a native focus event if the window itself doesn't
      // have focus.
      if (delegate_ && !delegate_->HasFocus())
        continue;
    }

    // Send the notification event to the operating system.
    NotifyAccessibilityEvent(notification_type, node);

    // Set initial focus when a page is loaded.
    if (notification_type == AccessibilityNotificationLoadComplete) {
      if (!focus_)
        SetFocus(root_, false);
      if (!delegate_ || delegate_->HasFocus())
        NotifyAccessibilityEvent(AccessibilityNotificationFocusChanged, focus_);
    }
  }
}

gfx::NativeView BrowserAccessibilityManager::GetParentView() {
  return parent_view_;
}

BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
    BrowserAccessibility* root) {
  if (focus_ && (!root || focus_->IsDescendantOf(root)))
    return focus_;

  return NULL;
}

void BrowserAccessibilityManager::SetFocus(
    BrowserAccessibility* node, bool notify) {
  if (focus_ != node)
    focus_ = node;

  if (notify && node && delegate_)
    delegate_->SetAccessibilityFocus(node->renderer_id());
}

void BrowserAccessibilityManager::DoDefaultAction(
    const BrowserAccessibility& node) {
  if (delegate_)
    delegate_->AccessibilityDoDefaultAction(node.renderer_id());
}

void BrowserAccessibilityManager::ScrollToMakeVisible(
    const BrowserAccessibility& node, gfx::Rect subfocus) {
  if (delegate_) {
    delegate_->AccessibilityScrollToMakeVisible(node.renderer_id(), subfocus);
  }
}

void BrowserAccessibilityManager::ScrollToPoint(
    const BrowserAccessibility& node, gfx::Point point) {
  if (delegate_) {
    delegate_->AccessibilityScrollToPoint(node.renderer_id(), point);
  }
}

void BrowserAccessibilityManager::SetTextSelection(
    const BrowserAccessibility& node, int start_offset, int end_offset) {
  if (delegate_) {
    delegate_->AccessibilitySetTextSelection(
        node.renderer_id(), start_offset, end_offset);
  }
}

gfx::Rect BrowserAccessibilityManager::GetViewBounds() {
  if (delegate_)
    return delegate_->GetViewBounds();
  return gfx::Rect();
}

void BrowserAccessibilityManager::UpdateNodesForTesting(
    const AccessibilityNodeData& node1,
    const AccessibilityNodeData& node2 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node3 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node4 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node5 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node6 /* = AccessibilityNodeData() */,
    const AccessibilityNodeData& node7 /* = AccessibilityNodeData() */) {
  std::vector<AccessibilityNodeData> nodes;
  nodes.push_back(node1);
  if (node2.id != AccessibilityNodeData().id)
    nodes.push_back(node2);
  if (node3.id != AccessibilityNodeData().id)
    nodes.push_back(node3);
  if (node4.id != AccessibilityNodeData().id)
    nodes.push_back(node4);
  if (node5.id != AccessibilityNodeData().id)
    nodes.push_back(node5);
  if (node6.id != AccessibilityNodeData().id)
    nodes.push_back(node6);
  if (node7.id != AccessibilityNodeData().id)
    nodes.push_back(node7);
  UpdateNodes(nodes);
}

bool BrowserAccessibilityManager::UpdateNodes(
    const std::vector<AccessibilityNodeData>& nodes) {
  bool success = true;

  // First, update all of the nodes in the tree.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    if (!UpdateNode(nodes[i]))
      success = false;
  }

  // In a second pass, call PostInitialize on each one - this must
  // be called after all of each node's children are initialized too.
  for (size_t i = 0; i < nodes.size() && success; i++) {
    BrowserAccessibility* instance = GetFromRendererID(nodes[i].id);
    if (instance) {
      instance->PostInitialize();
    } else {
      success = false;
    }
  }

  if (!success) {
    // A bad accessibility tree could lead to memory corruption.
    // Ask the delegate to crash the renderer, or if not available,
    // crash the browser.
    if (delegate_)
      delegate_->FatalAccessibilityTreeError();
    else
      CHECK(false);
  }

  return success;
}

BrowserAccessibility* BrowserAccessibilityManager::CreateNode(
    BrowserAccessibility* parent,
    int32 renderer_id,
    int32 index_in_parent) {
  BrowserAccessibility* instance = factory_->Create();
  int32 child_id = GetNextChildID();
  instance->InitializeTreeStructure(
      this, parent, child_id, renderer_id, index_in_parent);
  child_id_map_[child_id] = instance;
  renderer_id_to_child_id_map_[renderer_id] = child_id;
  return instance;
}

bool BrowserAccessibilityManager::UpdateNode(const AccessibilityNodeData& src) {
  // This method updates one node in the tree based on serialized data
  // received from the renderer.

  // Create a set of child ids in |src| for fast lookup. If a duplicate id is
  // found, exit now with a fatal error before changing anything else.
  std::set<int32> new_child_ids;
  for (size_t i = 0; i < src.child_ids.size(); ++i) {
    if (new_child_ids.find(src.child_ids[i]) != new_child_ids.end())
      return false;
    new_child_ids.insert(src.child_ids[i]);
  }

  // Look up the node by id. If it's not found, then either the root
  // of the tree is being swapped, or we're out of sync with the renderer
  // and this is a serious error.
  BrowserAccessibility* instance = GetFromRendererID(src.id);
  if (!instance) {
    if (src.role != AccessibilityNodeData::ROLE_ROOT_WEB_AREA)
      return false;
    instance = CreateNode(NULL, src.id, 0);
  }

  // Update all of the node-specific data, like its role, state, name, etc.
  instance->InitializeData(src);

  //
  // Update the children in three steps:
  //
  // 1. Iterate over the old children and delete nodes that are no longer
  //    in the tree.
  // 2. Build up a vector of new children, reusing children that haven't
  //    changed (but may have been reordered) and adding new empty
  //    objects for new children.
  // 3. Swap in the new children vector for the old one.

  // Delete any previous children of this instance that are no longer
  // children first. We make a deletion-only pass first to prevent a
  // node that's being reparented from being the child of both its old
  // parent and new parent, which could lead to a double-free.
  // If a node is reparented, the renderer will always send us a fresh
  // copy of the node.
  const std::vector<BrowserAccessibility*>& old_children = instance->children();
  for (size_t i = 0; i < old_children.size(); ++i) {
    int old_id = old_children[i]->renderer_id();
    if (new_child_ids.find(old_id) == new_child_ids.end())
      old_children[i]->Destroy();
  }

  // Now build a vector of new children, reusing objects that were already
  // children of this node before.
  std::vector<BrowserAccessibility*> new_children;
  bool success = true;
  for (size_t i = 0; i < src.child_ids.size(); i++) {
    int32 child_renderer_id = src.child_ids[i];
    int32 index_in_parent = static_cast<int32>(i);
    BrowserAccessibility* child = GetFromRendererID(child_renderer_id);
    if (child) {
      if (child->parent() != instance) {
        // This is a serious error - nodes should never be reparented.
        // If this case occurs, continue so this node isn't left in an
        // inconsistent state, but return failure at the end.
        success = false;
        continue;
      }
      child->UpdateParent(instance, index_in_parent);
    } else {
      child = CreateNode(instance, child_renderer_id, index_in_parent);
    }
    new_children.push_back(child);
  }

  // Finally, swap in the new children vector for the old.
  instance->SwapChildren(new_children);

  // Handle the case where this node is the new root of the tree.
  if (src.role == AccessibilityNodeData::ROLE_ROOT_WEB_AREA &&
      (!root_ || root_->renderer_id() != src.id)) {
    if (root_)
      root_->Destroy();
    if (focus_ == root_)
      focus_ = instance;
    root_ = instance;
  }

  // Keep track of what node is focused.
  if ((src.state >> AccessibilityNodeData::STATE_FOCUSED) & 1)
    SetFocus(instance, false);

  return success;
}

}  // namespace content
<|endoftext|>


<commit_before>#include "SchedulerTrack.h"

#include "Capture.h"
#include "EventTrack.h"
#include "GlCanvas.h"
#include "TimeGraph.h"

const Color kInactiveColor(100, 100, 100, 255);
const Color kSelectionColor(0, 128, 255, 255);

void SchedulerTrack::Draw(GlCanvas* canvas, bool picking) {
  ThreadTrack::Draw(canvas, picking);
}

float SchedulerTrack::GetHeight() const {
  TimeGraphLayout& layout = time_graph_->GetLayout();
  return depth_ *
             (layout.GetTextCoresHeight() + layout.GetSpaceBetweenCores()) +
         layout.GetEventTrackHeight() + layout.GetTrackBottomMargin();
}

inline Color GetTimerColor(const Timer& timer, TimeGraph* time_graph,
                           bool is_selected, bool same_tid, bool same_pid,
                           bool inactive) {
  if (is_selected) {
    return kSelectionColor;
  } else if (!same_tid && (inactive || !same_pid)) {
    return kInactiveColor;
  }
  return time_graph->GetTimesliceColor(timer);
}

inline float GetYFromDepth(const TimeGraphLayout& layout, float track_y,
                           uint32_t depth) {
  return track_y - layout.GetEventTrackHeight() -
         layout.GetSpaceBetweenTracksAndThread() -
         (layout.GetTextCoresHeight() + layout.GetSpaceBetweenCores()) *
             (depth + 1);
}

void SchedulerTrack::UpdatePrimitives(uint64_t min_tick, uint64_t max_tick) {
  event_track_->UpdatePrimitives(min_tick, max_tick);

  Batcher* batcher = &time_graph_->GetBatcher();
  GlCanvas* canvas = time_graph_->GetCanvas();
  const TimeGraphLayout& layout = time_graph_->GetLayout();
  const auto& target_process = Capture::GTargetProcess;
  uint32_t target_pid = target_process ? target_process->GetID() : 0;
  uint32_t selected_thread_id = Capture::GSelectedThreadId;

  float world_start_x = canvas->GetWorldTopLeftX();
  float world_width = canvas->GetWorldWidth();
  double inv_time_window = 1.0 / time_graph_->GetTimeWindowUs();

  std::vector<std::shared_ptr<TimerChain>> chains_by_depth = GetTimers();
  for (std::shared_ptr<TimerChain>& timer_chain : chains_by_depth) {
    for (TextBox& text_box : *timer_chain) {
      const Timer& timer = text_box.GetTimer();
      if (min_tick > timer.m_End || max_tick < timer.m_Start) continue;

      UpdateDepth(timer.m_Depth + 1);
      double start_us = time_graph_->GetUsFromTick(timer.m_Start);
      double end_us = time_graph_->GetUsFromTick(timer.m_End);
      double elapsed_us = end_us - start_us;
      double normalized_start = start_us * inv_time_window;
      double normalized_length = elapsed_us * inv_time_window;
      float world_timer_width =
          static_cast<float>(normalized_length * world_width);
      float world_timer_x =
          static_cast<float>(world_start_x + normalized_start * world_width);
      float world_timer_y = GetYFromDepth(layout, m_Pos[1], timer.m_Depth);

      bool is_visible_width = normalized_length * canvas->getWidth() > 1;
      bool is_same_pid_as_target = target_pid == 0 || target_pid == timer.m_PID;
      bool is_same_tid_as_selected = timer.m_TID == selected_thread_id;
      bool is_inactive = selected_thread_id != 0 && !is_same_tid_as_selected;
      bool is_selected = &text_box == Capture::GSelectedTextBox;

      Vec2 pos(world_timer_x, world_timer_y);
      Vec2 size(world_timer_width, layout.GetTextCoresHeight());
      float z = GlCanvas::Z_VALUE_BOX_ACTIVE;
      Color color = GetTimerColor(timer, time_graph_, is_selected,
                                  is_same_tid_as_selected,
                                  is_same_pid_as_target, is_inactive);

      if (is_visible_width) {
        batcher->AddShadedBox(pos, size, z, color, PickingID::BOX, &text_box);
      } else {
        auto type = PickingID::LINE;
        batcher->AddVerticalLine(pos, size[1], z, color, type, &text_box);
      }
    }
  }
}
<commit_msg>Fix crash in SchedulerTrack.<commit_after>#include "SchedulerTrack.h"

#include "Capture.h"
#include "EventTrack.h"
#include "GlCanvas.h"
#include "TimeGraph.h"

const Color kInactiveColor(100, 100, 100, 255);
const Color kSelectionColor(0, 128, 255, 255);

void SchedulerTrack::Draw(GlCanvas* canvas, bool picking) {
  ThreadTrack::Draw(canvas, picking);
}

float SchedulerTrack::GetHeight() const {
  TimeGraphLayout& layout = time_graph_->GetLayout();
  return depth_ *
             (layout.GetTextCoresHeight() + layout.GetSpaceBetweenCores()) +
         layout.GetEventTrackHeight() + layout.GetTrackBottomMargin();
}

inline Color GetTimerColor(const Timer& timer, TimeGraph* time_graph,
                           bool is_selected, bool same_tid, bool same_pid,
                           bool inactive) {
  if (is_selected) {
    return kSelectionColor;
  } else if (!same_tid && (inactive || !same_pid)) {
    return kInactiveColor;
  }
  return time_graph->GetTimesliceColor(timer);
}

inline float GetYFromDepth(const TimeGraphLayout& layout, float track_y,
                           uint32_t depth) {
  return track_y - layout.GetEventTrackHeight() -
         layout.GetSpaceBetweenTracksAndThread() -
         (layout.GetTextCoresHeight() + layout.GetSpaceBetweenCores()) *
             (depth + 1);
}

void SchedulerTrack::UpdatePrimitives(uint64_t min_tick, uint64_t max_tick) {
  event_track_->UpdatePrimitives(min_tick, max_tick);

  Batcher* batcher = &time_graph_->GetBatcher();
  GlCanvas* canvas = time_graph_->GetCanvas();
  const TimeGraphLayout& layout = time_graph_->GetLayout();
  const auto& target_process = Capture::GTargetProcess;
  uint32_t target_pid = target_process ? target_process->GetID() : 0;
  uint32_t selected_thread_id = Capture::GSelectedThreadId;

  float world_start_x = canvas->GetWorldTopLeftX();
  float world_width = canvas->GetWorldWidth();
  double inv_time_window = 1.0 / time_graph_->GetTimeWindowUs();

  std::vector<std::shared_ptr<TimerChain>> chains_by_depth = GetTimers();
  for (std::shared_ptr<TimerChain>& timer_chain : chains_by_depth) {
    if (timer_chain == nullptr) continue;
    for (TextBox& text_box : *timer_chain) {
      const Timer& timer = text_box.GetTimer();
      if (min_tick > timer.m_End || max_tick < timer.m_Start) continue;

      UpdateDepth(timer.m_Depth + 1);
      double start_us = time_graph_->GetUsFromTick(timer.m_Start);
      double end_us = time_graph_->GetUsFromTick(timer.m_End);
      double elapsed_us = end_us - start_us;
      double normalized_start = start_us * inv_time_window;
      double normalized_length = elapsed_us * inv_time_window;
      float world_timer_width =
          static_cast<float>(normalized_length * world_width);
      float world_timer_x =
          static_cast<float>(world_start_x + normalized_start * world_width);
      float world_timer_y = GetYFromDepth(layout, m_Pos[1], timer.m_Depth);

      bool is_visible_width = normalized_length * canvas->getWidth() > 1;
      bool is_same_pid_as_target = target_pid == 0 || target_pid == timer.m_PID;
      bool is_same_tid_as_selected = timer.m_TID == selected_thread_id;
      bool is_inactive = selected_thread_id != 0 && !is_same_tid_as_selected;
      bool is_selected = &text_box == Capture::GSelectedTextBox;

      Vec2 pos(world_timer_x, world_timer_y);
      Vec2 size(world_timer_width, layout.GetTextCoresHeight());
      float z = GlCanvas::Z_VALUE_BOX_ACTIVE;
      Color color = GetTimerColor(timer, time_graph_, is_selected,
                                  is_same_tid_as_selected,
                                  is_same_pid_as_target, is_inactive);

      if (is_visible_width) {
        batcher->AddShadedBox(pos, size, z, color, PickingID::BOX, &text_box);
      } else {
        auto type = PickingID::LINE;
        batcher->AddVerticalLine(pos, size[1], z, color, type, &text_box);
      }
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (C) 2010, 2011 and 2012 Marcin Arkadiusz Skrobiranda.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.

#include <Game/GameServer/Human/Operators/GetHumans/GetHumansOperator.hpp>

using namespace GameServer::Common;
using namespace GameServer::Persistence;

namespace GameServer
{
namespace Human
{

GetHumansOperator::GetHumansOperator(
    IHumanPersistenceFacadeShrPtr a_human_persistence_facade
)
    : m_human_persistence_facade(a_human_persistence_facade)
{
}

GetHumansOperatorExitCode GetHumansOperator::getHumans(
    ITransactionShrPtr         a_transaction,
    IDHolder           const & a_id_holder
) const
{
    try
    {
        HumanWithVolumeMap const humans = m_human_persistence_facade->getHumans(a_transaction, a_id_holder);

        return GetHumansOperatorExitCode(GET_HUMANS_OPERATOR_EXIT_CODE_HUMANS_HAVE_BEEN_GOT, humans);
    }
    catch (...)
    {
        return GetHumansOperatorExitCode(GET_HUMANS_OPERATOR_EXIT_CODE_UNEXPECTED_ERROR);
    }
}

} // namespace Human
} // namespace GameServer
<commit_msg>Fix: bugs found during testing.<commit_after>// Copyright (C) 2010, 2011 and 2012 Marcin Arkadiusz Skrobiranda.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.

#include <Game/GameServer/Human/Operators/GetHumans/GetHumansOperator.hpp>

using namespace GameServer::Common;
using namespace GameServer::Persistence;

namespace GameServer
{
namespace Human
{

GetHumansOperator::GetHumansOperator(
    IHumanPersistenceFacadeShrPtr a_human_persistence_facade
)
    : m_human_persistence_facade(a_human_persistence_facade)
{
}

GetHumansOperatorExitCode GetHumansOperator::getHumans(
    ITransactionShrPtr         a_transaction,
    IDHolder           const & a_id_holder
) const
{
    try
    {
        HumanWithVolumeMap const humans = m_human_persistence_facade->getHumans(a_transaction, a_id_holder);

        return (humans.empty())
            ? GetHumansOperatorExitCode(GET_HUMANS_OPERATOR_EXIT_CODE_UNEXPECTED_ERROR)
            : GetHumansOperatorExitCode(GET_HUMANS_OPERATOR_EXIT_CODE_HUMANS_HAVE_BEEN_GOT, humans);
    }
    catch (...)
    {
        return GetHumansOperatorExitCode(GET_HUMANS_OPERATOR_EXIT_CODE_UNEXPECTED_ERROR);
    }
}

} // namespace Human
} // namespace GameServer
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/browser/ui/views/frame/app_non_client_frame_view_aura.h"

#include "base/debug/stack_trace.h"
#include "chrome/browser/ui/views/frame/browser_frame.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "grit/ui_resources.h"
#include "ui/aura/window.h"
#include "ui/base/animation/slide_animation.h"
#include "ui/base/hit_test.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/non_client_view.h"

namespace {
// The number of pixels to use as a hover zone at the top of the screen.
const int kTopMargin = 1;
// How long the hover animation takes if uninterrupted.
const int kHoverFadeDurationMs = 130;
// The number of pixels within the shadow to draw the buttons.
const int kShadowStart = 28;
}

class AppNonClientFrameViewAura::ControlView
    : public views::View, public views::ButtonListener {
 public:
  explicit ControlView(AppNonClientFrameViewAura* owner) :
      owner_(owner),
      close_button_(CreateImageButton(IDR_AURA_WINDOW_FULLSCREEN_CLOSE)),
      restore_button_(CreateImageButton(IDR_AURA_WINDOW_FULLSCREEN_RESTORE)) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    separator_ =
        *rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SEPARATOR).ToSkBitmap();
    shadow_ = *rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SHADOW).ToSkBitmap();
    AddChildView(close_button_);
    AddChildView(restore_button_);
  }

  virtual void Layout() OVERRIDE {
    restore_button_->SetPosition(gfx::Point(kShadowStart, 0));
    close_button_->SetPosition(
        gfx::Point(kShadowStart + close_button_->width() + separator_.width(),
                   0));
  }

  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(shadow_.width(), shadow_.height());
  }

  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    views::View::OnPaint(canvas);
    canvas->DrawBitmapInt(
        separator_, restore_button_->x() + restore_button_->width(), 0);
    canvas->DrawBitmapInt(shadow_, 0, 0);
  }

  void ButtonPressed(
      views::Button* sender,
      const views::Event& event) OVERRIDE {
    if (sender == close_button_)
      owner_->Close();
    else if (sender == restore_button_)
      owner_->Restore();
  }

 private:
  // Gets an image representing 3 bitmaps laid out horizontally that will be
  // used as the normal, hot and pushed states for the created button.
  views::ImageButton* CreateImageButton(int resource_id) {
    views::ImageButton* button = new views::ImageButton(this);
    const SkBitmap* all_images =
        ResourceBundle::GetSharedInstance().GetImageNamed(
            resource_id).ToSkBitmap();
    int width = all_images->width() / 3;
    int height = all_images->height();

    SkBitmap normal, hot, pushed;
    all_images->extractSubset(
        &normal,
        SkIRect::MakeXYWH(0, 0, width, height));
    all_images->extractSubset(
        &hot,
        SkIRect::MakeXYWH(width, 0, width, height));
    all_images->extractSubset(
        &pushed,
        SkIRect::MakeXYWH(2 * width, 0, width, height));
    button->SetImage(views::CustomButton::BS_NORMAL, &normal);
    button->SetImage(views::CustomButton::BS_HOT, &hot);
    button->SetImage(views::CustomButton::BS_PUSHED, &pushed);

    button->SizeToPreferredSize();
    return button;
  }

  AppNonClientFrameViewAura* owner_;
  views::ImageButton* close_button_;
  views::ImageButton* restore_button_;
  SkBitmap separator_;
  SkBitmap shadow_;

  DISALLOW_COPY_AND_ASSIGN(ControlView);
};

class AppNonClientFrameViewAura::Host : public views::MouseWatcherHost {
 public:
  explicit Host(AppNonClientFrameViewAura* owner) : owner_(owner) {}
  virtual ~Host() {}

  virtual bool Contains(
      const gfx::Point& screen_point,
      views::MouseWatcherHost::MouseEventType type) {
    gfx::Rect top_margin = owner_->GetScreenBounds();
    top_margin.set_height(kTopMargin);
    gfx::Rect control_bounds = owner_->GetControlBounds();
    control_bounds.Inset(kShadowStart, 0, 0, kShadowStart);
    return top_margin.Contains(screen_point) ||
        control_bounds.Contains(screen_point);
  }

  AppNonClientFrameViewAura* owner_;

  DISALLOW_COPY_AND_ASSIGN(Host);
};

AppNonClientFrameViewAura::AppNonClientFrameViewAura(
    BrowserFrame* frame, BrowserView* browser_view)
    : BrowserNonClientFrameView(frame, browser_view),
      control_view_(new ControlView(this)),
      control_widget_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          mouse_watcher_(new Host(this), this)) {
}

AppNonClientFrameViewAura::~AppNonClientFrameViewAura() {
}

gfx::Rect AppNonClientFrameViewAura::GetBoundsForClientView() const {
  gfx::Rect bounds = GetLocalBounds();
  bounds.Inset(0, kTopMargin, 0,  0);
  return bounds;
}

gfx::Rect AppNonClientFrameViewAura::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  gfx::Rect bounds = client_bounds;
  bounds.Inset(0, -kTopMargin, 0, 0);
  return bounds;
}

int AppNonClientFrameViewAura::NonClientHitTest(
    const gfx::Point& point) {
  return bounds().Contains(point) ? HTCLIENT : HTNOWHERE;
}

void AppNonClientFrameViewAura::GetWindowMask(const gfx::Size& size,
                                              gfx::Path* window_mask) {
}

void AppNonClientFrameViewAura::ResetWindowControls() {
}

void AppNonClientFrameViewAura::UpdateWindowIcon() {
}

gfx::Rect AppNonClientFrameViewAura::GetBoundsForTabStrip(
    views::View* tabstrip) const {
  return gfx::Rect();
}

int AppNonClientFrameViewAura::GetHorizontalTabStripVerticalOffset(
    bool restored) const {
  return 0;
}

void AppNonClientFrameViewAura::UpdateThrobber(bool running) {
}

void AppNonClientFrameViewAura::OnMouseEntered(
    const views::MouseEvent& event) {
  if (!control_widget_) {
    control_widget_ = new views::Widget;
    views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
    params.parent = browser_view()->GetNativeHandle();
    params.transparent = true;
    control_widget_->Init(params);
    control_widget_->SetContentsView(control_view_);
    aura::Window* window = control_widget_->GetNativeView();
    gfx::Rect control_bounds = GetControlBounds();
    control_bounds.set_y(control_bounds.y() - control_bounds.height());
    window->SetBounds(control_bounds);
    control_widget_->Show();
  }

  ui::Layer* layer = control_widget_->GetNativeView()->layer();
  ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator());
  scoped_setter.SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kHoverFadeDurationMs));
  layer->SetBounds(GetControlBounds());
  layer->SetOpacity(1);

  mouse_watcher_.Start();
}

void AppNonClientFrameViewAura::MouseMovedOutOfHost() {
  ui::Layer* layer = control_widget_->GetNativeView()->layer();

  ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator());
  scoped_setter.SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kHoverFadeDurationMs));
  gfx::Rect control_bounds = GetControlBounds();
  control_bounds.set_y(control_bounds.y() - control_bounds.height());
  layer->SetBounds(control_bounds);
  layer->SetOpacity(0);
}

gfx::Rect AppNonClientFrameViewAura::GetControlBounds() const {
  gfx::Size preferred = control_view_->GetPreferredSize();
  gfx::Point location(width() - preferred.width(), 0);
  ConvertPointToWidget(this, &location);
  return gfx::Rect(
      location.x(), location.y(),
      preferred.width(), preferred.height());
}

void AppNonClientFrameViewAura::Close() {
  if (control_widget_)
    control_widget_->Close();
  control_widget_ = NULL;
  mouse_watcher_.Stop();
  frame()->Close();
}

void AppNonClientFrameViewAura::Restore() {
  if (control_widget_)
    control_widget_->Close();
  control_widget_ = NULL;
  mouse_watcher_.Stop();
  frame()->Restore();
}
<commit_msg>Create black background for full screen app windows BUG=118111 TEST=Visual<commit_after>// Copyright (c) 2012 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/browser/ui/views/frame/app_non_client_frame_view_aura.h"

#include "base/debug/stack_trace.h"
#include "chrome/browser/ui/views/frame/browser_frame.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "grit/ui_resources.h"
#include "ui/aura/window.h"
#include "ui/base/animation/slide_animation.h"
#include "ui/base/hit_test.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/point.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/non_client_view.h"

namespace {
// The number of pixels to use as a hover zone at the top of the screen.
const int kTopMargin = 1;
// How long the hover animation takes if uninterrupted.
const int kHoverFadeDurationMs = 130;
// The number of pixels within the shadow to draw the buttons.
const int kShadowStart = 28;
}

class AppNonClientFrameViewAura::ControlView
    : public views::View, public views::ButtonListener {
 public:
  explicit ControlView(AppNonClientFrameViewAura* owner) :
      owner_(owner),
      close_button_(CreateImageButton(IDR_AURA_WINDOW_FULLSCREEN_CLOSE)),
      restore_button_(CreateImageButton(IDR_AURA_WINDOW_FULLSCREEN_RESTORE)) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    separator_ =
        *rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SEPARATOR).ToSkBitmap();
    shadow_ = *rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SHADOW).ToSkBitmap();
    AddChildView(close_button_);
    AddChildView(restore_button_);
  }

  virtual void Layout() OVERRIDE {
    restore_button_->SetPosition(gfx::Point(kShadowStart, 0));
    close_button_->SetPosition(
        gfx::Point(kShadowStart + close_button_->width() + separator_.width(),
                   0));
  }

  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(shadow_.width(), shadow_.height());
  }

  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    views::View::OnPaint(canvas);
    canvas->DrawBitmapInt(
        separator_, restore_button_->x() + restore_button_->width(), 0);
    canvas->DrawBitmapInt(shadow_, 0, 0);
  }

  void ButtonPressed(
      views::Button* sender,
      const views::Event& event) OVERRIDE {
    if (sender == close_button_)
      owner_->Close();
    else if (sender == restore_button_)
      owner_->Restore();
  }

 private:
  // Gets an image representing 3 bitmaps laid out horizontally that will be
  // used as the normal, hot and pushed states for the created button.
  views::ImageButton* CreateImageButton(int resource_id) {
    views::ImageButton* button = new views::ImageButton(this);
    const SkBitmap* all_images =
        ResourceBundle::GetSharedInstance().GetImageNamed(
            resource_id).ToSkBitmap();
    int width = all_images->width() / 3;
    int height = all_images->height();

    SkBitmap normal, hot, pushed;
    all_images->extractSubset(
        &normal,
        SkIRect::MakeXYWH(0, 0, width, height));
    all_images->extractSubset(
        &hot,
        SkIRect::MakeXYWH(width, 0, width, height));
    all_images->extractSubset(
        &pushed,
        SkIRect::MakeXYWH(2 * width, 0, width, height));
    button->SetImage(views::CustomButton::BS_NORMAL, &normal);
    button->SetImage(views::CustomButton::BS_HOT, &hot);
    button->SetImage(views::CustomButton::BS_PUSHED, &pushed);

    button->SizeToPreferredSize();
    return button;
  }

  AppNonClientFrameViewAura* owner_;
  views::ImageButton* close_button_;
  views::ImageButton* restore_button_;
  SkBitmap separator_;
  SkBitmap shadow_;

  DISALLOW_COPY_AND_ASSIGN(ControlView);
};

class AppNonClientFrameViewAura::Host : public views::MouseWatcherHost {
 public:
  explicit Host(AppNonClientFrameViewAura* owner) : owner_(owner) {}
  virtual ~Host() {}

  virtual bool Contains(
      const gfx::Point& screen_point,
      views::MouseWatcherHost::MouseEventType type) {
    gfx::Rect top_margin = owner_->GetScreenBounds();
    top_margin.set_height(kTopMargin);
    gfx::Rect control_bounds = owner_->GetControlBounds();
    control_bounds.Inset(kShadowStart, 0, 0, kShadowStart);
    return top_margin.Contains(screen_point) ||
        control_bounds.Contains(screen_point);
  }

  AppNonClientFrameViewAura* owner_;

  DISALLOW_COPY_AND_ASSIGN(Host);
};

AppNonClientFrameViewAura::AppNonClientFrameViewAura(
    BrowserFrame* frame, BrowserView* browser_view)
    : BrowserNonClientFrameView(frame, browser_view),
      control_view_(new ControlView(this)),
      control_widget_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          mouse_watcher_(new Host(this), this)) {
  set_background(views::Background::CreateSolidBackground(SK_ColorBLACK));
}

AppNonClientFrameViewAura::~AppNonClientFrameViewAura() {
}

gfx::Rect AppNonClientFrameViewAura::GetBoundsForClientView() const {
  gfx::Rect bounds = GetLocalBounds();
  bounds.Inset(0, kTopMargin, 0,  0);
  return bounds;
}

gfx::Rect AppNonClientFrameViewAura::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  gfx::Rect bounds = client_bounds;
  bounds.Inset(0, -kTopMargin, 0, 0);
  return bounds;
}

int AppNonClientFrameViewAura::NonClientHitTest(
    const gfx::Point& point) {
  return bounds().Contains(point) ? HTCLIENT : HTNOWHERE;
}

void AppNonClientFrameViewAura::GetWindowMask(const gfx::Size& size,
                                              gfx::Path* window_mask) {
}

void AppNonClientFrameViewAura::ResetWindowControls() {
}

void AppNonClientFrameViewAura::UpdateWindowIcon() {
}

gfx::Rect AppNonClientFrameViewAura::GetBoundsForTabStrip(
    views::View* tabstrip) const {
  return gfx::Rect();
}

int AppNonClientFrameViewAura::GetHorizontalTabStripVerticalOffset(
    bool restored) const {
  return 0;
}

void AppNonClientFrameViewAura::UpdateThrobber(bool running) {
}

void AppNonClientFrameViewAura::OnMouseEntered(
    const views::MouseEvent& event) {
  if (!control_widget_) {
    control_widget_ = new views::Widget;
    views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
    params.parent = browser_view()->GetNativeHandle();
    params.transparent = true;
    control_widget_->Init(params);
    control_widget_->SetContentsView(control_view_);
    aura::Window* window = control_widget_->GetNativeView();
    gfx::Rect control_bounds = GetControlBounds();
    control_bounds.set_y(control_bounds.y() - control_bounds.height());
    window->SetBounds(control_bounds);
    control_widget_->Show();
  }

  ui::Layer* layer = control_widget_->GetNativeView()->layer();
  ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator());
  scoped_setter.SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kHoverFadeDurationMs));
  layer->SetBounds(GetControlBounds());
  layer->SetOpacity(1);

  mouse_watcher_.Start();
}

void AppNonClientFrameViewAura::MouseMovedOutOfHost() {
  ui::Layer* layer = control_widget_->GetNativeView()->layer();

  ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator());
  scoped_setter.SetTransitionDuration(
      base::TimeDelta::FromMilliseconds(kHoverFadeDurationMs));
  gfx::Rect control_bounds = GetControlBounds();
  control_bounds.set_y(control_bounds.y() - control_bounds.height());
  layer->SetBounds(control_bounds);
  layer->SetOpacity(0);
}

gfx::Rect AppNonClientFrameViewAura::GetControlBounds() const {
  gfx::Size preferred = control_view_->GetPreferredSize();
  gfx::Point location(width() - preferred.width(), 0);
  ConvertPointToWidget(this, &location);
  return gfx::Rect(
      location.x(), location.y(),
      preferred.width(), preferred.height());
}

void AppNonClientFrameViewAura::Close() {
  if (control_widget_)
    control_widget_->Close();
  control_widget_ = NULL;
  mouse_watcher_.Stop();
  frame()->Close();
}

void AppNonClientFrameViewAura::Restore() {
  if (control_widget_)
    control_widget_->Close();
  control_widget_ = NULL;
  mouse_watcher_.Stop();
  frame()->Restore();
}
<|endoftext|>


<commit_before>
#include <cmath>

#include <gtest/gtest.h>

#include "drake/systems/plants/constraint/dynamic_constraint.h"
#include "drake/util/eigen_matrix_compare.h"

using drake::util::MatrixCompareType;

namespace drake {
namespace systems {
namespace {

class PendulumTestDynamicConstraint : public DynamicConstraint {
 public:
  PendulumTestDynamicConstraint(int num_states, int num_inputs)
      : DynamicConstraint(num_states, num_inputs) {}

 protected:
  void dynamics(const Drake::TaylorVecXd& state,
                const Drake::TaylorVecXd& input,
                Drake::TaylorVecXd* xdot) const override {
    // From the Pendulum example:
    const double m = 1.0;
    const double b = 0.1;
    const double lc = .5;
    const double I = 0.25;
    const double g = 9.81;

    ASSERT_EQ(state.size(), 2);
    ASSERT_EQ(input.size(), 1);
    xdot->resize(2);
    (*xdot)(0) = state(1);
    (*xdot)(1) = (input(0) - m * g * lc * sin(state(0)) - b * state(1)) / I;
  }
};

GTEST_TEST(DynamicConstraintPendulumDynamicsTest, DynamicConstraintTest) {
  const int kNumStates = 2;
  const int kNumInputs = 1;

  Eigen::VectorXd x(1 + 2 * kNumStates + 2 * kNumInputs);
  x(0) = 0.2;          // h
  x(1) = 0;            // x0(0)
  x(2) = 0;            // x0(1)
  x(3) = 0.05 * M_PI;  // x1(0)
  x(4) = 0;            // x1(1)
  x(5) = 0.00537668;   // u0
  x(6) = 0.018339;     // u1

  PendulumTestDynamicConstraint dut(kNumStates, kNumInputs);

  Drake::TaylorVecXd result;
  dut.eval(Drake::initializeAutoDiff(x), result);

  // Expected values came from running the MATLAB code for
  // PendulumPlant through the constraint function in
  // DircolTrajectoryOptimization.m and printing the results.
  EXPECT_NEAR(result(0).value(), 1.1027, 1e-4);
  EXPECT_NEAR(result(1).value(), 2.2657, 1e-4);

  Eigen::VectorXd d_0_expected(x.size());
  d_0_expected << -6.26766, -7.0095, -0.74, 7.015539, -0.76, -0.1, 0.1;
  Eigen::VectorXd d_1_expected(x.size());
  d_1_expected << 0.1508698, 14.488559, -6.715012, 14.818155,
      7.315012, -2.96, -3.04;
  EXPECT_TRUE(CompareMatrices(result(0).derivatives(), d_0_expected, 1e-4,
                              MatrixCompareType::absolute));
  EXPECT_TRUE(CompareMatrices(result(1).derivatives(), d_1_expected, 1e-4,
                              MatrixCompareType::absolute));
}

}  // anonymous namespace
}  // namespace systems
}  // namespace drake
<commit_msg>Clarify a comment<commit_after>
#include <cmath>

#include <gtest/gtest.h>

#include "drake/systems/plants/constraint/dynamic_constraint.h"
#include "drake/util/eigen_matrix_compare.h"

using drake::util::MatrixCompareType;

namespace drake {
namespace systems {
namespace {

class PendulumTestDynamicConstraint : public DynamicConstraint {
 public:
  PendulumTestDynamicConstraint(int num_states, int num_inputs)
      : DynamicConstraint(num_states, num_inputs) {}

 protected:
  void dynamics(const Drake::TaylorVecXd& state,
                const Drake::TaylorVecXd& input,
                Drake::TaylorVecXd* xdot) const override {
    // From the Pendulum example:
    const double m = 1.0;
    const double b = 0.1;
    const double lc = .5;
    const double I = 0.25;
    const double g = 9.81;

    ASSERT_EQ(state.size(), 2);
    ASSERT_EQ(input.size(), 1);
    xdot->resize(2);
    (*xdot)(0) = state(1);
    (*xdot)(1) = (input(0) - m * g * lc * sin(state(0)) - b * state(1)) / I;
  }
};

GTEST_TEST(DynamicConstraintPendulumDynamicsTest, DynamicConstraintTest) {
  const int kNumStates = 2;
  const int kNumInputs = 1;

  // Initial state/input and expected result values came from running
  // the MATLAB code for PendulumPlant through the constraint function
  // in DircolTrajectoryOptimization.m and printing the results.
  Eigen::VectorXd x(1 + 2 * kNumStates + 2 * kNumInputs);
  x(0) = 0.2;          // h
  x(1) = 0;            // x0(0)
  x(2) = 0;            // x0(1)
  x(3) = 0.05 * M_PI;  // x1(0)
  x(4) = 0;            // x1(1)
  x(5) = 0.00537668;   // u0
  x(6) = 0.018339;     // u1

  PendulumTestDynamicConstraint dut(kNumStates, kNumInputs);

  Drake::TaylorVecXd result;
  dut.eval(Drake::initializeAutoDiff(x), result);

  EXPECT_NEAR(result(0).value(), 1.1027, 1e-4);
  EXPECT_NEAR(result(1).value(), 2.2657, 1e-4);

  Eigen::VectorXd d_0_expected(x.size());
  d_0_expected << -6.26766, -7.0095, -0.74, 7.015539, -0.76, -0.1, 0.1;
  Eigen::VectorXd d_1_expected(x.size());
  d_1_expected << 0.1508698, 14.488559, -6.715012, 14.818155,
      7.315012, -2.96, -3.04;
  EXPECT_TRUE(CompareMatrices(result(0).derivatives(), d_0_expected, 1e-4,
                              MatrixCompareType::absolute));
  EXPECT_TRUE(CompareMatrices(result(1).derivatives(), d_1_expected, 1e-4,
                              MatrixCompareType::absolute));
}

}  // anonymous namespace
}  // namespace systems
}  // namespace drake
<|endoftext|>