<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   EC_Movable.cpp
 *  @brief  Contains Entity Actions for moving entity with this component in scene.
 */

#include "StableHeaders.h"
#include "EC_Movable.h"

#include "NetworkEvents.h"
#include "WorldStream.h"
#include "Entity.h"
#include "EC_OpenSimPrim.h"
#include "EC_OgrePlaceable.h"
#include "LoggingFunctions.h"

DEFINE_POCO_LOGGING_FUNCTIONS("EC_Movable")

EC_Movable::~EC_Movable()
{
}

void EC_Movable::SetWorldStreamPtr(ProtocolUtilities::WorldStreamPtr worldStream)
{
    worldStream_ = worldStream;
}

void EC_Movable::Move(const QString &direction)
{
    Vector3df change, orientation;
    if (direction == "Forward")
        change.x += 1;
    else if (direction == "Backward")
        change.x -= 1;
    else if (direction == "Left")
        change.y -= 1;
    else if (direction == "Right")
        change.y += 1;
    else
    {
        LogWarning("Invalid direction for Move action: " + direction.toStdString());
        return;
    }

    SendMultipleObjectUpdatePacket(change, Quaternion());
}

void EC_Movable::Rotate(const QString &direction)
{
    Quaternion orientation;
    if (direction == "Left")
        orientation;
    else if (direction == "Right")
        orientation;
    else
    {
        LogWarning("Invalid direction for Rotate action: " + direction.toStdString());
        return;
    }

    SendMultipleObjectUpdatePacket(Vector3df(), orientation);
}

EC_Movable::EC_Movable(Foundation::ModuleInterface *module):
    Foundation::ComponentInterface(module->GetFramework())
{
    connect(this, SIGNAL(ParentEntitySet()), SLOT(RegisterActions()));
}

void EC_Movable::SendMultipleObjectUpdatePacket(const Vector3df &deltaPos, const Quaternion &deltaOri)
{
    Scene::Entity *entity = GetParentEntity();
    if (worldStream_ && entity)
    {
        std::vector<ProtocolUtilities::MultiObjectUpdateInfo> updates;
        EC_OpenSimPrim *prim = entity->GetComponent<EC_OpenSimPrim>().get();
        OgreRenderer::EC_OgrePlaceable *ogre_pos = entity->GetComponent<OgreRenderer::EC_OgrePlaceable >().get();
        if (!prim && !ogre_pos)
            return;

        ProtocolUtilities::MultiObjectUpdateInfo update;
        update.local_id_ = prim->LocalId;
        update.position_ = ogre_pos->GetPosition() + deltaPos;
        update.orientation_ = ogre_pos->GetOrientation() + deltaOri;
        update.scale_ = ogre_pos->GetScale();
        updates.push_back(update);

        worldStream_->SendMultipleObjectUpdatePacket(updates);
    }
}

void EC_Movable::RegisterActions()
{
    Scene::Entity *entity = GetParentEntity();
    assert(entity);
    if (entity)
    {
        entity->ConnectAction("Move", this, SLOT(Move(const QString &)));
        entity->ConnectAction("Rotate", this, SLOT(Rotate(const QString &)));
    }
}

<commit_msg>Simple hard-coded 90 degree rotate values to left and right for EC_Movable. Attach EC_InputMapper to entity and use U and O to rotate.<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   EC_Movable.cpp
 *  @brief  Contains Entity Actions for moving entity with this component in scene.
 */

#include "StableHeaders.h"
#include "EC_Movable.h"

#include "NetworkEvents.h"
#include "WorldStream.h"
#include "Entity.h"
#include "EC_OpenSimPrim.h"
#include "EC_OgrePlaceable.h"
#include "LoggingFunctions.h"

DEFINE_POCO_LOGGING_FUNCTIONS("EC_Movable")

EC_Movable::~EC_Movable()
{
}

void EC_Movable::SetWorldStreamPtr(ProtocolUtilities::WorldStreamPtr worldStream)
{
    worldStream_ = worldStream;
}

void EC_Movable::Move(const QString &direction)
{
    Vector3df change, orientation;
    if (direction == "Forward")
        change.x += 1;
    else if (direction == "Backward")
        change.x -= 1;
    else if (direction == "Left")
        change.y -= 1;
    else if (direction == "Right")
        change.y += 1;
    else
    {
        LogWarning("Invalid direction for Move action: " + direction.toStdString());
        return;
    }

    SendMultipleObjectUpdatePacket(change, Quaternion());
}

void EC_Movable::Rotate(const QString &direction)
{
    Quaternion orientation;
    if (direction == "Left")
    {
        orientation.z = 0.7071f;
        orientation.w = 0.7071f;
    }
    else if (direction == "Right")
    {
        orientation.z = -0.7071f;
        orientation.w = 0.7071f;
    }
    else
    {
        LogWarning("Invalid direction for Rotate action: " + direction.toStdString());
        return;
    }

    SendMultipleObjectUpdatePacket(Vector3df(), orientation);
}

EC_Movable::EC_Movable(Foundation::ModuleInterface *module):
    Foundation::ComponentInterface(module->GetFramework())
{
    connect(this, SIGNAL(ParentEntitySet()), SLOT(RegisterActions()));
}

void EC_Movable::SendMultipleObjectUpdatePacket(const Vector3df &deltaPos, const Quaternion &deltaOri)
{
    Scene::Entity *entity = GetParentEntity();
    if (worldStream_ && entity)
    {
        std::vector<ProtocolUtilities::MultiObjectUpdateInfo> updates;
        EC_OpenSimPrim *prim = entity->GetComponent<EC_OpenSimPrim>().get();
        OgreRenderer::EC_OgrePlaceable *ogre_pos = entity->GetComponent<OgreRenderer::EC_OgrePlaceable >().get();
        if (!prim && !ogre_pos)
            return;

        ProtocolUtilities::MultiObjectUpdateInfo update;
        update.local_id_ = prim->LocalId;
        update.position_ = ogre_pos->GetPosition() + deltaPos;
        update.orientation_ = ogre_pos->GetOrientation() * deltaOri;
        update.scale_ = ogre_pos->GetScale();
        updates.push_back(update);

        worldStream_->SendMultipleObjectUpdatePacket(updates);
    }
}

void EC_Movable::RegisterActions()
{
    Scene::Entity *entity = GetParentEntity();
    assert(entity);
    if (entity)
    {
        entity->ConnectAction("Move", this, SLOT(Move(const QString &)));
        entity->ConnectAction("Rotate", this, SLOT(Rotate(const QString &)));
    }
}

<|endoftext|>


<commit_before>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2013-2017 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

// UnitTest include.
#include <UnitTest/unit_test.hpp>

// Args include.
#include <Args/all.hpp>

using namespace Args;

#ifdef ARGS_WSTRING_BUILD
	using CHAR = String::value_type;
#else
	using CHAR = char;
#endif

TEST( ArgExceptions, TestNoValueForArg )
{
	const int argc = 2;
	const CHAR * argv[ argc ] = { SL( "program.exe" ),
		SL( "-a" ) };

	CmdLine cmd;

	cmd.addArgWithFlagOnly( SL( 'a' ), true );

	try {
		cmd.parse( argc, argv );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Argument \"-a\" requires value that wasn't presented." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestRequiredArgInAllOfGroup )
{
	const int argc = 2;
	const CHAR * argv[ argc ] = { SL( "program.exe" ),
		SL( "-a" ) };

	CmdLine cmd;

	cmd.addAllOfGroup( SL( "group" ) )
			.addArgWithFlagOnly( SL( 'a' ), true, true )
		.end();

	try {
		cmd.parse( argc, argv );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Required argument \"-a\" is not allowed to be in "
				"AllOf group \"group\"." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestAlreadyInCmdLine1 )
{
	CmdLine cmd;

	try {
		auto a1 = CmdLine::ArgPtr( new Arg( Char( SL( 'a' ) ), true, true ),
			details::Deleter< ArgIface >( true ) );
		auto a2 = CmdLine::ArgPtr( a1.get(),
			details::Deleter< ArgIface >( false ) );

		cmd.addArg( std::move( a1 ) );
		cmd.addArg( std::move( a2 ) );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Argument \"-a\" already in the command line parser." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestAlreadyInCmdLine2 )
{
	CmdLine cmd;

	try {
		Arg a1( Char( SL( 'a' ) ), true, true );

		cmd.addArg( &a1 );
		cmd.addArg( &a1 );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Argument \"-a\" already in the command line parser." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestAddingNull )
{
	CmdLine cmd;

	try {
		cmd.addArg( nullptr );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Attempt to add nullptr to the "
				"command line as argument." ) )

		return;
	}

	CHECK_CONDITION( false )
}

int main()
{
	RUN_ALL_TESTS()

	return 0;
}
<commit_msg>Testing.<commit_after>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2013-2017 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

// UnitTest include.
#include <UnitTest/unit_test.hpp>

// Args include.
#include <Args/all.hpp>

using namespace Args;

#ifdef ARGS_WSTRING_BUILD
	using CHAR = String::value_type;
#else
	using CHAR = char;
#endif

TEST( ArgExceptions, TestNoValueForArg )
{
	const int argc = 2;
	const CHAR * argv[ argc ] = { SL( "program.exe" ),
		SL( "-a" ) };

	CmdLine cmd;

	cmd.addArgWithFlagOnly( SL( 'a' ), true );

	try {
		cmd.parse( argc, argv );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Argument \"-a\" requires value that wasn't presented." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestRequiredArgInAllOfGroup )
{
	const int argc = 2;
	const CHAR * argv[ argc ] = { SL( "program.exe" ),
		SL( "-a" ) };

	CmdLine cmd;

	cmd.addAllOfGroup( SL( "group" ) )
			.addArgWithFlagOnly( SL( 'a' ), true, true )
		.end();

	try {
		cmd.parse( argc, argv );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Required argument \"-a\" is not allowed to be in "
				"AllOf group \"group\"." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestAlreadyInCmdLine1 )
{
	CmdLine cmd;

	try {
		auto a1 = CmdLine::ArgPtr( new Arg( Char( SL( 'a' ) ), true, true ),
			details::Deleter< ArgIface >( true ) );
		auto a2 = CmdLine::ArgPtr( a1.get(),
			details::Deleter< ArgIface >( false ) );

		cmd.addArg( std::move( a1 ) );
		cmd.addArg( std::move( a2 ) );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Argument \"-a\" already in the command line parser." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestAlreadyInCmdLine2 )
{
	CmdLine cmd;

	try {
		Arg a1( Char( SL( 'a' ) ), true, true );

		cmd.addArg( &a1 );
		cmd.addArg( &a1 );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Argument \"-a\" already in the command line parser." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestAddingNull )
{
	CmdLine cmd;

	try {
		cmd.addArg( nullptr );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Attempt to add nullptr to the "
				"command line as argument." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestEmptyNameOfArgAsCommand )
{
	try {
		CmdLine cmd;

		ArgAsCommand a( SL( "" ) );

		cmd.addArg( a );
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "ArgAsCommand can't be with empty name." ) )

		return;
	}

	CHECK_CONDITION( false )
}

TEST( ArgExceptions, TestDissallowedNameOfArgAsCommand )
{
	try {
		CmdLine cmd;

		ArgAsCommand a( SL( "arg with space" ) );

		cmd.addArg( a );

		cmd.parse();
	}
	catch( const BaseException & x )
	{
		CHECK_CONDITION( x.desc() ==
			SL( "Disallowed name \"arg with space\" for the argument." ) )

		return;
	}

	CHECK_CONDITION( false )
}

int main()
{
	RUN_ALL_TESTS()

	return 0;
}
<|endoftext|>


<commit_before>//----------------------------  get_fe_from_name.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2005 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  get_fe_from_name.cc  ---------------------------
// Test the get_fe_from_name function of the fe_tools.

#include "../tests.h"
#include <fstream>
#include <base/logstream.h>
#include <fe/fe.h>
#include <fe/fe_tools.h>

int main ()
{
  std::ofstream logfile("get_fe_from_name.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  FiniteElement<1> * fe1;
  FiniteElement<2> * fe2;
  FiniteElement<3> * fe3;

  std::string name;
  name = "FE_Q(1)";
  fe1 = FETools::get_fe_from_name(name);
  fe2 = FETools::get_fe_from_name(name);
  fe3 = FETools::get_fe_from_name(name);

  deallog << "Read " << name << std::endl;
  deallog << "Generated :" << std::endl;
  deallog << fe1->get_name()  << std::endl;
  deallog << fe2->get_name()  << std::endl;
  deallog << fe3->get_name()  << std::endl;

  delete fe1;
  delete fe2;
  delete fe3;

  return 0;
}

<commit_msg>One has to specify the template argument for get_fe_from_name.<commit_after>//----------------------------  get_fe_from_name.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2005 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  get_fe_from_name.cc  ---------------------------
// Test the get_fe_from_name function of the fe_tools.

#include "../tests.h"
#include <fstream>
#include <base/logstream.h>
#include <fe/fe.h>
#include <fe/fe_tools.h>

int main ()
{
  std::ofstream logfile("get_fe_from_name.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  FiniteElement<1> * fe1;
  FiniteElement<2> * fe2;
  FiniteElement<3> * fe3;

  std::string name;
  name = "FE_Q(1)";
  fe1 = FETools::get_fe_from_name<1>(name);
  fe2 = FETools::get_fe_from_name<2>(name);
  fe3 = FETools::get_fe_from_name<3>(name);

  deallog << "Read " << name << std::endl;
  deallog << "Generated :" << std::endl;
  deallog << fe1->get_name()  << std::endl;
  deallog << fe2->get_name()  << std::endl;
  deallog << fe3->get_name()  << std::endl;

  delete fe1;
  delete fe2;
  delete fe3;

  return 0;
}

<|endoftext|>


<commit_before><commit_msg>Fix interactive_ui_tests failures by temporarily allowing direct dns lookup.<commit_after><|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/browser/oom_priority_manager.h"

#include <algorithm>
#include <vector>

#include "base/process.h"
#include "base/process_util.h"
#include "base/string_number_conversions.h"
#include "base/string16.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/timer.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/chrome_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/zygote_host_linux.h"
#include "content/common/content_notification_types.h"
#include "content/common/notification_service.h"

#if !defined(OS_CHROMEOS)
#error This file only meant to be compiled on ChromeOS
#endif

using base::TimeDelta;
using base::TimeTicks;
using base::ProcessHandle;
using base::ProcessMetrics;

namespace {

// Returns a unique ID for a TabContents.  Do not cast back to a pointer, as
// the TabContents could be deleted if the user closed the tab.
int64 IdFromTabContents(TabContents* tab_contents) {
  return reinterpret_cast<int64>(tab_contents);
}

// Discards a tab with the given unique ID.  Returns true if discard occurred.
bool DiscardTabById(int64 target_tab_contents_id) {
  for (BrowserList::const_iterator browser_iterator = BrowserList::begin();
       browser_iterator != BrowserList::end(); ++browser_iterator) {
    Browser* browser = *browser_iterator;
    TabStripModel* model = browser->tabstrip_model();
    for (int idx = 0; idx < model->count(); idx++) {
      // Can't discard tabs that are already discarded.
      if (model->IsTabDiscarded(idx))
        continue;
      TabContents* tab_contents = model->GetTabContentsAt(idx)->tab_contents();
      int64 tab_contents_id = IdFromTabContents(tab_contents);
      if (tab_contents_id == target_tab_contents_id) {
        model->DiscardTabContentsAt(idx);
        return true;
      }
    }
  }
  return false;
}

}  // namespace

namespace browser {

// The default interval in seconds after which to adjust the oom_score_adj
// value.
#define ADJUSTMENT_INTERVAL_SECONDS 10

// The default interval in milliseconds to wait before setting the score of
// currently focused tab.
#define FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS 500

OomPriorityManager::TabStats::TabStats()
  : is_pinned(false),
    is_selected(false),
    renderer_handle(0),
    tab_contents_id(0) {
}

OomPriorityManager::TabStats::~TabStats() {
}

OomPriorityManager::OomPriorityManager()
  : focused_tab_pid_(0) {
  registrar_.Add(this,
      content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
      NotificationService::AllSources());
  registrar_.Add(this,
      content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
      NotificationService::AllSources());
  registrar_.Add(this,
      content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
      NotificationService::AllSources());
}

OomPriorityManager::~OomPriorityManager() {
  Stop();
}

void OomPriorityManager::Start() {
  if (!timer_.IsRunning()) {
    timer_.Start(FROM_HERE,
                 TimeDelta::FromSeconds(ADJUSTMENT_INTERVAL_SECONDS),
                 this,
                 &OomPriorityManager::AdjustOomPriorities);
  }
}

void OomPriorityManager::Stop() {
  timer_.Stop();
}

std::vector<string16> OomPriorityManager::GetTabTitles() {
  TabStatsList stats = GetTabStatsOnUIThread();
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
  std::vector<string16> titles;
  titles.reserve(stats.size());
  TabStatsList::iterator it = stats.begin();
  for ( ; it != stats.end(); ++it) {
    string16 str = it->title;
    str += ASCIIToUTF16(" (");
    int score = pid_to_oom_score_[it->renderer_handle];
    str += base::IntToString16(score);
    str += ASCIIToUTF16(")");
    titles.push_back(str);
  }
  return titles;
}

// TODO(jamescook): This should consider tabs with references to other tabs,
// such as tabs created with JavaScript window.open().  We might want to
// discard the entire set together, or use that in the priority computation.
bool OomPriorityManager::DiscardTab() {
  TabStatsList stats = GetTabStatsOnUIThread();
  if (stats.empty())
    return false;
  // Loop until we find a non-discarded tab to kill.
  for (TabStatsList::const_reverse_iterator stats_rit = stats.rbegin();
       stats_rit != stats.rend();
       ++stats_rit) {
    int64 least_important_tab_id = stats_rit->tab_contents_id;
    if (DiscardTabById(least_important_tab_id))
      return true;
  }
  return false;
}

// Returns true if |first| is considered less desirable to be killed
// than |second|.
bool OomPriorityManager::CompareTabStats(TabStats first,
                                         TabStats second) {
  // Being currently selected is most important.
  if (first.is_selected != second.is_selected)
    return first.is_selected == true;

  // Being pinned is second most important.
  if (first.is_pinned != second.is_pinned)
    return first.is_pinned == true;

  // Being more recently selected is more important.
  return first.last_selected > second.last_selected;
}

void OomPriorityManager::AdjustFocusedTabScoreOnFileThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
  ZygoteHost::GetInstance()->AdjustRendererOOMScore(
      focused_tab_pid_, chrome::kLowestRendererOomScore);
  pid_to_oom_score_[focused_tab_pid_] = chrome::kLowestRendererOomScore;
}

void OomPriorityManager::OnFocusTabScoreAdjustmentTimeout() {
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(
          this, &OomPriorityManager::AdjustFocusedTabScoreOnFileThread));
}

void OomPriorityManager::Observe(int type, const NotificationSource& source,
                                 const NotificationDetails& details) {
  base::ProcessHandle handle = 0;
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
  switch (type) {
    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
    case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
      handle = Source<RenderProcessHost>(source)->GetHandle();
      pid_to_oom_score_.erase(handle);
      break;
    }
    case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: {
      bool visible = *Details<bool>(details).ptr();
      if (visible) {
        focused_tab_pid_ =
            Source<RenderWidgetHost>(source).ptr()->process()->GetHandle();

        // If the currently focused tab already has a lower score, do not
        // set it. This can happen in case the newly focused tab is script
        // connected to the previous tab.
        ProcessScoreMap::iterator it;
        it = pid_to_oom_score_.find(focused_tab_pid_);
        if (it == pid_to_oom_score_.end()
            || it->second != chrome::kLowestRendererOomScore) {
          // By starting a timer we guarantee that the tab is focused for
          // certain amount of time. Secondly, it also does not add overhead
          // to the tab switching time.
          if (focus_tab_score_adjust_timer_.IsRunning())
            focus_tab_score_adjust_timer_.Reset();
          else
            focus_tab_score_adjust_timer_.Start(FROM_HERE,
              TimeDelta::FromMilliseconds(FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS),
              this, &OomPriorityManager::OnFocusTabScoreAdjustmentTimeout);
        }
      }
      break;
    }
    default:
      NOTREACHED() << L"Received unexpected notification";
      break;
  }
}

// Here we collect most of the information we need to sort the
// existing renderers in priority order, and hand out oom_score_adj
// scores based on that sort order.
//
// Things we need to collect on the browser thread (because
// TabStripModel isn't thread safe):
// 1) whether or not a tab is pinned
// 2) last time a tab was selected
// 3) is the tab currently selected
void OomPriorityManager::AdjustOomPriorities() {
  if (BrowserList::size() == 0)
    return;
  TabStatsList stats_list = GetTabStatsOnUIThread();
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this,
                        &OomPriorityManager::AdjustOomPrioritiesOnFileThread,
                        stats_list));
}

OomPriorityManager::TabStatsList OomPriorityManager::GetTabStatsOnUIThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TabStatsList stats_list;
  stats_list.reserve(32);  // 99% of users have < 30 tabs open
  for (BrowserList::const_iterator browser_iterator = BrowserList::begin();
       browser_iterator != BrowserList::end(); ++browser_iterator) {
    Browser* browser = *browser_iterator;
    const TabStripModel* model = browser->tabstrip_model();
    for (int i = 0; i < model->count(); i++) {
      TabContents* contents = model->GetTabContentsAt(i)->tab_contents();
      if (!contents->is_crashed()) {
        TabStats stats;
        stats.last_selected = contents->last_selected_time();
        stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle();
        stats.is_pinned = model->IsTabPinned(i);
        stats.is_selected = model->IsTabSelected(i);
        stats.title = contents->GetTitle();
        stats.tab_contents_id = IdFromTabContents(contents);
        stats_list.push_back(stats);
      }
    }
  }
  // Sort the data we collected so that least desirable to be
  // killed is first, most desirable is last.
  std::sort(stats_list.begin(), stats_list.end(), CompareTabStats);
  return stats_list;
}

void OomPriorityManager::AdjustOomPrioritiesOnFileThread(
    TabStatsList stats_list) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);

  // Now we assign priorities based on the sorted list.  We're
  // assigning priorities in the range of kLowestRendererOomScore to
  // kHighestRendererOomScore (defined in chrome_constants.h).
  // oom_score_adj takes values from -1000 to 1000.  Negative values
  // are reserved for system processes, and we want to give some room
  // below the range we're using to allow for things that want to be
  // above the renderers in priority, so the defined range gives us
  // some variation in priority without taking up the whole range.  In
  // the end, however, it's a pretty arbitrary range to use.  Higher
  // values are more likely to be killed by the OOM killer.
  //
  // We also remove any duplicate PIDs, leaving the most important
  // (least likely to be killed) of the duplicates, so that a
  // particular renderer process takes on the oom_score_adj of the
  // least likely tab to be killed.
  const int kPriorityRange = chrome::kHighestRendererOomScore -
                             chrome::kLowestRendererOomScore;
  float priority_increment =
      static_cast<float>(kPriorityRange) / stats_list.size();
  float priority = chrome::kLowestRendererOomScore;
  std::set<base::ProcessHandle> already_seen;
  int score = 0;
  ProcessScoreMap::iterator it;
  for (TabStatsList::iterator iterator = stats_list.begin();
       iterator != stats_list.end(); ++iterator) {
    if (already_seen.find(iterator->renderer_handle) == already_seen.end()) {
      already_seen.insert(iterator->renderer_handle);
      // If a process has the same score as the newly calculated value,
      // do not set it.
      score = static_cast<int>(priority + 0.5f);
      it = pid_to_oom_score_.find(iterator->renderer_handle);
      if (it == pid_to_oom_score_.end() || it->second != score) {
        ZygoteHost::GetInstance()->AdjustRendererOOMScore(
            iterator->renderer_handle, score);
        pid_to_oom_score_[iterator->renderer_handle] = score;
      }
      priority += priority_increment;
    }
  }
}

}  // namespace browser
<commit_msg>Change usage of AllSources to AllBrowserContextsAndSources to indicate that usage is safe for multiprofiles. <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/browser/oom_priority_manager.h"

#include <algorithm>
#include <vector>

#include "base/process.h"
#include "base/process_util.h"
#include "base/string_number_conversions.h"
#include "base/string16.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "base/timer.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/chrome_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/zygote_host_linux.h"
#include "content/common/content_notification_types.h"
#include "content/common/notification_service.h"

#if !defined(OS_CHROMEOS)
#error This file only meant to be compiled on ChromeOS
#endif

using base::TimeDelta;
using base::TimeTicks;
using base::ProcessHandle;
using base::ProcessMetrics;

namespace {

// Returns a unique ID for a TabContents.  Do not cast back to a pointer, as
// the TabContents could be deleted if the user closed the tab.
int64 IdFromTabContents(TabContents* tab_contents) {
  return reinterpret_cast<int64>(tab_contents);
}

// Discards a tab with the given unique ID.  Returns true if discard occurred.
bool DiscardTabById(int64 target_tab_contents_id) {
  for (BrowserList::const_iterator browser_iterator = BrowserList::begin();
       browser_iterator != BrowserList::end(); ++browser_iterator) {
    Browser* browser = *browser_iterator;
    TabStripModel* model = browser->tabstrip_model();
    for (int idx = 0; idx < model->count(); idx++) {
      // Can't discard tabs that are already discarded.
      if (model->IsTabDiscarded(idx))
        continue;
      TabContents* tab_contents = model->GetTabContentsAt(idx)->tab_contents();
      int64 tab_contents_id = IdFromTabContents(tab_contents);
      if (tab_contents_id == target_tab_contents_id) {
        model->DiscardTabContentsAt(idx);
        return true;
      }
    }
  }
  return false;
}

}  // namespace

namespace browser {

// The default interval in seconds after which to adjust the oom_score_adj
// value.
#define ADJUSTMENT_INTERVAL_SECONDS 10

// The default interval in milliseconds to wait before setting the score of
// currently focused tab.
#define FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS 500

OomPriorityManager::TabStats::TabStats()
  : is_pinned(false),
    is_selected(false),
    renderer_handle(0),
    tab_contents_id(0) {
}

OomPriorityManager::TabStats::~TabStats() {
}

OomPriorityManager::OomPriorityManager()
  : focused_tab_pid_(0) {
  registrar_.Add(this,
      content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
      NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this,
      content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
      NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this,
      content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
      NotificationService::AllBrowserContextsAndSources());
}

OomPriorityManager::~OomPriorityManager() {
  Stop();
}

void OomPriorityManager::Start() {
  if (!timer_.IsRunning()) {
    timer_.Start(FROM_HERE,
                 TimeDelta::FromSeconds(ADJUSTMENT_INTERVAL_SECONDS),
                 this,
                 &OomPriorityManager::AdjustOomPriorities);
  }
}

void OomPriorityManager::Stop() {
  timer_.Stop();
}

std::vector<string16> OomPriorityManager::GetTabTitles() {
  TabStatsList stats = GetTabStatsOnUIThread();
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
  std::vector<string16> titles;
  titles.reserve(stats.size());
  TabStatsList::iterator it = stats.begin();
  for ( ; it != stats.end(); ++it) {
    string16 str = it->title;
    str += ASCIIToUTF16(" (");
    int score = pid_to_oom_score_[it->renderer_handle];
    str += base::IntToString16(score);
    str += ASCIIToUTF16(")");
    titles.push_back(str);
  }
  return titles;
}

// TODO(jamescook): This should consider tabs with references to other tabs,
// such as tabs created with JavaScript window.open().  We might want to
// discard the entire set together, or use that in the priority computation.
bool OomPriorityManager::DiscardTab() {
  TabStatsList stats = GetTabStatsOnUIThread();
  if (stats.empty())
    return false;
  // Loop until we find a non-discarded tab to kill.
  for (TabStatsList::const_reverse_iterator stats_rit = stats.rbegin();
       stats_rit != stats.rend();
       ++stats_rit) {
    int64 least_important_tab_id = stats_rit->tab_contents_id;
    if (DiscardTabById(least_important_tab_id))
      return true;
  }
  return false;
}

// Returns true if |first| is considered less desirable to be killed
// than |second|.
bool OomPriorityManager::CompareTabStats(TabStats first,
                                         TabStats second) {
  // Being currently selected is most important.
  if (first.is_selected != second.is_selected)
    return first.is_selected == true;

  // Being pinned is second most important.
  if (first.is_pinned != second.is_pinned)
    return first.is_pinned == true;

  // Being more recently selected is more important.
  return first.last_selected > second.last_selected;
}

void OomPriorityManager::AdjustFocusedTabScoreOnFileThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
  ZygoteHost::GetInstance()->AdjustRendererOOMScore(
      focused_tab_pid_, chrome::kLowestRendererOomScore);
  pid_to_oom_score_[focused_tab_pid_] = chrome::kLowestRendererOomScore;
}

void OomPriorityManager::OnFocusTabScoreAdjustmentTimeout() {
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(
          this, &OomPriorityManager::AdjustFocusedTabScoreOnFileThread));
}

void OomPriorityManager::Observe(int type, const NotificationSource& source,
                                 const NotificationDetails& details) {
  base::ProcessHandle handle = 0;
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
  switch (type) {
    case content::NOTIFICATION_RENDERER_PROCESS_CLOSED:
    case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
      handle = Source<RenderProcessHost>(source)->GetHandle();
      pid_to_oom_score_.erase(handle);
      break;
    }
    case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: {
      bool visible = *Details<bool>(details).ptr();
      if (visible) {
        focused_tab_pid_ =
            Source<RenderWidgetHost>(source).ptr()->process()->GetHandle();

        // If the currently focused tab already has a lower score, do not
        // set it. This can happen in case the newly focused tab is script
        // connected to the previous tab.
        ProcessScoreMap::iterator it;
        it = pid_to_oom_score_.find(focused_tab_pid_);
        if (it == pid_to_oom_score_.end()
            || it->second != chrome::kLowestRendererOomScore) {
          // By starting a timer we guarantee that the tab is focused for
          // certain amount of time. Secondly, it also does not add overhead
          // to the tab switching time.
          if (focus_tab_score_adjust_timer_.IsRunning())
            focus_tab_score_adjust_timer_.Reset();
          else
            focus_tab_score_adjust_timer_.Start(FROM_HERE,
              TimeDelta::FromMilliseconds(FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS),
              this, &OomPriorityManager::OnFocusTabScoreAdjustmentTimeout);
        }
      }
      break;
    }
    default:
      NOTREACHED() << L"Received unexpected notification";
      break;
  }
}

// Here we collect most of the information we need to sort the
// existing renderers in priority order, and hand out oom_score_adj
// scores based on that sort order.
//
// Things we need to collect on the browser thread (because
// TabStripModel isn't thread safe):
// 1) whether or not a tab is pinned
// 2) last time a tab was selected
// 3) is the tab currently selected
void OomPriorityManager::AdjustOomPriorities() {
  if (BrowserList::size() == 0)
    return;
  TabStatsList stats_list = GetTabStatsOnUIThread();
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this,
                        &OomPriorityManager::AdjustOomPrioritiesOnFileThread,
                        stats_list));
}

OomPriorityManager::TabStatsList OomPriorityManager::GetTabStatsOnUIThread() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  TabStatsList stats_list;
  stats_list.reserve(32);  // 99% of users have < 30 tabs open
  for (BrowserList::const_iterator browser_iterator = BrowserList::begin();
       browser_iterator != BrowserList::end(); ++browser_iterator) {
    Browser* browser = *browser_iterator;
    const TabStripModel* model = browser->tabstrip_model();
    for (int i = 0; i < model->count(); i++) {
      TabContents* contents = model->GetTabContentsAt(i)->tab_contents();
      if (!contents->is_crashed()) {
        TabStats stats;
        stats.last_selected = contents->last_selected_time();
        stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle();
        stats.is_pinned = model->IsTabPinned(i);
        stats.is_selected = model->IsTabSelected(i);
        stats.title = contents->GetTitle();
        stats.tab_contents_id = IdFromTabContents(contents);
        stats_list.push_back(stats);
      }
    }
  }
  // Sort the data we collected so that least desirable to be
  // killed is first, most desirable is last.
  std::sort(stats_list.begin(), stats_list.end(), CompareTabStats);
  return stats_list;
}

void OomPriorityManager::AdjustOomPrioritiesOnFileThread(
    TabStatsList stats_list) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
  base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);

  // Now we assign priorities based on the sorted list.  We're
  // assigning priorities in the range of kLowestRendererOomScore to
  // kHighestRendererOomScore (defined in chrome_constants.h).
  // oom_score_adj takes values from -1000 to 1000.  Negative values
  // are reserved for system processes, and we want to give some room
  // below the range we're using to allow for things that want to be
  // above the renderers in priority, so the defined range gives us
  // some variation in priority without taking up the whole range.  In
  // the end, however, it's a pretty arbitrary range to use.  Higher
  // values are more likely to be killed by the OOM killer.
  //
  // We also remove any duplicate PIDs, leaving the most important
  // (least likely to be killed) of the duplicates, so that a
  // particular renderer process takes on the oom_score_adj of the
  // least likely tab to be killed.
  const int kPriorityRange = chrome::kHighestRendererOomScore -
                             chrome::kLowestRendererOomScore;
  float priority_increment =
      static_cast<float>(kPriorityRange) / stats_list.size();
  float priority = chrome::kLowestRendererOomScore;
  std::set<base::ProcessHandle> already_seen;
  int score = 0;
  ProcessScoreMap::iterator it;
  for (TabStatsList::iterator iterator = stats_list.begin();
       iterator != stats_list.end(); ++iterator) {
    if (already_seen.find(iterator->renderer_handle) == already_seen.end()) {
      already_seen.insert(iterator->renderer_handle);
      // If a process has the same score as the newly calculated value,
      // do not set it.
      score = static_cast<int>(priority + 0.5f);
      it = pid_to_oom_score_.find(iterator->renderer_handle);
      if (it == pid_to_oom_score_.end() || it->second != score) {
        ZygoteHost::GetInstance()->AdjustRendererOOMScore(
            iterator->renderer_handle, score);
        pid_to_oom_score_[iterator->renderer_handle] = score;
      }
      priority += priority_increment;
    }
  }
}

}  // namespace browser
<|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/browser/spellcheck_host_impl.h"

#include <set>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/spellcheck_host_observer.h"
#include "chrome/browser/spellchecker_platform_engine.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "chrome/common/spellcheck_common.h"
#include "content/common/notification_service.h"
#include "googleurl/src/gurl.h"
#include "third_party/hunspell/google/bdict.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_MACOSX)
#include "base/metrics/histogram.h"
#endif

namespace {

FilePath GetFirstChoiceFilePath(const std::string& language) {
  FilePath dict_dir;
  {
    // This should not do blocking IO from the UI thread!
    // Temporarily allow it for now.
    //   http://code.google.com/p/chromium/issues/detail?id=60643
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
  }
  return SpellCheckCommon::GetVersionedFileName(language, dict_dir);
}

#if defined(OS_MACOSX)
// Collect metrics on how often Hunspell is used on OS X vs the native
// spellchecker.
void RecordSpellCheckStats(bool native_spellchecker_used,
                           const std::string& language) {
  static std::set<std::string> languages_seen;

  // Only count a language code once for each session..
  if (languages_seen.find(language) != languages_seen.end()) {
    return;
  }
  languages_seen.insert(language);

  enum {
    SPELLCHECK_OSX_NATIVE_SPELLCHECKER_USED = 0,
    SPELLCHECK_HUNSPELL_USED = 1
  };

  bool engine_used = native_spellchecker_used ?
                         SPELLCHECK_OSX_NATIVE_SPELLCHECKER_USED :
                         SPELLCHECK_HUNSPELL_USED;

  UMA_HISTOGRAM_COUNTS("SpellCheck.OSXEngineUsed", engine_used);
}
#endif

#if defined(OS_WIN)
FilePath GetFallbackFilePath(const FilePath& first_choice) {
  FilePath dict_dir;
  PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
  return dict_dir.Append(first_choice.BaseName());
}
#endif

}  // namespace

// Constructed on UI thread.
SpellCheckHostImpl::SpellCheckHostImpl(
    SpellCheckHostObserver* observer,
    const std::string& language,
    URLRequestContextGetter* request_context_getter)
    : observer_(observer),
      language_(language),
      file_(base::kInvalidPlatformFileValue),
      tried_to_download_(false),
      use_platform_spellchecker_(false),
      request_context_getter_(request_context_getter) {
  DCHECK(observer_);
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  FilePath personal_file_directory;
  PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
  custom_dictionary_file_ =
      personal_file_directory.Append(chrome::kCustomDictionaryFileName);

  bdict_file_path_ = GetFirstChoiceFilePath(language);
}

SpellCheckHostImpl::~SpellCheckHostImpl() {
  if (file_ != base::kInvalidPlatformFileValue)
    base::ClosePlatformFile(file_);
}

void SpellCheckHostImpl::Initialize() {
  if (SpellCheckerPlatform::SpellCheckerAvailable() &&
      SpellCheckerPlatform::PlatformSupportsLanguage(language_)) {
#if defined(OS_MACOSX)
    RecordSpellCheckStats(true, language_);
#endif
    use_platform_spellchecker_ = true;
    SpellCheckerPlatform::SetLanguage(language_);
    MessageLoop::current()->PostTask(FROM_HERE,
        NewRunnableMethod(this,
            &SpellCheckHostImpl::InformObserverOfInitialization));
    return;
  }

#if defined(OS_MACOSX)
  RecordSpellCheckStats(false, language_);
#endif

  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this,
                        &SpellCheckHostImpl::InitializeDictionaryLocation));
}

void SpellCheckHostImpl::UnsetObserver() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  observer_ = NULL;
  request_context_getter_ = NULL;
  fetcher_.reset();
}

void SpellCheckHostImpl::AddWord(const std::string& word) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  custom_words_.push_back(word);
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this,
          &SpellCheckHostImpl::WriteWordToCustomDictionary, word));
  NotificationService::current()->Notify(
      NotificationType::SPELLCHECK_WORD_ADDED,
      Source<SpellCheckHost>(this), NotificationService::NoDetails());
}

void SpellCheckHostImpl::InitializeDictionaryLocation() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

#if defined(OS_WIN)
  // Check if the dictionary exists in the fallback location. If so, use it
  // rather than downloading anew.
  FilePath fallback = GetFallbackFilePath(bdict_file_path_);
  if (!file_util::PathExists(bdict_file_path_) &&
      file_util::PathExists(fallback)) {
    bdict_file_path_ = fallback;
  }
#endif

  InitializeInternal();
}

void SpellCheckHostImpl::InitializeInternal() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  if (!observer_)
    return;

  file_ = base::CreatePlatformFile(
      bdict_file_path_,
      base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
      NULL, NULL);

  // File didn't exist. Download it.
  if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ &&
      request_context_getter_) {
    // We download from the ui thread because we need to know that
    // |request_context_getter_| is still valid before initiating the download.
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this, &SpellCheckHostImpl::DownloadDictionary));
    return;
  }

  request_context_getter_ = NULL;

  if (file_ != base::kInvalidPlatformFileValue) {
    // Load custom dictionary.
    std::string contents;
    file_util::ReadFileToString(custom_dictionary_file_, &contents);
    std::vector<std::string> list_of_words;
    base::SplitString(contents, '\n', &list_of_words);
    for (size_t i = 0; i < list_of_words.size(); ++i)
      custom_words_.push_back(list_of_words[i]);
  }

  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
      NewRunnableMethod(this,
          &SpellCheckHostImpl::InformObserverOfInitialization));
}

void SpellCheckHostImpl::InitializeOnFileThread() {
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));

  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this, &SpellCheckHostImpl::Initialize));
}

void SpellCheckHostImpl::InformObserverOfInitialization() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (observer_)
    observer_->SpellCheckHostInitialized();
}

void SpellCheckHostImpl::DownloadDictionary() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (!request_context_getter_) {
    InitializeOnFileThread();
    return;
  }

  // Determine URL of file to download.
  static const char kDownloadServerUrl[] =
      "http://cache.pack.google.com/edgedl/chrome/dict/";
  std::string bdict_file = bdict_file_path_.BaseName().MaybeAsASCII();
  if (bdict_file.empty()) {
    NOTREACHED();
    return;
  }
  GURL url = GURL(std::string(kDownloadServerUrl) +
                  StringToLowerASCII(bdict_file));
  fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
  fetcher_->set_request_context(request_context_getter_);
  tried_to_download_ = true;
  fetcher_->Start();
  request_context_getter_ = NULL;
}

void SpellCheckHostImpl::WriteWordToCustomDictionary(const std::string& word) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  // Stored in UTF-8.
  std::string word_to_add(word + "\n");
  FILE* f = file_util::OpenFile(custom_dictionary_file_, "a+");
  if (f)
    fputs(word_to_add.c_str(), f);
  file_util::CloseFile(f);
}

void SpellCheckHostImpl::OnURLFetchComplete(const URLFetcher* source,
                                            const GURL& url,
                                            const net::URLRequestStatus& status,
                                            int response_code,
                                            const ResponseCookies& cookies,
                                            const std::string& data) {
  DCHECK(source);
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  fetcher_.reset();

  if ((response_code / 100) != 2) {
    // Initialize will not try to download the file a second time.
    LOG(ERROR) << "Failure to download dictionary.";
    InitializeOnFileThread();
    return;
  }

  // Basic sanity check on the dictionary.
  // There's the small chance that we might see a 200 status code for a body
  // that represents some form of failure.
  if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' ||
      data[3] != 'c') {
    LOG(ERROR) << "Failure to download dictionary.";
    InitializeOnFileThread();
    return;
  }

  data_ = data;
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this, &SpellCheckHostImpl::SaveDictionaryData));
}

void SpellCheckHostImpl::SaveDictionaryData() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  // To prevent corrupted dictionary data from causing a renderer crash, scan
  // the dictionary data and verify it is sane before save it to a file.
  if (!hunspell::BDict::Verify(data_.data(), data_.size())) {
    LOG(ERROR) << "Failure to verify the downloaded dictionary.";
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this,
                          &SpellCheckHostImpl::InformObserverOfInitialization));
    return;
  }

  size_t bytes_written =
      file_util::WriteFile(bdict_file_path_, data_.data(), data_.length());
  if (bytes_written != data_.length()) {
    bool success = false;
#if defined(OS_WIN)
    bdict_file_path_ = GetFallbackFilePath(bdict_file_path_);
    bytes_written =
        file_util::WriteFile(GetFallbackFilePath(bdict_file_path_),
                                                 data_.data(), data_.length());
    if (bytes_written == data_.length())
      success = true;
#endif
    data_.clear();

    if (!success) {
      LOG(ERROR) << "Failure to save dictionary.";
      file_util::Delete(bdict_file_path_, false);
      // To avoid trying to load a partially saved dictionary, shortcut the
      // Initialize() call.
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
          NewRunnableMethod(this,
              &SpellCheckHostImpl::InformObserverOfInitialization));
      return;
    }
  }

  data_.clear();
  Initialize();
}

const base::PlatformFile& SpellCheckHostImpl::GetDictionaryFile() const {
  return file_;
}

const std::vector<std::string>& SpellCheckHostImpl::GetCustomWords() const {
  return custom_words_;
}

const std::string& SpellCheckHostImpl::GetLastAddedFile() const {
  return custom_words_.back();
}

const std::string& SpellCheckHostImpl::GetLanguage() const {
  return language_;
}

bool SpellCheckHostImpl::IsUsingPlatformChecker() const {
  return use_platform_spellchecker_;
}
<commit_msg>A quick fix for Bug 60643. This change just moves the initialization code of |bdict_file_path_| from SpellCheckHostImpl::SpellCheckHostImpl() (running on the UI thread) to SpellCheckHostImpl::InitializeDictionaryLocation() (running on the FILE thread) so we can initialize it without assertions.<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/browser/spellcheck_host_impl.h"

#include <set>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/spellcheck_host_observer.h"
#include "chrome/browser/spellchecker_platform_engine.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "chrome/common/spellcheck_common.h"
#include "content/common/notification_service.h"
#include "googleurl/src/gurl.h"
#include "third_party/hunspell/google/bdict.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_MACOSX)
#include "base/metrics/histogram.h"
#endif

namespace {

FilePath GetFirstChoiceFilePath(const std::string& language) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  FilePath dict_dir;
  PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir);
  return SpellCheckCommon::GetVersionedFileName(language, dict_dir);
}

#if defined(OS_MACOSX)
// Collect metrics on how often Hunspell is used on OS X vs the native
// spellchecker.
void RecordSpellCheckStats(bool native_spellchecker_used,
                           const std::string& language) {
  static std::set<std::string> languages_seen;

  // Only count a language code once for each session..
  if (languages_seen.find(language) != languages_seen.end()) {
    return;
  }
  languages_seen.insert(language);

  enum {
    SPELLCHECK_OSX_NATIVE_SPELLCHECKER_USED = 0,
    SPELLCHECK_HUNSPELL_USED = 1
  };

  bool engine_used = native_spellchecker_used ?
                         SPELLCHECK_OSX_NATIVE_SPELLCHECKER_USED :
                         SPELLCHECK_HUNSPELL_USED;

  UMA_HISTOGRAM_COUNTS("SpellCheck.OSXEngineUsed", engine_used);
}
#endif

#if defined(OS_WIN)
FilePath GetFallbackFilePath(const FilePath& first_choice) {
  FilePath dict_dir;
  PathService::Get(chrome::DIR_USER_DATA, &dict_dir);
  return dict_dir.Append(first_choice.BaseName());
}
#endif

}  // namespace

// Constructed on UI thread.
SpellCheckHostImpl::SpellCheckHostImpl(
    SpellCheckHostObserver* observer,
    const std::string& language,
    URLRequestContextGetter* request_context_getter)
    : observer_(observer),
      language_(language),
      file_(base::kInvalidPlatformFileValue),
      tried_to_download_(false),
      use_platform_spellchecker_(false),
      request_context_getter_(request_context_getter) {
  DCHECK(observer_);
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  FilePath personal_file_directory;
  PathService::Get(chrome::DIR_USER_DATA, &personal_file_directory);
  custom_dictionary_file_ =
      personal_file_directory.Append(chrome::kCustomDictionaryFileName);
}

SpellCheckHostImpl::~SpellCheckHostImpl() {
  if (file_ != base::kInvalidPlatformFileValue)
    base::ClosePlatformFile(file_);
}

void SpellCheckHostImpl::Initialize() {
  if (SpellCheckerPlatform::SpellCheckerAvailable() &&
      SpellCheckerPlatform::PlatformSupportsLanguage(language_)) {
#if defined(OS_MACOSX)
    RecordSpellCheckStats(true, language_);
#endif
    use_platform_spellchecker_ = true;
    SpellCheckerPlatform::SetLanguage(language_);
    MessageLoop::current()->PostTask(FROM_HERE,
        NewRunnableMethod(this,
            &SpellCheckHostImpl::InformObserverOfInitialization));
    return;
  }

#if defined(OS_MACOSX)
  RecordSpellCheckStats(false, language_);
#endif

  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this,
                        &SpellCheckHostImpl::InitializeDictionaryLocation));
}

void SpellCheckHostImpl::UnsetObserver() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  observer_ = NULL;
  request_context_getter_ = NULL;
  fetcher_.reset();
}

void SpellCheckHostImpl::AddWord(const std::string& word) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  custom_words_.push_back(word);
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this,
          &SpellCheckHostImpl::WriteWordToCustomDictionary, word));
  NotificationService::current()->Notify(
      NotificationType::SPELLCHECK_WORD_ADDED,
      Source<SpellCheckHost>(this), NotificationService::NoDetails());
}

void SpellCheckHostImpl::InitializeDictionaryLocation() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  // Initialize the BDICT path. This initialization should be in the FILE thread
  // because it checks if there is a "Dictionaries" directory and create it.
  if (bdict_file_path_.empty())
    bdict_file_path_ = GetFirstChoiceFilePath(language_);

#if defined(OS_WIN)
  // Check if the dictionary exists in the fallback location. If so, use it
  // rather than downloading anew.
  FilePath fallback = GetFallbackFilePath(bdict_file_path_);
  if (!file_util::PathExists(bdict_file_path_) &&
      file_util::PathExists(fallback)) {
    bdict_file_path_ = fallback;
  }
#endif

  InitializeInternal();
}

void SpellCheckHostImpl::InitializeInternal() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  if (!observer_)
    return;

  file_ = base::CreatePlatformFile(
      bdict_file_path_,
      base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN,
      NULL, NULL);

  // File didn't exist. Download it.
  if (file_ == base::kInvalidPlatformFileValue && !tried_to_download_ &&
      request_context_getter_) {
    // We download from the ui thread because we need to know that
    // |request_context_getter_| is still valid before initiating the download.
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this, &SpellCheckHostImpl::DownloadDictionary));
    return;
  }

  request_context_getter_ = NULL;

  if (file_ != base::kInvalidPlatformFileValue) {
    // Load custom dictionary.
    std::string contents;
    file_util::ReadFileToString(custom_dictionary_file_, &contents);
    std::vector<std::string> list_of_words;
    base::SplitString(contents, '\n', &list_of_words);
    for (size_t i = 0; i < list_of_words.size(); ++i)
      custom_words_.push_back(list_of_words[i]);
  }

  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
      NewRunnableMethod(this,
          &SpellCheckHostImpl::InformObserverOfInitialization));
}

void SpellCheckHostImpl::InitializeOnFileThread() {
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE));

  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this, &SpellCheckHostImpl::Initialize));
}

void SpellCheckHostImpl::InformObserverOfInitialization() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (observer_)
    observer_->SpellCheckHostInitialized();
}

void SpellCheckHostImpl::DownloadDictionary() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  if (!request_context_getter_) {
    InitializeOnFileThread();
    return;
  }

  // Determine URL of file to download.
  static const char kDownloadServerUrl[] =
      "http://cache.pack.google.com/edgedl/chrome/dict/";
  std::string bdict_file = bdict_file_path_.BaseName().MaybeAsASCII();
  if (bdict_file.empty()) {
    NOTREACHED();
    return;
  }
  GURL url = GURL(std::string(kDownloadServerUrl) +
                  StringToLowerASCII(bdict_file));
  fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
  fetcher_->set_request_context(request_context_getter_);
  tried_to_download_ = true;
  fetcher_->Start();
  request_context_getter_ = NULL;
}

void SpellCheckHostImpl::WriteWordToCustomDictionary(const std::string& word) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  // Stored in UTF-8.
  std::string word_to_add(word + "\n");
  FILE* f = file_util::OpenFile(custom_dictionary_file_, "a+");
  if (f)
    fputs(word_to_add.c_str(), f);
  file_util::CloseFile(f);
}

void SpellCheckHostImpl::OnURLFetchComplete(const URLFetcher* source,
                                            const GURL& url,
                                            const net::URLRequestStatus& status,
                                            int response_code,
                                            const ResponseCookies& cookies,
                                            const std::string& data) {
  DCHECK(source);
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  fetcher_.reset();

  if ((response_code / 100) != 2) {
    // Initialize will not try to download the file a second time.
    LOG(ERROR) << "Failure to download dictionary.";
    InitializeOnFileThread();
    return;
  }

  // Basic sanity check on the dictionary.
  // There's the small chance that we might see a 200 status code for a body
  // that represents some form of failure.
  if (data.size() < 4 || data[0] != 'B' || data[1] != 'D' || data[2] != 'i' ||
      data[3] != 'c') {
    LOG(ERROR) << "Failure to download dictionary.";
    InitializeOnFileThread();
    return;
  }

  data_ = data;
  BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(this, &SpellCheckHostImpl::SaveDictionaryData));
}

void SpellCheckHostImpl::SaveDictionaryData() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  // To prevent corrupted dictionary data from causing a renderer crash, scan
  // the dictionary data and verify it is sane before save it to a file.
  if (!hunspell::BDict::Verify(data_.data(), data_.size())) {
    LOG(ERROR) << "Failure to verify the downloaded dictionary.";
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this,
                          &SpellCheckHostImpl::InformObserverOfInitialization));
    return;
  }

  size_t bytes_written =
      file_util::WriteFile(bdict_file_path_, data_.data(), data_.length());
  if (bytes_written != data_.length()) {
    bool success = false;
#if defined(OS_WIN)
    bdict_file_path_ = GetFallbackFilePath(bdict_file_path_);
    bytes_written =
        file_util::WriteFile(GetFallbackFilePath(bdict_file_path_),
                                                 data_.data(), data_.length());
    if (bytes_written == data_.length())
      success = true;
#endif
    data_.clear();

    if (!success) {
      LOG(ERROR) << "Failure to save dictionary.";
      file_util::Delete(bdict_file_path_, false);
      // To avoid trying to load a partially saved dictionary, shortcut the
      // Initialize() call.
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
          NewRunnableMethod(this,
              &SpellCheckHostImpl::InformObserverOfInitialization));
      return;
    }
  }

  data_.clear();
  Initialize();
}

const base::PlatformFile& SpellCheckHostImpl::GetDictionaryFile() const {
  return file_;
}

const std::vector<std::string>& SpellCheckHostImpl::GetCustomWords() const {
  return custom_words_;
}

const std::string& SpellCheckHostImpl::GetLastAddedFile() const {
  return custom_words_.back();
}

const std::string& SpellCheckHostImpl::GetLanguage() const {
  return language_;
}

bool SpellCheckHostImpl::IsUsingPlatformChecker() const {
  return use_platform_spellchecker_;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: controlpropertymap.cxx,v $
 *
 *  $Revision: 1.25 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:13:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
#ifndef _XMLOFF_PROPMAPPINGTYPES_HXX
#include <xmloff/maptype.hxx>
#endif
#ifndef _XMLOFF_XMLTYPES_HXX
#include <xmloff/xmltypes.hxx>
#endif
#ifndef __SGI_STL_ALGORITHM
#include <algorithm>
#endif

#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#include "strings.hxx"
#endif
#ifndef _XMLOFF_CONTEXTID_HXX_
#include <xmloff/contextid.hxx>
#endif

#ifndef _XMLOFF_FORMS_CONTROLPROPERTYMAP_HXX_
#include "controlpropertymap.hxx"
#endif

#include <string.h>

using namespace ::xmloff::token;

//.........................................................................
namespace xmloff
{
//.........................................................................

#define MAP_ASCII( name, prefix, token, type, context )  { name, sizeof(name)-1, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST( name, prefix, token, type, context )  { name.ascii, name.length, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST_P( name, prefix, token, type, context )  { name.ascii, name.length,   prefix, token, type|XML_TYPE_PROP_PARAGRAPH, context }
#define MAP_END()   { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0 }

    XMLPropertyMapEntry* getControlStylePropertyMap_Access( )
    {
        static XMLPropertyMapEntry aControlStyleProperties[] =
        {
            MAP_CONST( PROPERTY_BACKGROUNDCOLOR, XML_NAMESPACE_FO,      XML_BACKGROUND_COLOR,       XML_TYPE_COLOR, 0 ),
            MAP_CONST_P( PROPERTY_ALIGN,          XML_NAMESPACE_FO,       XML_TEXT_ALIGN,             XML_TYPE_TEXT_ALIGN, 0 ),
            MAP_CONST( PROPERTY_BORDER,         XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "FontCharWidth",         XML_NAMESPACE_STYLE,    XML_FONT_CHAR_WIDTH,        XML_TYPE_NUMBER16, 0 ),
            MAP_ASCII( "FontCharset",           XML_NAMESPACE_STYLE,    XML_FONT_CHARSET,           XML_TYPE_TEXT_FONTENCODING, 0 ),
            MAP_ASCII( "FontFamily",            XML_NAMESPACE_STYLE,    XML_FONT_FAMILY_GENERIC,    XML_TYPE_TEXT_FONTFAMILY, 0 ),
            MAP_ASCII( "FontHeight",            XML_NAMESPACE_FO,       XML_FONT_SIZE,              XML_TYPE_CHAR_HEIGHT, 0 ),
            MAP_ASCII( "FontKerning",           XML_NAMESPACE_STYLE,    XML_LETTER_KERNING,         XML_TYPE_BOOL, 0 ),
            MAP_ASCII( "FontName",              XML_NAMESPACE_STYLE,    XML_FONT_NAME,              XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontOrientation",       XML_NAMESPACE_STYLE,    XML_ROTATION_ANGLE,         XML_TYPE_ROTATION_ANGLE, 0 ),
            MAP_ASCII( "FontPitch",             XML_NAMESPACE_STYLE,    XML_FONT_PITCH,             XML_TYPE_TEXT_FONTPITCH, 0 ),
            MAP_ASCII( "FontSlant",             XML_NAMESPACE_FO,       XML_FONT_STYLE,             XML_TYPE_TEXT_POSTURE, 0 ),

            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_STYLE,    XML_TYPE_TEXT_CROSSEDOUT_STYLE|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TYPE,     XML_TYPE_TEXT_CROSSEDOUT_TYPE|MID_FLAG_MERGE_PROPERTY,  0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_WIDTH,    XML_TYPE_TEXT_CROSSEDOUT_WIDTH|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TEXT,     XML_TYPE_TEXT_CROSSEDOUT_TEXT|MID_FLAG_MERGE_PROPERTY,  0),

            MAP_ASCII( "FontStyleName",         XML_NAMESPACE_STYLE,    XML_FONT_STYLE_NAME,        XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_STYLE,       XML_TYPE_TEXT_UNDERLINE_STYLE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_TYPE,        XML_TYPE_TEXT_UNDERLINE_TYPE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_WIDTH,       XML_TYPE_TEXT_UNDERLINE_WIDTH|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontWeight",            XML_NAMESPACE_FO,       XML_FONT_WEIGHT,            XML_TYPE_TEXT_WEIGHT, 0 ),
            MAP_ASCII( "FontWidth",             XML_NAMESPACE_STYLE,    XML_FONT_WIDTH,             XML_TYPE_FONT_WIDTH, 0 ),
            MAP_ASCII( "FontWordLineMode",      XML_NAMESPACE_FO,       XML_SCORE_SPACES,           XML_TYPE_NBOOL, 0 ),
            MAP_ASCII( "SymbolColor",           XML_NAMESPACE_STYLE,    XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_ASCII( "BorderColor",           XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER_COLOR|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "TextColor",             XML_NAMESPACE_FO,       XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_CONST( PROPERTY_FORMATKEY,      XML_NAMESPACE_STYLE,    XML_DATA_STYLE_NAME,        XML_TYPE_STRING | MID_FLAG_NO_PROPERTY_EXPORT | MID_FLAG_SPECIAL_ITEM, CTF_FORMS_DATA_STYLE ),
            MAP_ASCII( "FontEmphasisMark",      XML_NAMESPACE_STYLE,    XML_TEXT_EMPHASIZE,         XML_TYPE_CONTROL_TEXT_EMPHASIZE, 0 ),
            MAP_ASCII( "FontRelief",            XML_NAMESPACE_STYLE,    XML_FONT_RELIEF,            XML_TYPE_TEXT_FONT_RELIEF|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_ASCII( "TextLineColor",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_COLOR,   XML_TYPE_TEXT_UNDERLINE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_END()
        };

        return aControlStyleProperties;
    }

    const XMLPropertyMapEntry* getControlStylePropertyMap( )
    {
        return getControlStylePropertyMap_Access();
    }

    //=====================================================================
    //---------------------------------------------------------------------
    struct XMLPropertyMapEntryLess
    {
        sal_Bool operator()(const XMLPropertyMapEntry& _rLeft, const XMLPropertyMapEntry& _rRight)
        {
            return strcmp(_rLeft.msApiName, _rRight.msApiName) < 0;
        }
    };

    //---------------------------------------------------------------------
    void implSortMap(XMLPropertyMapEntry* _pMap)
    {
        XMLPropertyMapEntry* pEnd;
        // determine the last element
        for ( pEnd = _pMap; pEnd->msApiName; ++pEnd)
            ;
        ::std::sort(_pMap, pEnd, XMLPropertyMapEntryLess());
    }

    //---------------------------------------------------------------------
    void initializePropertyMaps()
    {
        static sal_Bool bSorted = sal_False;
        if (!bSorted)
        {
            implSortMap(getControlStylePropertyMap_Access());
            bSorted = sal_True;
        }
    }

    //=====================================================================
    //= OFormExportPropertyMapper
    //=====================================================================
    //---------------------------------------------------------------------
    OFormExportPropertyMapper::OFormExportPropertyMapper( const UniReference< XMLPropertySetMapper >& _rMapper )
        :SvXMLExportPropertyMapper( _rMapper )
    {
    }

    //---------------------------------------------------------------------
    void OFormExportPropertyMapper::handleSpecialItem( SvXMLAttributeList& _rAttrList, const XMLPropertyState& _rProperty, const SvXMLUnitConverter& _rUnitConverter,
        const SvXMLNamespaceMap& _rNamespaceMap, const ::std::vector< XMLPropertyState >* _pProperties,
        sal_uInt32 _nIdx ) const
    {
        // ignore the number style of grid columns - this is formatted elsewhere
        if ( CTF_FORMS_DATA_STYLE != getPropertySetMapper()->GetEntryContextId( _rProperty.mnIndex ) )
            SvXMLExportPropertyMapper::handleSpecialItem( _rAttrList, _rProperty, _rUnitConverter, _rNamespaceMap, _pProperties, _nIdx );
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

<commit_msg>INTEGRATION: CWS changefileheader (1.25.162); FILE MERGED 2008/04/01 13:04:48 thb 1.25.162.2: #i85898# Stripping all external header guards 2008/03/31 16:28:11 rt 1.25.162.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: controlpropertymap.cxx,v $
 * $Revision: 1.26 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include "xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/maptype.hxx>
#include <xmloff/xmltypes.hxx>
#ifndef __SGI_STL_ALGORITHM
#include <algorithm>
#endif
#include "strings.hxx"
#include <xmloff/contextid.hxx>
#include "controlpropertymap.hxx"

#include <string.h>

using namespace ::xmloff::token;

//.........................................................................
namespace xmloff
{
//.........................................................................

#define MAP_ASCII( name, prefix, token, type, context )  { name, sizeof(name)-1, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST( name, prefix, token, type, context )  { name.ascii, name.length, prefix, token, type|XML_TYPE_PROP_TEXT, context }
#define MAP_CONST_P( name, prefix, token, type, context )  { name.ascii, name.length,   prefix, token, type|XML_TYPE_PROP_PARAGRAPH, context }
#define MAP_END()   { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0 }

    XMLPropertyMapEntry* getControlStylePropertyMap_Access( )
    {
        static XMLPropertyMapEntry aControlStyleProperties[] =
        {
            MAP_CONST( PROPERTY_BACKGROUNDCOLOR, XML_NAMESPACE_FO,      XML_BACKGROUND_COLOR,       XML_TYPE_COLOR, 0 ),
            MAP_CONST_P( PROPERTY_ALIGN,          XML_NAMESPACE_FO,       XML_TEXT_ALIGN,             XML_TYPE_TEXT_ALIGN, 0 ),
            MAP_CONST( PROPERTY_BORDER,         XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "FontCharWidth",         XML_NAMESPACE_STYLE,    XML_FONT_CHAR_WIDTH,        XML_TYPE_NUMBER16, 0 ),
            MAP_ASCII( "FontCharset",           XML_NAMESPACE_STYLE,    XML_FONT_CHARSET,           XML_TYPE_TEXT_FONTENCODING, 0 ),
            MAP_ASCII( "FontFamily",            XML_NAMESPACE_STYLE,    XML_FONT_FAMILY_GENERIC,    XML_TYPE_TEXT_FONTFAMILY, 0 ),
            MAP_ASCII( "FontHeight",            XML_NAMESPACE_FO,       XML_FONT_SIZE,              XML_TYPE_CHAR_HEIGHT, 0 ),
            MAP_ASCII( "FontKerning",           XML_NAMESPACE_STYLE,    XML_LETTER_KERNING,         XML_TYPE_BOOL, 0 ),
            MAP_ASCII( "FontName",              XML_NAMESPACE_STYLE,    XML_FONT_NAME,              XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontOrientation",       XML_NAMESPACE_STYLE,    XML_ROTATION_ANGLE,         XML_TYPE_ROTATION_ANGLE, 0 ),
            MAP_ASCII( "FontPitch",             XML_NAMESPACE_STYLE,    XML_FONT_PITCH,             XML_TYPE_TEXT_FONTPITCH, 0 ),
            MAP_ASCII( "FontSlant",             XML_NAMESPACE_FO,       XML_FONT_STYLE,             XML_TYPE_TEXT_POSTURE, 0 ),

            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_STYLE,    XML_TYPE_TEXT_CROSSEDOUT_STYLE|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TYPE,     XML_TYPE_TEXT_CROSSEDOUT_TYPE|MID_FLAG_MERGE_PROPERTY,  0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_WIDTH,    XML_TYPE_TEXT_CROSSEDOUT_WIDTH|MID_FLAG_MERGE_PROPERTY, 0),
            MAP_ASCII( "FontStrikeout",         XML_NAMESPACE_STYLE,    XML_TEXT_LINE_THROUGH_TEXT,     XML_TYPE_TEXT_CROSSEDOUT_TEXT|MID_FLAG_MERGE_PROPERTY,  0),

            MAP_ASCII( "FontStyleName",         XML_NAMESPACE_STYLE,    XML_FONT_STYLE_NAME,        XML_TYPE_STRING, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_STYLE,       XML_TYPE_TEXT_UNDERLINE_STYLE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_TYPE,        XML_TYPE_TEXT_UNDERLINE_TYPE|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontUnderline",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_WIDTH,       XML_TYPE_TEXT_UNDERLINE_WIDTH|MID_FLAG_MERGE_PROPERTY, 0 ),
            MAP_ASCII( "FontWeight",            XML_NAMESPACE_FO,       XML_FONT_WEIGHT,            XML_TYPE_TEXT_WEIGHT, 0 ),
            MAP_ASCII( "FontWidth",             XML_NAMESPACE_STYLE,    XML_FONT_WIDTH,             XML_TYPE_FONT_WIDTH, 0 ),
            MAP_ASCII( "FontWordLineMode",      XML_NAMESPACE_FO,       XML_SCORE_SPACES,           XML_TYPE_NBOOL, 0 ),
            MAP_ASCII( "SymbolColor",           XML_NAMESPACE_STYLE,    XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_ASCII( "BorderColor",           XML_NAMESPACE_FO,       XML_BORDER,                 XML_TYPE_CONTROL_BORDER_COLOR|MID_FLAG_MULTI_PROPERTY|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
            MAP_ASCII( "TextColor",             XML_NAMESPACE_FO,       XML_COLOR,                  XML_TYPE_COLOR, 0 ),
            MAP_CONST( PROPERTY_FORMATKEY,      XML_NAMESPACE_STYLE,    XML_DATA_STYLE_NAME,        XML_TYPE_STRING | MID_FLAG_NO_PROPERTY_EXPORT | MID_FLAG_SPECIAL_ITEM, CTF_FORMS_DATA_STYLE ),
            MAP_ASCII( "FontEmphasisMark",      XML_NAMESPACE_STYLE,    XML_TEXT_EMPHASIZE,         XML_TYPE_CONTROL_TEXT_EMPHASIZE, 0 ),
            MAP_ASCII( "FontRelief",            XML_NAMESPACE_STYLE,    XML_FONT_RELIEF,            XML_TYPE_TEXT_FONT_RELIEF|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_ASCII( "TextLineColor",         XML_NAMESPACE_STYLE,    XML_TEXT_UNDERLINE_COLOR,   XML_TYPE_TEXT_UNDERLINE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
            MAP_END()
        };

        return aControlStyleProperties;
    }

    const XMLPropertyMapEntry* getControlStylePropertyMap( )
    {
        return getControlStylePropertyMap_Access();
    }

    //=====================================================================
    //---------------------------------------------------------------------
    struct XMLPropertyMapEntryLess
    {
        sal_Bool operator()(const XMLPropertyMapEntry& _rLeft, const XMLPropertyMapEntry& _rRight)
        {
            return strcmp(_rLeft.msApiName, _rRight.msApiName) < 0;
        }
    };

    //---------------------------------------------------------------------
    void implSortMap(XMLPropertyMapEntry* _pMap)
    {
        XMLPropertyMapEntry* pEnd;
        // determine the last element
        for ( pEnd = _pMap; pEnd->msApiName; ++pEnd)
            ;
        ::std::sort(_pMap, pEnd, XMLPropertyMapEntryLess());
    }

    //---------------------------------------------------------------------
    void initializePropertyMaps()
    {
        static sal_Bool bSorted = sal_False;
        if (!bSorted)
        {
            implSortMap(getControlStylePropertyMap_Access());
            bSorted = sal_True;
        }
    }

    //=====================================================================
    //= OFormExportPropertyMapper
    //=====================================================================
    //---------------------------------------------------------------------
    OFormExportPropertyMapper::OFormExportPropertyMapper( const UniReference< XMLPropertySetMapper >& _rMapper )
        :SvXMLExportPropertyMapper( _rMapper )
    {
    }

    //---------------------------------------------------------------------
    void OFormExportPropertyMapper::handleSpecialItem( SvXMLAttributeList& _rAttrList, const XMLPropertyState& _rProperty, const SvXMLUnitConverter& _rUnitConverter,
        const SvXMLNamespaceMap& _rNamespaceMap, const ::std::vector< XMLPropertyState >* _pProperties,
        sal_uInt32 _nIdx ) const
    {
        // ignore the number style of grid columns - this is formatted elsewhere
        if ( CTF_FORMS_DATA_STYLE != getPropertySetMapper()->GetEntryContextId( _rProperty.mnIndex ) )
            SvXMLExportPropertyMapper::handleSpecialItem( _rAttrList, _rProperty, _rUnitConverter, _rNamespaceMap, _pProperties, _nIdx );
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "app/message_box_flags.h"
#include "base/gfx/rect.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/view_ids.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "views/event.h"

#if defined(OS_WIN)
#define MAYBE_SlowTermination DISABLED_SlowTermination
#else
#define MAYBE_SlowTermination SlowTermination
#endif

class FastShutdown : public UITest {
};

// This tests for a previous error where uninstalling an onbeforeunload
// handler would enable fast shutdown even if an onUnload handler still
// existed.
TEST_F(FastShutdown, MAYBE_SlowTermination) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  scoped_refptr<WindowProxy> window(browser->GetWindow());
  ASSERT_TRUE(window.get());

  // This page has an unload handler.
  GURL url = GetTestUrl(L"fast_shutdown", L"on_unloader.html");
  NavigateToURLBlockUntilNavigationsComplete(url, 1);
  gfx::Rect bounds;
  ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER, &bounds, true));
  // This click will launch a popup which has a before unload handler.
  ASSERT_TRUE(window->SimulateOSClick(bounds.CenterPoint(),
                                      views::Event::EF_LEFT_BUTTON_DOWN));
  ASSERT_TRUE(browser->WaitForTabCountToBecome(2, action_timeout_ms()));
  // Close the tab, removing the one and only before unload handler.
  scoped_refptr<TabProxy> tab(browser->GetTab(1));
  ASSERT_TRUE(tab->Close(true));

  // Close the browser. We should launch the unload handler, which is an
  // alert().
  ASSERT_TRUE(browser->ApplyAccelerator(IDC_CLOSE_WINDOW));
  ASSERT_TRUE(automation()->WaitForAppModalDialog(action_timeout_ms()));
  automation()->ClickAppModalDialogButton(MessageBoxFlags::DIALOGBUTTON_OK);
}
<commit_msg>Increase the action timeout on the fast shutdown ui test.<commit_after>// Copyright (c) 2009 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 "app/message_box_flags.h"
#include "base/gfx/rect.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/view_ids.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "views/event.h"

#if defined(OS_WIN)
#define MAYBE_SlowTermination DISABLED_SlowTermination
#else
#define MAYBE_SlowTermination SlowTermination
#endif

class FastShutdown : public UITest {
};

// This tests for a previous error where uninstalling an onbeforeunload
// handler would enable fast shutdown even if an onUnload handler still
// existed.
TEST_F(FastShutdown, MAYBE_SlowTermination) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  scoped_refptr<WindowProxy> window(browser->GetWindow());
  ASSERT_TRUE(window.get());

  // This page has an unload handler.
  GURL url = GetTestUrl(L"fast_shutdown", L"on_unloader.html");
  NavigateToURLBlockUntilNavigationsComplete(url, 1);
  gfx::Rect bounds;
  ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER, &bounds, true));
  // This click will launch a popup which has a before unload handler.
  ASSERT_TRUE(window->SimulateOSClick(bounds.CenterPoint(),
                                      views::Event::EF_LEFT_BUTTON_DOWN));
  ASSERT_TRUE(browser->WaitForTabCountToBecome(2, action_max_timeout_ms()));
  // Close the tab, removing the one and only before unload handler.
  scoped_refptr<TabProxy> tab(browser->GetTab(1));
  ASSERT_TRUE(tab->Close(true));

  // Close the browser. We should launch the unload handler, which is an
  // alert().
  ASSERT_TRUE(browser->ApplyAccelerator(IDC_CLOSE_WINDOW));
  ASSERT_TRUE(automation()->WaitForAppModalDialog(action_max_timeout_ms()));
  automation()->ClickAppModalDialogButton(MessageBoxFlags::DIALOGBUTTON_OK);
}
<|endoftext|>