<commit_before>/*
 *  gucefCOM: GUCEF module providing communication
 *  implementations for standardized protocols.
 *  Copyright (C) 2002 - 2007.  Dinand Vanvelzen
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  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
 */

/*-------------------------------------------------------------------------//
//                                                                         //
//      INCLUDES                                                           //
//                                                                         //
//-------------------------------------------------------------------------*/

#ifndef GUCEF_CORE_CDATANODE_H
#include "CDataNode.h"
#define GUCEF_CORE_CDATANODE_H
#endif /* GUCEF_CORE_CDATANODE_H ? */

#include "gucefCOM_CStatsDClient.h"

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

namespace GUCEF {
namespace COM {

/*-------------------------------------------------------------------------//
//                                                                         //
//      IMPLEMENTATION                                                     //
//                                                                         //
//-------------------------------------------------------------------------*/

CStatsDClient::CStatsDClient( void )
    : CORE::CIMetricsSystemClient()
    , m_udpSender( false )
    , m_statsDestination()
    , m_statsInterface()
    , m_statNamePrefix()
{GUCEF_TRACE;

    m_statsDestination.SetPortInHostByteOrder( 8125 );
}

/*-------------------------------------------------------------------------*/

CStatsDClient::CStatsDClient( CORE::CPulseGenerator& pulseGenerator )
    : CORE::CIMetricsSystemClient()
    , m_udpSender( pulseGenerator, false )
    , m_statsDestination()
    , m_statsInterface()
    , m_statNamePrefix()
{GUCEF_TRACE;

    m_statsDestination.SetPortInHostByteOrder( 8125 );
}

/*-------------------------------------------------------------------------*/

CStatsDClient::~CStatsDClient()
{GUCEF_TRACE;

    m_udpSender.Close();
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Increment( const CString& key, const Float32 frequency ) const
{GUCEF_TRACE;

    Count( key, 1, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Decrement( const CString& key, const Float32 frequency ) const
{GUCEF_TRACE;

    Count( key, -1, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Count( const CString& key, const Int32 delta, const Float32 frequency ) const
{GUCEF_TRACE;

    static const CString statTypeName = "c";
    Transmit( key, delta, statTypeName, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Gauge( const CString& key, const UInt32 value, const Float32 frequency ) const
{GUCEF_TRACE;

    static const CString statTypeName = "g";
    Transmit( key, value, statTypeName, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Timing( const CString& key, const UInt32 ms, const Float32 frequency ) const
{GUCEF_TRACE;

    static const CString statTypeName = "ms";
    Transmit( key, ms, statTypeName, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Transmit( const CString& key      ,
                         const Int32 value       ,
                         const CString& type     ,
                         const Float32 frequency ) const
{GUCEF_TRACE;

    if ( !m_udpSender.IsActive() )
    {
        CStatsDClient* thisObj = const_cast< CStatsDClient* >( this );
        if ( !thisObj->Open() )
            return;
    }

    const auto isFrequencyOne = []( const Float32 frequency ) noexcept
    {
        constexpr Float32 epsilon{ 0.0001f };
        return std::fabs( frequency - 1.0f ) < epsilon;
    };

    // Test if one should send or not, according to the frequency rate
    if ( !isFrequencyOne( frequency ) )
    {
        if ( frequency < static_cast<float>( std::rand() ) / RAND_MAX )
        {
            return;
        }
    }

    // Prepare the buffer, with a sampling rate if specified different from 1.0f
    char buffer[256];
    int msgSize=0;
    if ( isFrequencyOne( frequency ) )
    {
        // Sampling rate is 1.0f, no need to specify it
        msgSize = std::snprintf( buffer, sizeof(buffer), "%s%s:%d|%s", m_statNamePrefix.C_String(), key.C_String(), value, type.C_String() );
    }
    else
    {
        // Sampling rate is different from 1.0f, hence specify it
        msgSize = std::snprintf( buffer, sizeof(buffer), "%s%s:%d|%s|@%.2f", m_statNamePrefix.C_String(), key.C_String(), value, type.C_String(), frequency );
    }

    // Send the message via the UDP sender
    if ( msgSize > 0 )
        m_udpSender.SendPacketTo( m_statsDestination, buffer, (UInt16) msgSize );
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::SaveConfig( CORE::CDataNode& tree ) const
{GUCEF_TRACE;

    CORE::CDataNode* node = tree.Find( "StatsDClient" );
    if ( GUCEF_NULL == node )
    {
        node = tree.AddChild( "StatsDClient" );
        if ( GUCEF_NULL == node )
            return false;
    }

    node->SetAttribute( "StatsDestination", m_statsDestination.AddressAndPortAsString() );
    node->SetAttribute( "StatsNamePrefix", m_statNamePrefix );
    node->SetAttribute( "StatsInterface", m_statsInterface.AddressAndPortAsString() );
    return true;
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::LoadConfig( const CORE::CDataNode& treeroot )
{GUCEF_TRACE;

    const CORE::CDataNode* node = treeroot.Find( "StatsDClient" );
    if ( GUCEF_NULL != node )
    {
        // First load the mandatory settings
        CORE::CString value;
        value = node->GetAttributeValueOrChildValueByName( "StatsDestination" );
        if ( !value.IsNULLOrEmpty() )
        {
            value = CORE::ResolveVars( value );
            m_statsDestination.SetHostnameAndPort( value );
        }
        else
            return false;

        // Load extra settings for which the default can also be good enough
        value = node->GetAttributeValueOrChildValueByName( "StatsNamePrefix" );
        if ( !value.IsNULLOrEmpty() )
        {
            m_statNamePrefix = CORE::ResolveVars( value );
        }
        value = node->GetAttributeValueOrChildValueByName( "StatsInterface" );
        if ( !value.IsNULLOrEmpty() )
        {
            value = CORE::ResolveVars( value );
            m_statsInterface.SetHostnameAndPort( value );
        }

        return true;
    }
    return true;
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::Open( void )
{GUCEF_TRACE;

    if ( m_udpSender.IsActive() )
        m_udpSender.Close();

    if ( m_udpSender.Open( m_statsInterface ) )
    {
        GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "StatsDClient:Open(): Successfully opened socket at " + m_statsInterface.AddressAndPortAsString() );
        return true;
    }
    else
    {
        GUCEF_ERROR_LOG( CORE::LOGLEVEL_NORMAL, "StatsDClient:Open(): Failed to open socket at " + m_statsInterface.AddressAndPortAsString() );
        return false;
    }
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::Close( void )
{GUCEF_TRACE;

    m_udpSender.Close();
    return true;
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::SetStatsDestination( const COMCORE::CHostAddress& dest )
{GUCEF_TRACE;

    m_statsDestination = dest;
}

/*-------------------------------------------------------------------------*/

const COMCORE::CHostAddress&
CStatsDClient::GetStatsDestination( void ) const
{GUCEF_TRACE;

    return m_statsDestination;
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::SetStatsInterface( const COMCORE::CHostAddress& interface )
{GUCEF_TRACE;

    m_statsInterface = interface;
}

/*-------------------------------------------------------------------------*/

const COMCORE::CHostAddress&
CStatsDClient::GetStatsInterface( void ) const
{GUCEF_TRACE;

    return m_statsInterface;
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::SetStatNamePrefix( const CString& prefix )
{GUCEF_TRACE;

    m_statNamePrefix = prefix;
}

/*-------------------------------------------------------------------------*/

const CString&
CStatsDClient::GetStatNamePrefix( void ) const
{GUCEF_TRACE;

    return m_statNamePrefix;
}

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

} /* namespace COM */
} /* namespace GUCEF */

/*-------------------------------------------------------------------------*/
<commit_msg>Add header include needed to build under VS 2019<commit_after>/*
 *  gucefCOM: GUCEF module providing communication
 *  implementations for standardized protocols.
 *  Copyright (C) 2002 - 2007.  Dinand Vanvelzen
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  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
 */

/*-------------------------------------------------------------------------//
//                                                                         //
//      INCLUDES                                                           //
//                                                                         //
//-------------------------------------------------------------------------*/

#include <cmath>

#ifndef GUCEF_CORE_CDATANODE_H
#include "CDataNode.h"
#define GUCEF_CORE_CDATANODE_H
#endif /* GUCEF_CORE_CDATANODE_H ? */

#include "gucefCOM_CStatsDClient.h"

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

namespace GUCEF {
namespace COM {

/*-------------------------------------------------------------------------//
//                                                                         //
//      IMPLEMENTATION                                                     //
//                                                                         //
//-------------------------------------------------------------------------*/

CStatsDClient::CStatsDClient( void )
    : CORE::CIMetricsSystemClient()
    , m_udpSender( false )
    , m_statsDestination()
    , m_statsInterface()
    , m_statNamePrefix()
{GUCEF_TRACE;

    m_statsDestination.SetPortInHostByteOrder( 8125 );
}

/*-------------------------------------------------------------------------*/

CStatsDClient::CStatsDClient( CORE::CPulseGenerator& pulseGenerator )
    : CORE::CIMetricsSystemClient()
    , m_udpSender( pulseGenerator, false )
    , m_statsDestination()
    , m_statsInterface()
    , m_statNamePrefix()
{GUCEF_TRACE;

    m_statsDestination.SetPortInHostByteOrder( 8125 );
}

/*-------------------------------------------------------------------------*/

CStatsDClient::~CStatsDClient()
{GUCEF_TRACE;

    m_udpSender.Close();
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Increment( const CString& key, const Float32 frequency ) const
{GUCEF_TRACE;

    Count( key, 1, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Decrement( const CString& key, const Float32 frequency ) const
{GUCEF_TRACE;

    Count( key, -1, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Count( const CString& key, const Int32 delta, const Float32 frequency ) const
{GUCEF_TRACE;

    static const CString statTypeName = "c";
    Transmit( key, delta, statTypeName, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Gauge( const CString& key, const UInt32 value, const Float32 frequency ) const
{GUCEF_TRACE;

    static const CString statTypeName = "g";
    Transmit( key, value, statTypeName, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Timing( const CString& key, const UInt32 ms, const Float32 frequency ) const
{GUCEF_TRACE;

    static const CString statTypeName = "ms";
    Transmit( key, ms, statTypeName, frequency );
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::Transmit( const CString& key      ,
                         const Int32 value       ,
                         const CString& type     ,
                         const Float32 frequency ) const
{GUCEF_TRACE;

    if ( !m_udpSender.IsActive() )
    {
        CStatsDClient* thisObj = const_cast< CStatsDClient* >( this );
        if ( !thisObj->Open() )
            return;
    }

    const auto isFrequencyOne = []( const Float32 frequency ) noexcept
    {
        constexpr Float32 epsilon{ 0.0001f };
        return std::fabs( frequency - 1.0f ) < epsilon;
    };

    // Test if one should send or not, according to the frequency rate
    if ( !isFrequencyOne( frequency ) )
    {
        if ( frequency < static_cast<float>( std::rand() ) / RAND_MAX )
        {
            return;
        }
    }

    // Prepare the buffer, with a sampling rate if specified different from 1.0f
    char buffer[256];
    int msgSize=0;
    if ( isFrequencyOne( frequency ) )
    {
        // Sampling rate is 1.0f, no need to specify it
        msgSize = std::snprintf( buffer, sizeof(buffer), "%s%s:%d|%s", m_statNamePrefix.C_String(), key.C_String(), value, type.C_String() );
    }
    else
    {
        // Sampling rate is different from 1.0f, hence specify it
        msgSize = std::snprintf( buffer, sizeof(buffer), "%s%s:%d|%s|@%.2f", m_statNamePrefix.C_String(), key.C_String(), value, type.C_String(), frequency );
    }

    // Send the message via the UDP sender
    if ( msgSize > 0 )
        m_udpSender.SendPacketTo( m_statsDestination, buffer, (UInt16) msgSize );
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::SaveConfig( CORE::CDataNode& tree ) const
{GUCEF_TRACE;

    CORE::CDataNode* node = tree.Find( "StatsDClient" );
    if ( GUCEF_NULL == node )
    {
        node = tree.AddChild( "StatsDClient" );
        if ( GUCEF_NULL == node )
            return false;
    }

    node->SetAttribute( "StatsDestination", m_statsDestination.AddressAndPortAsString() );
    node->SetAttribute( "StatsNamePrefix", m_statNamePrefix );
    node->SetAttribute( "StatsInterface", m_statsInterface.AddressAndPortAsString() );
    return true;
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::LoadConfig( const CORE::CDataNode& treeroot )
{GUCEF_TRACE;

    const CORE::CDataNode* node = treeroot.Find( "StatsDClient" );
    if ( GUCEF_NULL != node )
    {
        // First load the mandatory settings
        CORE::CString value;
        value = node->GetAttributeValueOrChildValueByName( "StatsDestination" );
        if ( !value.IsNULLOrEmpty() )
        {
            value = CORE::ResolveVars( value );
            m_statsDestination.SetHostnameAndPort( value );
        }
        else
            return false;

        // Load extra settings for which the default can also be good enough
        value = node->GetAttributeValueOrChildValueByName( "StatsNamePrefix" );
        if ( !value.IsNULLOrEmpty() )
        {
            m_statNamePrefix = CORE::ResolveVars( value );
        }
        value = node->GetAttributeValueOrChildValueByName( "StatsInterface" );
        if ( !value.IsNULLOrEmpty() )
        {
            value = CORE::ResolveVars( value );
            m_statsInterface.SetHostnameAndPort( value );
        }

        return true;
    }
    return true;
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::Open( void )
{GUCEF_TRACE;

    if ( m_udpSender.IsActive() )
        m_udpSender.Close();

    if ( m_udpSender.Open( m_statsInterface ) )
    {
        GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "StatsDClient:Open(): Successfully opened socket at " + m_statsInterface.AddressAndPortAsString() );
        return true;
    }
    else
    {
        GUCEF_ERROR_LOG( CORE::LOGLEVEL_NORMAL, "StatsDClient:Open(): Failed to open socket at " + m_statsInterface.AddressAndPortAsString() );
        return false;
    }
}

/*-------------------------------------------------------------------------*/

bool
CStatsDClient::Close( void )
{GUCEF_TRACE;

    m_udpSender.Close();
    return true;
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::SetStatsDestination( const COMCORE::CHostAddress& dest )
{GUCEF_TRACE;

    m_statsDestination = dest;
}

/*-------------------------------------------------------------------------*/

const COMCORE::CHostAddress&
CStatsDClient::GetStatsDestination( void ) const
{GUCEF_TRACE;

    return m_statsDestination;
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::SetStatsInterface( const COMCORE::CHostAddress& interface )
{GUCEF_TRACE;

    m_statsInterface = interface;
}

/*-------------------------------------------------------------------------*/

const COMCORE::CHostAddress&
CStatsDClient::GetStatsInterface( void ) const
{GUCEF_TRACE;

    return m_statsInterface;
}

/*-------------------------------------------------------------------------*/

void
CStatsDClient::SetStatNamePrefix( const CString& prefix )
{GUCEF_TRACE;

    m_statNamePrefix = prefix;
}

/*-------------------------------------------------------------------------*/

const CString&
CStatsDClient::GetStatNamePrefix( void ) const
{GUCEF_TRACE;

    return m_statNamePrefix;
}

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

} /* namespace COM */
} /* namespace GUCEF */

/*-------------------------------------------------------------------------*/
<|endoftext|>


<commit_before>#include "test.h"
#include "Constants.h"
#include "Configuration.h"
#include "FilesystemInclude.h"
#include "FstreamInclude.h"

TEST(NoConfigurationFile)
{
  const filesystem::path tempDir = filesystem::unique_path(filesystem::temp_directory_path() / "%%%%%-%%%%%");
  ASSERT(filesystem::create_directories(tempDir));
  const filesystem::path curDir = filesystem::current_path();
  filesystem::current_path(tempDir);

  Configuration config;
  ASSERT(config.companyName == "YourCompany");
  ASSERT(config.regenTag == "GENERATED BY CPP-DEPENDENCIES");
  ASSERT(config.versionUsed == CURRENT_VERSION);
  ASSERT(config.cycleColor == "orange");
  ASSERT(config.publicDepColor == "blue");
  ASSERT(config.privateDepColor == "lightblue");
  ASSERT(config.componentLinkLimit == 30);
  ASSERT(config.componentLocLowerLimit == 200);
  ASSERT(config.componentLocUpperLimit == 20000);
  ASSERT(config.fileLocUpperLimit == 2000);
  ASSERT(config.addLibraryAliases.size() == 1);
  ASSERT(config.addLibraryAliases.count("add_library") == 1);
  ASSERT(config.addExecutableAliases.size() == 1);
  ASSERT(config.addExecutableAliases.count("add_executable") == 1);

  filesystem::current_path(curDir);
}

TEST(ReadConfigurationFile)
{
  const filesystem::path tempDir = filesystem::unique_path(filesystem::temp_directory_path() / "%%%%%-%%%%%");
  ASSERT(filesystem::create_directories(tempDir));
  const filesystem::path curDir = filesystem::current_path();
  filesystem::current_path(tempDir);

  streams::ofstream out(CONFIG_FILE);
  out << "versionUsed: 3\n"
      << "companyName: MyCompany\n"
      << "regenTag: MY_REGEN_TAG\n"
      << "cycleColor: brown\n"
      << "publicDepColor: black\n"
      << "privateDepColor: grey\n"
      << "componentLinkLimit: 2\n"
      << "componentLocLowerLimit: 1\n"
      << "componentLocUpperLimit: 123\n"
      << "fileLocUpperLimit: 567\n";
  out.close();

  Configuration config;
  ASSERT(config.companyName == "MyCompany");
  ASSERT(config.regenTag == "MY_REGEN_TAG");
  ASSERT(config.versionUsed == "3");
  ASSERT(config.cycleColor == "brown");
  ASSERT(config.publicDepColor == "black");
  ASSERT(config.privateDepColor == "grey");
  ASSERT(config.componentLinkLimit == 2);
  ASSERT(config.componentLocLowerLimit == 1);
  ASSERT(config.componentLocUpperLimit == 123);
  ASSERT(config.fileLocUpperLimit == 567);
  ASSERT(config.addLibraryAliases.size() == 1);
  ASSERT(config.addLibraryAliases.count("add_library") == 1);
  ASSERT(config.addExecutableAliases.size() == 1);
  ASSERT(config.addExecutableAliases.count("add_executable") == 1);

  filesystem::current_path(curDir);
}

TEST(ReadConfigurationFile_Aliases)
{
  const filesystem::path tempDir = filesystem::unique_path(filesystem::temp_directory_path() / "%%%%%-%%%%%");
  ASSERT(filesystem::create_directories(tempDir));
  const filesystem::path curDir = filesystem::current_path();
  filesystem::current_path(tempDir);

  streams::ofstream out(CONFIG_FILE);
  out << "addLibraryAlias: add_special_library\n"
      << "addLibraryAlias: add_test_lib\n"
      << "addExecutableAlias: add_special_exe\n"
      << "addExecutableAlias: add_test\n";
  out.close();

  Configuration config;
  ASSERT(config.addLibraryAliases.size() == 3);
  ASSERT(config.addLibraryAliases.count("add_library") == 1);
  ASSERT(config.addLibraryAliases.count("add_special_library") == 1);
  ASSERT(config.addLibraryAliases.count("add_test_lib") == 1);

  ASSERT(config.addExecutableAliases.size() == 3);
  ASSERT(config.addExecutableAliases.count("add_executable") == 1);
  ASSERT(config.addExecutableAliases.count("add_special_exe") == 1);
  ASSERT(config.addExecutableAliases.count("add_test") == 1);

  filesystem::current_path(curDir);
}
<commit_msg>Put writing to out file in separate scope.<commit_after>#include "test.h"
#include "Constants.h"
#include "Configuration.h"
#include "FilesystemInclude.h"
#include "FstreamInclude.h"

TEST(NoConfigurationFile)
{
  const filesystem::path tempDir = filesystem::unique_path(filesystem::temp_directory_path() / "%%%%%-%%%%%");
  ASSERT(filesystem::create_directories(tempDir));
  const filesystem::path curDir = filesystem::current_path();
  filesystem::current_path(tempDir);

  Configuration config;
  ASSERT(config.companyName == "YourCompany");
  ASSERT(config.regenTag == "GENERATED BY CPP-DEPENDENCIES");
  ASSERT(config.versionUsed == CURRENT_VERSION);
  ASSERT(config.cycleColor == "orange");
  ASSERT(config.publicDepColor == "blue");
  ASSERT(config.privateDepColor == "lightblue");
  ASSERT(config.componentLinkLimit == 30);
  ASSERT(config.componentLocLowerLimit == 200);
  ASSERT(config.componentLocUpperLimit == 20000);
  ASSERT(config.fileLocUpperLimit == 2000);
  ASSERT(config.addLibraryAliases.size() == 1);
  ASSERT(config.addLibraryAliases.count("add_library") == 1);
  ASSERT(config.addExecutableAliases.size() == 1);
  ASSERT(config.addExecutableAliases.count("add_executable") == 1);

  filesystem::current_path(curDir);
}

TEST(ReadConfigurationFile)
{
  const filesystem::path tempDir = filesystem::unique_path(filesystem::temp_directory_path() / "%%%%%-%%%%%");
  ASSERT(filesystem::create_directories(tempDir));
  const filesystem::path curDir = filesystem::current_path();
  filesystem::current_path(tempDir);

  {
    streams::ofstream out(CONFIG_FILE);
    out << "versionUsed: 3\n"
        << "companyName: MyCompany\n"
        << "regenTag: MY_REGEN_TAG\n"
        << "cycleColor: brown\n"
        << "publicDepColor: black\n"
        << "privateDepColor: grey\n"
        << "componentLinkLimit: 2\n"
        << "componentLocLowerLimit: 1\n"
        << "componentLocUpperLimit: 123\n"
        << "fileLocUpperLimit: 567\n";
  }

  Configuration config;
  ASSERT(config.companyName == "MyCompany");
  ASSERT(config.regenTag == "MY_REGEN_TAG");
  ASSERT(config.versionUsed == "3");
  ASSERT(config.cycleColor == "brown");
  ASSERT(config.publicDepColor == "black");
  ASSERT(config.privateDepColor == "grey");
  ASSERT(config.componentLinkLimit == 2);
  ASSERT(config.componentLocLowerLimit == 1);
  ASSERT(config.componentLocUpperLimit == 123);
  ASSERT(config.fileLocUpperLimit == 567);
  ASSERT(config.addLibraryAliases.size() == 1);
  ASSERT(config.addLibraryAliases.count("add_library") == 1);
  ASSERT(config.addExecutableAliases.size() == 1);
  ASSERT(config.addExecutableAliases.count("add_executable") == 1);

  filesystem::current_path(curDir);
}

TEST(ReadConfigurationFile_Aliases)
{
  const filesystem::path tempDir = filesystem::unique_path(filesystem::temp_directory_path() / "%%%%%-%%%%%");
  ASSERT(filesystem::create_directories(tempDir));
  const filesystem::path curDir = filesystem::current_path();
  filesystem::current_path(tempDir);

  {
    streams::ofstream out(CONFIG_FILE);
    out << "addLibraryAlias: add_special_library\n"
        << "addLibraryAlias: add_test_lib\n"
        << "addExecutableAlias: add_special_exe\n"
        << "addExecutableAlias: add_test\n";
  }

  Configuration config;
  ASSERT(config.addLibraryAliases.size() == 3);
  ASSERT(config.addLibraryAliases.count("add_library") == 1);
  ASSERT(config.addLibraryAliases.count("add_special_library") == 1);
  ASSERT(config.addLibraryAliases.count("add_test_lib") == 1);

  ASSERT(config.addExecutableAliases.size() == 3);
  ASSERT(config.addExecutableAliases.count("add_executable") == 1);
  ASSERT(config.addExecutableAliases.count("add_special_exe") == 1);
  ASSERT(config.addExecutableAliases.count("add_test") == 1);

  filesystem::current_path(curDir);
}
<|endoftext|>


<commit_before><commit_msg>Override extension_action_redesign feature switch for Media Router. This approach temporarily and reversibly overrides the feature switch. The previous CL changed the feature switch for the lifetime of the process, which negatively impacted test isolation.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_test.h"

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/browser/sync/signin_manager.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/testing_pref_service.h"

class NewTabUITest : public UITest {
 public:
  NewTabUITest() {
    dom_automation_enabled_ = true;
    // Set home page to the empty string so that we can set the home page using
    // preferences.
    set_homepage("");

    // Setup the DEFAULT_THEME profile (has fake history entries).
    set_template_user_data(UITest::ComputeTypicalUserDataSource(
        ProxyLauncher::DEFAULT_THEME));
  }
};

TEST_F(NewTabUITest, NTPHasThumbnails) {
  // Switch to the "new tab" tab, which should be any new tab after the
  // first (the first is about:blank).
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // TopSites should return at least 3 non-filler pages.
  // 8 - 3 = max 5 filler pages.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('filler').length <= 5)",
      action_max_timeout_ms()));
}

TEST_F(NewTabUITest, NTPHasLoginName) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  ASSERT_TRUE(window->SetStringPreference(prefs::kGoogleServicesUsername,
                                          "user@gmail.com"));
  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  std::wstring displayed_username;
  // The login span should be eventually populated and have the
  // correct value.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText.length > 0)",
      action_max_timeout_ms()));

  ASSERT_TRUE(tab->ExecuteAndExtractString(
      L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText)",
      &displayed_username));

  EXPECT_EQ(L"user@gmail.com", displayed_username);
}

// Loads about:hang into two NTP tabs, ensuring we don't crash.
// See http://crbug.com/59859.
TEST_F(NewTabUITest, AboutHangInNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Navigate to about:hang to stall the process.
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kAboutHangURL)));

  // Visit about:hang again in another NTP.  Don't bother waiting for the
  // NTP to load, because it's hung.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab2 = window->GetActiveTab();
  ASSERT_TRUE(tab2.get());
  ASSERT_TRUE(tab2->NavigateToURLAsync(GURL(chrome::kAboutHangURL)));
}

// Fails about ~5% of the time on all platforms. http://crbug.com/45001
TEST_F(NewTabUITest, FLAKY_ChromeInternalLoadsNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Go to the "new tab page" using its old url, rather than chrome://newtab.
  scoped_refptr<TabProxy> tab = window->GetTab(0);
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL("chrome-internal:")));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Ensure there are some thumbnails loaded in the page.
  int thumbnails_count = -1;
  ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('thumbnail-container').length)",
      &thumbnails_count));
  EXPECT_GT(thumbnails_count, 0);
}

// Flaky on XP bots: http://crbug.com/51726
TEST_F(NewTabUITest, FLAKY_UpdateUserPrefsVersion) {
  // PrefService with JSON user-pref file only, no enforced or advised prefs.
  scoped_ptr<PrefService> prefs(new TestingPrefService);

  // Does the migration
  NewTabUI::RegisterUserPrefs(prefs.get());

  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  // Reset the version
  prefs->ClearPref(prefs::kNTPPrefVersion);
  ASSERT_EQ(0, prefs->GetInteger(prefs::kNTPPrefVersion));

  bool migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_TRUE(migrated);
  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_FALSE(migrated);
}
<commit_msg>Disable NewTabUITest.NTPHasLoginName as it sometimes hangs.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_test.h"

#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/browser/sync/signin_manager.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/testing_pref_service.h"

class NewTabUITest : public UITest {
 public:
  NewTabUITest() {
    dom_automation_enabled_ = true;
    // Set home page to the empty string so that we can set the home page using
    // preferences.
    set_homepage("");

    // Setup the DEFAULT_THEME profile (has fake history entries).
    set_template_user_data(UITest::ComputeTypicalUserDataSource(
        ProxyLauncher::DEFAULT_THEME));
  }
};

TEST_F(NewTabUITest, NTPHasThumbnails) {
  // Switch to the "new tab" tab, which should be any new tab after the
  // first (the first is about:blank).
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // TopSites should return at least 3 non-filler pages.
  // 8 - 3 = max 5 filler pages.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('filler').length <= 5)",
      action_max_timeout_ms()));
}

// Sometimes hangs: http://crbug.com/70157
TEST_F(NewTabUITest, DISABLED_NTPHasLoginName) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  ASSERT_TRUE(window->SetStringPreference(prefs::kGoogleServicesUsername,
                                          "user@gmail.com"));
  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  std::wstring displayed_username;
  // The login span should be eventually populated and have the
  // correct value.
  ASSERT_TRUE(WaitUntilJavaScriptCondition(tab, L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText.length > 0)",
      action_max_timeout_ms()));

  ASSERT_TRUE(tab->ExecuteAndExtractString(
      L"",
      L"window.domAutomationController.send("
      L"document.getElementById('login-username').innerText)",
      &displayed_username));

  EXPECT_EQ(L"user@gmail.com", displayed_username);
}

// Loads about:hang into two NTP tabs, ensuring we don't crash.
// See http://crbug.com/59859.
TEST_F(NewTabUITest, AboutHangInNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Bring up a new tab page.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));
  scoped_refptr<TabProxy> tab = window->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Navigate to about:hang to stall the process.
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL(chrome::kAboutHangURL)));

  // Visit about:hang again in another NTP.  Don't bother waiting for the
  // NTP to load, because it's hung.
  ASSERT_TRUE(window->RunCommand(IDC_NEW_TAB));
  scoped_refptr<TabProxy> tab2 = window->GetActiveTab();
  ASSERT_TRUE(tab2.get());
  ASSERT_TRUE(tab2->NavigateToURLAsync(GURL(chrome::kAboutHangURL)));
}

// Fails about ~5% of the time on all platforms. http://crbug.com/45001
TEST_F(NewTabUITest, FLAKY_ChromeInternalLoadsNTP) {
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(window.get());

  // Go to the "new tab page" using its old url, rather than chrome://newtab.
  scoped_refptr<TabProxy> tab = window->GetTab(0);
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURLAsync(GURL("chrome-internal:")));
  int load_time;
  ASSERT_TRUE(automation()->WaitForInitialNewTabUILoad(&load_time));

  // Ensure there are some thumbnails loaded in the page.
  int thumbnails_count = -1;
  ASSERT_TRUE(tab->ExecuteAndExtractInt(L"",
      L"window.domAutomationController.send("
      L"document.getElementsByClassName('thumbnail-container').length)",
      &thumbnails_count));
  EXPECT_GT(thumbnails_count, 0);
}

// Flaky on XP bots: http://crbug.com/51726
TEST_F(NewTabUITest, FLAKY_UpdateUserPrefsVersion) {
  // PrefService with JSON user-pref file only, no enforced or advised prefs.
  scoped_ptr<PrefService> prefs(new TestingPrefService);

  // Does the migration
  NewTabUI::RegisterUserPrefs(prefs.get());

  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  // Reset the version
  prefs->ClearPref(prefs::kNTPPrefVersion);
  ASSERT_EQ(0, prefs->GetInteger(prefs::kNTPPrefVersion));

  bool migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_TRUE(migrated);
  ASSERT_EQ(NewTabUI::current_pref_version(),
            prefs->GetInteger(prefs::kNTPPrefVersion));

  migrated = NewTabUI::UpdateUserPrefsVersion(prefs.get());
  ASSERT_FALSE(migrated);
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <sstream>
#include <string>

#include "build/build_config.h"
#if defined(OS_WIN)
#include <shlwapi.h>
#endif

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/platform_thread.h"
#include "base/string_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "chrome/browser/net/url_request_slow_download_job.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request_unittest.h"

namespace {

const wchar_t kDocRoot[] = L"chrome/test/data";

#if defined(OS_WIN)
// Checks if the volume supports Alternate Data Streams. This is required for
// the Zone Identifier implementation.
bool VolumeSupportsADS(const std::wstring path) {
  wchar_t drive[MAX_PATH] = {0};
  wcscpy_s(drive, MAX_PATH, path.c_str());

  EXPECT_TRUE(PathStripToRootW(drive));

  DWORD fs_flags = 0;
  EXPECT_TRUE(GetVolumeInformationW(drive, NULL, 0, 0, NULL, &fs_flags, NULL,
                                    0));

  if (fs_flags & FILE_NAMED_STREAMS)
    return true;

  return false;
}
#endif  // defined(OS_WIN)

class DownloadTest : public UITest {
 protected:
  DownloadTest() : UITest() {}

  void CleanUpDownload(const FilePath& client_filename,
                       const FilePath& server_filename) {
    // Find the path on the client.
    FilePath file_on_client = download_prefix_.Append(client_filename);
    EXPECT_TRUE(file_util::PathExists(file_on_client));

    // Find the path on the server.
    FilePath file_on_server;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA,
                                 &file_on_server));
    file_on_server = file_on_server.Append(server_filename);
    ASSERT_TRUE(file_util::PathExists(file_on_server));

    // Check that we downloaded the file correctly.
    EXPECT_TRUE(file_util::ContentsEqual(file_on_server,
                                         file_on_client));

#if defined(OS_WIN)
    // Check if the Zone Identifier is correctly set.
    if (VolumeSupportsADS(file_on_client.value()))
      CheckZoneIdentifier(file_on_client.value());
#endif

    // Delete the client copy of the file.
    EXPECT_TRUE(file_util::Delete(file_on_client, false));
  }

  void CleanUpDownload(const FilePath& file) {
    CleanUpDownload(file, file);
  }

  virtual void SetUp() {
    UITest::SetUp();
    download_prefix_ = GetDownloadDirectory();
  }

 protected:
  void RunSizeTest(const GURL& url,
                   const std::wstring& expected_title_in_progress,
                   const std::wstring& expected_title_finished) {
    {
      EXPECT_EQ(1, GetTabCount());

      NavigateToURL(url);
      // Downloads appear in the shelf
      WaitUntilTabCount(1);
      // TODO(tc): check download status text

      // Complete sending the request.  We do this by loading a second URL in a
      // separate tab.
      scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
      EXPECT_TRUE(window->AppendTab(GURL(
          URLRequestSlowDownloadJob::kFinishDownloadUrl)));
      EXPECT_EQ(2, GetTabCount());
      // TODO(tc): check download status text

      // Make sure the download shelf is showing.
      EXPECT_TRUE(WaitForDownloadShelfVisible(window.get()));
    }

    FilePath filename;
    net::FileURLToFilePath(url, &filename);
    filename = filename.BaseName();
    FilePath download_path = download_prefix_.Append(filename);
    EXPECT_TRUE(file_util::PathExists(download_path));

    // Delete the file we just downloaded.
    for (int i = 0; i < 10; ++i) {
      if (file_util::Delete(download_path, false))
        break;
      PlatformThread::Sleep(action_max_timeout_ms() / 10);
    }
    EXPECT_FALSE(file_util::PathExists(download_path));
  }

#if defined(OS_WIN)
  // Checks if the ZoneIdentifier is correctly set to "Internet" (3)
  void CheckZoneIdentifier(const std::wstring full_path) {
    std::wstring path = full_path + L":Zone.Identifier";

    // This polling and sleeping here is a very bad pattern. But due to how
    // Windows file semantics work it's really hard to do it other way. We are
    // reading a file written by a different process, using a different handle.
    // Windows does not guarantee that we will get the same contents even after
    // the other process closes the handle, flushes the buffers, etc.
    for (int i = 0; i < 20; i++) {
      PlatformThread::Sleep(sleep_timeout_ms());

      const DWORD kShare = FILE_SHARE_READ |
                           FILE_SHARE_WRITE |
                           FILE_SHARE_DELETE;
      HANDLE file = CreateFile(path.c_str(), GENERIC_READ, kShare, NULL,
                               OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
      if (file == INVALID_HANDLE_VALUE)
        continue;

      char buffer[100] = {0};
      DWORD read = 0;
      BOOL read_result = ReadFile(file, buffer, 100, &read, NULL);
      CloseHandle(file);

      if (!read_result)
        continue;

      const char kIdentifier[] = "[ZoneTransfer]\nZoneId=3";
      if (read != arraysize(kIdentifier))
        continue;

      if (strcmp(kIdentifier, buffer) == 0)
        return;
    }

    FAIL() << "Could not detect Internet ZoneIndentifier";
  }
#endif  // defined(OS_WIN)

  FilePath download_prefix_;
};

// Download a file with non-viewable content, verify that the
// download tab opened and the file exists.
TEST_F(DownloadTest, DownloadMimeType) {
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  // No new tabs created, downloads appear in the current tab's download shelf.
  WaitUntilTabCount(1);

  // Wait until the file is downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  CleanUpDownload(file);

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
}

// Access a file with a viewable mime-type, verify that a download
// did not initiate.
TEST_F(DownloadTest, NoDownload) {
  FilePath file(FILE_PATH_LITERAL("download-test2.html"));
  FilePath file_path = download_prefix_.Append(file);

  if (file_util::PathExists(file_path))
    ASSERT_TRUE(file_util::Delete(file_path, false));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  WaitUntilTabCount(1);

  // Wait to see if the file will be downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  EXPECT_FALSE(file_util::PathExists(file_path));
  if (file_util::PathExists(file_path))
    ASSERT_TRUE(file_util::Delete(file_path, false));

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_FALSE(WaitForDownloadShelfVisible(browser.get()));
}

// Download a 0-size file with a content-disposition header, verify that the
// download tab opened and the file exists as the filename specified in the
// header.  This also ensures we properly handle empty file downloads.
// See bug http://crbug.com/20809
TEST_F(DownloadTest, FLAKY_ContentDisposition) {
  FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
  FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  WaitUntilTabCount(1);

  // Wait until the file is downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  CleanUpDownload(download_file, file);

  // Ensure the download shelf is visible on the window.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
}

// Test that the download shelf is per-window by starting a download in one
// tab, opening a second tab, closing the shelf, going back to the first tab,
// and checking that the shelf is closed.
TEST_F(DownloadTest, PerWindowShelf) {
  FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
  FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  WaitUntilTabCount(1);

  // Wait until the file is downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  CleanUpDownload(download_file, file);

  // Ensure the download shelf is visible on the window.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));

  // Open a second tab
  browser->AppendTab(GURL());
  WaitUntilTabCount(2);

  // Hide shelf
  browser->SetShelfVisible(false);
  EXPECT_TRUE(WaitForDownloadShelfInvisible(browser.get()));

  // Go to first tab
  EXPECT_TRUE(browser->ActivateTab(0));
  int tab_count;
  EXPECT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  bool shelf_visible;
  EXPECT_TRUE(browser->IsShelfVisible(&shelf_visible));
  ASSERT_FALSE(shelf_visible);
}

// UnknownSize and KnownSize are tests which depend on
// URLRequestSlowDownloadJob to serve content in a certain way. Data will be
// sent in two chunks where the first chunk is 35K and the second chunk is 10K.
// The test will first attempt to download a file; but the server will "pause"
// in the middle until the server receives a second request for
// "download-finish.  At that time, the download will finish.
// Flaky on Linux: http://code.google.com/p/chromium/issues/detail?id=14746
TEST_F(DownloadTest, UnknownSize) {
  GURL url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
  FilePath filename;
  net::FileURLToFilePath(url, &filename);
  filename = filename.BaseName();
  RunSizeTest(url, L"32.0 KB - " + filename.ToWStringHack(),
              L"100% - " + filename.ToWStringHack());
}

// http://b/1158253
TEST_F(DownloadTest, DISABLED_KnownSize) {
  GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);
  FilePath filename;
  net::FileURLToFilePath(url, &filename);
  filename = filename.BaseName();
  RunSizeTest(url, L"71% - " + filename.ToWStringHack(),
              L"100% - " + filename.ToWStringHack());
}

// Test that when downloading an item in Incognito mode, we don't crash when
// closing the last Incognito window (http://crbug.com/13983).
TEST_F(DownloadTest, IncognitoDownload) {
  // Open a regular window and sanity check default values for window / tab
  // count and shelf visibility.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  int window_count = 0;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(1, window_count);
  EXPECT_EQ(1, GetTabCount());
  bool is_shelf_visible;
  browser->IsShelfVisible(&is_shelf_visible);
  EXPECT_FALSE(is_shelf_visible);

  // Open an Incognito window.
  ASSERT_TRUE(browser->RunCommand(IDC_NEW_INCOGNITO_WINDOW));
  scoped_refptr<BrowserProxy> incognito(automation()->GetBrowserWindow(1));
  scoped_refptr<TabProxy> tab(incognito->GetTab(0));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(2, window_count);

  // Download something.
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
  //PlatformThread::Sleep(1000);
  ASSERT_TRUE(tab->NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file)));
  PlatformThread::Sleep(action_timeout_ms());

  // Verify that the download shelf is showing for the Incognito window.
  EXPECT_TRUE(WaitForDownloadShelfVisible(incognito.get()));

  // Close the Incognito window and don't crash.
  ASSERT_TRUE(incognito->RunCommand(IDC_CLOSE_WINDOW));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(1, window_count);

  // Verify that the regular window does not have a download shelf.
  browser->IsShelfVisible(&is_shelf_visible);
  EXPECT_FALSE(is_shelf_visible);

  CleanUpDownload(file);
}

}  // namespace
<commit_msg>Disable DownloadTest.PerWindowShelf because of flakiness.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <sstream>
#include <string>

#include "build/build_config.h"
#if defined(OS_WIN)
#include <shlwapi.h>
#endif

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/platform_thread.h"
#include "base/string_util.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/net/url_request_mock_http_job.h"
#include "chrome/browser/net/url_request_slow_download_job.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request_unittest.h"

namespace {

const wchar_t kDocRoot[] = L"chrome/test/data";

#if defined(OS_WIN)
// Checks if the volume supports Alternate Data Streams. This is required for
// the Zone Identifier implementation.
bool VolumeSupportsADS(const std::wstring path) {
  wchar_t drive[MAX_PATH] = {0};
  wcscpy_s(drive, MAX_PATH, path.c_str());

  EXPECT_TRUE(PathStripToRootW(drive));

  DWORD fs_flags = 0;
  EXPECT_TRUE(GetVolumeInformationW(drive, NULL, 0, 0, NULL, &fs_flags, NULL,
                                    0));

  if (fs_flags & FILE_NAMED_STREAMS)
    return true;

  return false;
}
#endif  // defined(OS_WIN)

class DownloadTest : public UITest {
 protected:
  DownloadTest() : UITest() {}

  void CleanUpDownload(const FilePath& client_filename,
                       const FilePath& server_filename) {
    // Find the path on the client.
    FilePath file_on_client = download_prefix_.Append(client_filename);
    EXPECT_TRUE(file_util::PathExists(file_on_client));

    // Find the path on the server.
    FilePath file_on_server;
    ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA,
                                 &file_on_server));
    file_on_server = file_on_server.Append(server_filename);
    ASSERT_TRUE(file_util::PathExists(file_on_server));

    // Check that we downloaded the file correctly.
    EXPECT_TRUE(file_util::ContentsEqual(file_on_server,
                                         file_on_client));

#if defined(OS_WIN)
    // Check if the Zone Identifier is correctly set.
    if (VolumeSupportsADS(file_on_client.value()))
      CheckZoneIdentifier(file_on_client.value());
#endif

    // Delete the client copy of the file.
    EXPECT_TRUE(file_util::Delete(file_on_client, false));
  }

  void CleanUpDownload(const FilePath& file) {
    CleanUpDownload(file, file);
  }

  virtual void SetUp() {
    UITest::SetUp();
    download_prefix_ = GetDownloadDirectory();
  }

 protected:
  void RunSizeTest(const GURL& url,
                   const std::wstring& expected_title_in_progress,
                   const std::wstring& expected_title_finished) {
    {
      EXPECT_EQ(1, GetTabCount());

      NavigateToURL(url);
      // Downloads appear in the shelf
      WaitUntilTabCount(1);
      // TODO(tc): check download status text

      // Complete sending the request.  We do this by loading a second URL in a
      // separate tab.
      scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
      EXPECT_TRUE(window->AppendTab(GURL(
          URLRequestSlowDownloadJob::kFinishDownloadUrl)));
      EXPECT_EQ(2, GetTabCount());
      // TODO(tc): check download status text

      // Make sure the download shelf is showing.
      EXPECT_TRUE(WaitForDownloadShelfVisible(window.get()));
    }

    FilePath filename;
    net::FileURLToFilePath(url, &filename);
    filename = filename.BaseName();
    FilePath download_path = download_prefix_.Append(filename);
    EXPECT_TRUE(file_util::PathExists(download_path));

    // Delete the file we just downloaded.
    for (int i = 0; i < 10; ++i) {
      if (file_util::Delete(download_path, false))
        break;
      PlatformThread::Sleep(action_max_timeout_ms() / 10);
    }
    EXPECT_FALSE(file_util::PathExists(download_path));
  }

#if defined(OS_WIN)
  // Checks if the ZoneIdentifier is correctly set to "Internet" (3)
  void CheckZoneIdentifier(const std::wstring full_path) {
    std::wstring path = full_path + L":Zone.Identifier";

    // This polling and sleeping here is a very bad pattern. But due to how
    // Windows file semantics work it's really hard to do it other way. We are
    // reading a file written by a different process, using a different handle.
    // Windows does not guarantee that we will get the same contents even after
    // the other process closes the handle, flushes the buffers, etc.
    for (int i = 0; i < 20; i++) {
      PlatformThread::Sleep(sleep_timeout_ms());

      const DWORD kShare = FILE_SHARE_READ |
                           FILE_SHARE_WRITE |
                           FILE_SHARE_DELETE;
      HANDLE file = CreateFile(path.c_str(), GENERIC_READ, kShare, NULL,
                               OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
      if (file == INVALID_HANDLE_VALUE)
        continue;

      char buffer[100] = {0};
      DWORD read = 0;
      BOOL read_result = ReadFile(file, buffer, 100, &read, NULL);
      CloseHandle(file);

      if (!read_result)
        continue;

      const char kIdentifier[] = "[ZoneTransfer]\nZoneId=3";
      if (read != arraysize(kIdentifier))
        continue;

      if (strcmp(kIdentifier, buffer) == 0)
        return;
    }

    FAIL() << "Could not detect Internet ZoneIndentifier";
  }
#endif  // defined(OS_WIN)

  FilePath download_prefix_;
};

// Download a file with non-viewable content, verify that the
// download tab opened and the file exists.
TEST_F(DownloadTest, DownloadMimeType) {
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  // No new tabs created, downloads appear in the current tab's download shelf.
  WaitUntilTabCount(1);

  // Wait until the file is downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  CleanUpDownload(file);

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
}

// Access a file with a viewable mime-type, verify that a download
// did not initiate.
TEST_F(DownloadTest, NoDownload) {
  FilePath file(FILE_PATH_LITERAL("download-test2.html"));
  FilePath file_path = download_prefix_.Append(file);

  if (file_util::PathExists(file_path))
    ASSERT_TRUE(file_util::Delete(file_path, false));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  WaitUntilTabCount(1);

  // Wait to see if the file will be downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  EXPECT_FALSE(file_util::PathExists(file_path));
  if (file_util::PathExists(file_path))
    ASSERT_TRUE(file_util::Delete(file_path, false));

  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_FALSE(WaitForDownloadShelfVisible(browser.get()));
}

// Download a 0-size file with a content-disposition header, verify that the
// download tab opened and the file exists as the filename specified in the
// header.  This also ensures we properly handle empty file downloads.
// See bug http://crbug.com/20809
TEST_F(DownloadTest, FLAKY_ContentDisposition) {
  FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
  FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  WaitUntilTabCount(1);

  // Wait until the file is downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  CleanUpDownload(download_file, file);

  // Ensure the download shelf is visible on the window.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));
}

// Test that the download shelf is per-window by starting a download in one
// tab, opening a second tab, closing the shelf, going back to the first tab,
// and checking that the shelf is closed.
// See bug http://crbug.com/26325
TEST_F(DownloadTest, FLAKY_PerWindowShelf) {
  FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
  FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));

  EXPECT_EQ(1, GetTabCount());

  NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file));
  WaitUntilTabCount(1);

  // Wait until the file is downloaded.
  PlatformThread::Sleep(action_timeout_ms());

  CleanUpDownload(download_file, file);

  // Ensure the download shelf is visible on the window.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());
  EXPECT_TRUE(WaitForDownloadShelfVisible(browser.get()));

  // Open a second tab
  browser->AppendTab(GURL());
  WaitUntilTabCount(2);

  // Hide shelf
  browser->SetShelfVisible(false);
  EXPECT_TRUE(WaitForDownloadShelfInvisible(browser.get()));

  // Go to first tab
  EXPECT_TRUE(browser->ActivateTab(0));
  int tab_count;
  EXPECT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  bool shelf_visible;
  EXPECT_TRUE(browser->IsShelfVisible(&shelf_visible));
  ASSERT_FALSE(shelf_visible);
}

// UnknownSize and KnownSize are tests which depend on
// URLRequestSlowDownloadJob to serve content in a certain way. Data will be
// sent in two chunks where the first chunk is 35K and the second chunk is 10K.
// The test will first attempt to download a file; but the server will "pause"
// in the middle until the server receives a second request for
// "download-finish.  At that time, the download will finish.
// Flaky on Linux: http://code.google.com/p/chromium/issues/detail?id=14746
TEST_F(DownloadTest, UnknownSize) {
  GURL url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
  FilePath filename;
  net::FileURLToFilePath(url, &filename);
  filename = filename.BaseName();
  RunSizeTest(url, L"32.0 KB - " + filename.ToWStringHack(),
              L"100% - " + filename.ToWStringHack());
}

// http://b/1158253
TEST_F(DownloadTest, DISABLED_KnownSize) {
  GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl);
  FilePath filename;
  net::FileURLToFilePath(url, &filename);
  filename = filename.BaseName();
  RunSizeTest(url, L"71% - " + filename.ToWStringHack(),
              L"100% - " + filename.ToWStringHack());
}

// Test that when downloading an item in Incognito mode, we don't crash when
// closing the last Incognito window (http://crbug.com/13983).
TEST_F(DownloadTest, IncognitoDownload) {
  // Open a regular window and sanity check default values for window / tab
  // count and shelf visibility.
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  int window_count = 0;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(1, window_count);
  EXPECT_EQ(1, GetTabCount());
  bool is_shelf_visible;
  browser->IsShelfVisible(&is_shelf_visible);
  EXPECT_FALSE(is_shelf_visible);

  // Open an Incognito window.
  ASSERT_TRUE(browser->RunCommand(IDC_NEW_INCOGNITO_WINDOW));
  scoped_refptr<BrowserProxy> incognito(automation()->GetBrowserWindow(1));
  scoped_refptr<TabProxy> tab(incognito->GetTab(0));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(2, window_count);

  // Download something.
  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
  //PlatformThread::Sleep(1000);
  ASSERT_TRUE(tab->NavigateToURL(URLRequestMockHTTPJob::GetMockUrl(file)));
  PlatformThread::Sleep(action_timeout_ms());

  // Verify that the download shelf is showing for the Incognito window.
  EXPECT_TRUE(WaitForDownloadShelfVisible(incognito.get()));

  // Close the Incognito window and don't crash.
  ASSERT_TRUE(incognito->RunCommand(IDC_CLOSE_WINDOW));
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(1, window_count);

  // Verify that the regular window does not have a download shelf.
  browser->IsShelfVisible(&is_shelf_visible);
  EXPECT_FALSE(is_shelf_visible);

  CleanUpDownload(file);
}

}  // namespace
<|endoftext|>


<commit_before>#include "settings.h"
#include "deviceinfo.h"
#include "log/logger.h"

#include <QSettings>

LOGGER(Settings);

class Settings::Private
{
public:
    void sync();

    GetConfigResponse config;
    QSettings settings;
};

void Settings::Private::sync()
{
    settings.setValue("config", config.toVariant());
    settings.sync();
}

Settings::Settings(QObject *parent)
: QObject(parent)
, d(new Private)
{
}

Settings::~Settings()
{
    d->sync();
    delete d;
}

Settings::StorageType Settings::init()
{
    bool newSettings = deviceId().isNull();

    DeviceInfo info;
    setDeviceId(info.deviceId());

    LOG_INFO(QString("Device ID: %1").arg(deviceId()));

    // Create new settings
    if ( newSettings )
    {
        d->config.setControllerAddress("141.82.51.240:5105");
        LOG_INFO("Created new settings for this device");

        return NewSettings;
    }
    else
    {
        d->config.fillFromVariant( qvariant_cast<QVariantMap>(d->settings.value("config")) );

        // Always set the controller address if we have none
        if (d->config.controllerAddress().isEmpty())
        {
            LOG_WARNING("Controller address lost, setting back default one");
            d->config.setControllerAddress("141.82.51.240:5105");
        }

        LOG_INFO("Loaded existing settings for this device");
        return ExistingSettings;
    }
}

bool Settings::hasLoginData() const
{
    return !userId().isEmpty() && !password().isEmpty();
}

void Settings::setDeviceId(const QString &deviceId)
{
    if ( this->deviceId() != deviceId )
    {
        d->settings.setValue("device-id", deviceId);
        emit deviceIdChanged(deviceId);
    }
}

QString Settings::deviceId() const
{
    return d->settings.value("device-id").toString();
}

void Settings::setUserId(const QString &userId)
{
    if ( this->userId() != userId )
    {
        d->settings.setValue("user-id", userId);
        emit userIdChanged(userId);
    }
}

QString Settings::userId() const
{
    return d->settings.value("user-id").toString();
}

void Settings::setPassword(const QString &password)
{
    if ( this->password() != password )
    {
        d->settings.setValue("password", password);
        emit passwordChanged(password);
    }
}

QString Settings::password() const
{
    return d->settings.value("password").toString();
}

void Settings::setSessionId(const QString &sessionId)
{
    if ( this->sessionId() != sessionId )
    {
        d->settings.setValue("session-id", sessionId);
        emit sessionIdChanged(sessionId);
    }
}

QString Settings::sessionId() const
{
    return d->settings.value("session-id").toString();
}

bool Settings::isPassive() const
{
    return d->settings.value("passive").toBool();
}

void Settings::setPassive(bool passive)
{
    if ( this->isPassive() != passive )
    {
        d->settings.setValue("passive", passive);
        emit passiveChanged(passive);
    }
}

GetConfigResponse *Settings::config() const
{
    return &d->config;
}

void Settings::sync()
{
    d->sync();
}
<commit_msg>Fallback device ids<commit_after>#include "settings.h"
#include "deviceinfo.h"
#include "log/logger.h"

#include <QSettings>
#include <QCryptographicHash>

LOGGER(Settings);

class Settings::Private
{
public:
    void sync();

    GetConfigResponse config;
    QSettings settings;
};

void Settings::Private::sync()
{
    settings.setValue("config", config.toVariant());
    settings.sync();
}

Settings::Settings(QObject *parent)
: QObject(parent)
, d(new Private)
{
}

Settings::~Settings()
{
    d->sync();
    delete d;
}

Settings::StorageType Settings::init()
{
    bool newSettings = deviceId().isNull();

    DeviceInfo info;

    QString generatedDeviceId = info.deviceId();
    if (generatedDeviceId.isEmpty())
    {
        if (deviceId().isEmpty())
        {
            QCryptographicHash hash(QCryptographicHash::Sha224);
            hash.addData( QUuid::createUuid().toByteArray() );

            setDeviceId(QString::fromLatin1(hash.result().toHex()));

            LOG_INFO("Generated fallback device ID");
        }
        else
        {
            LOG_INFO("Took fallback device ID from config");
        }
    }
    else
    {
        setDeviceId(info.deviceId());
    }

    LOG_INFO(QString("Device ID: %1").arg(deviceId()));

    // Create new settings
    if ( newSettings )
    {
        d->config.setControllerAddress("141.82.51.240:5105");
        LOG_INFO("Created new settings for this device");

        return NewSettings;
    }
    else
    {
        d->config.fillFromVariant( qvariant_cast<QVariantMap>(d->settings.value("config")) );

        // Always set the controller address if we have none
        if (d->config.controllerAddress().isEmpty())
        {
            LOG_WARNING("Controller address lost, setting back default one");
            d->config.setControllerAddress("141.82.51.240:5105");
        }

        LOG_INFO("Loaded existing settings for this device");
        return ExistingSettings;
    }
}

bool Settings::hasLoginData() const
{
    return !userId().isEmpty() && !password().isEmpty();
}

void Settings::setDeviceId(const QString &deviceId)
{
    if ( this->deviceId() != deviceId )
    {
        d->settings.setValue("device-id", deviceId);
        emit deviceIdChanged(deviceId);
    }
}

QString Settings::deviceId() const
{
    return d->settings.value("device-id").toString();
}

void Settings::setUserId(const QString &userId)
{
    if ( this->userId() != userId )
    {
        d->settings.setValue("user-id", userId);
        emit userIdChanged(userId);
    }
}

QString Settings::userId() const
{
    return d->settings.value("user-id").toString();
}

void Settings::setPassword(const QString &password)
{
    if ( this->password() != password )
    {
        d->settings.setValue("password", password);
        emit passwordChanged(password);
    }
}

QString Settings::password() const
{
    return d->settings.value("password").toString();
}

void Settings::setSessionId(const QString &sessionId)
{
    if ( this->sessionId() != sessionId )
    {
        d->settings.setValue("session-id", sessionId);
        emit sessionIdChanged(sessionId);
    }
}

QString Settings::sessionId() const
{
    return d->settings.value("session-id").toString();
}

bool Settings::isPassive() const
{
    return d->settings.value("passive").toBool();
}

void Settings::setPassive(bool passive)
{
    if ( this->isPassive() != passive )
    {
        d->settings.setValue("passive", passive);
        emit passiveChanged(passive);
    }
}

GetConfigResponse *Settings::config() const
{
    return &d->config;
}

void Settings::sync()
{
    d->sync();
}
<|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 "ui/base/win/window_impl.h"

#include <list>

#include "base/debug/alias.h"
#include "base/memory/singleton.h"
#include "base/string_number_conversions.h"
#include "base/win/wrapped_window_proc.h"
#include "ui/base/win/hwnd_util.h"

namespace {

extern "C" {
  typedef HWND (*GetRootWindow)();
}

HMODULE GetMetroDll() {
  static HMODULE hm = ::GetModuleHandleA("metro_driver.dll");
  return hm;
}

HWND RootWindow(bool is_child_window) {
  HMODULE metro = GetMetroDll();
  if (!metro) {
    return is_child_window ? ::GetDesktopWindow() : HWND_DESKTOP;
  }
  GetRootWindow get_root_window =
      reinterpret_cast<GetRootWindow>(::GetProcAddress(metro, "GetRootWindow"));
  return get_root_window();
}

}  // namespace

namespace ui {

static const DWORD kWindowDefaultChildStyle =
    WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
static const DWORD kWindowDefaultStyle = WS_OVERLAPPEDWINDOW;
static const DWORD kWindowDefaultExStyle = 0;

///////////////////////////////////////////////////////////////////////////////
// WindowImpl class tracking.

// Several external scripts rely explicitly on this base class name for
// acquiring the window handle and will break if this is modified!
// static
const wchar_t* const WindowImpl::kBaseClassName = L"Chrome_WidgetWin_";

// WindowImpl class information used for registering unique windows.
struct ClassInfo {
  UINT style;
  HICON icon;

  ClassInfo(int style, HICON icon)
      : style(style),
        icon(icon) {}

  // Compares two ClassInfos. Returns true if all members match.
  bool Equals(const ClassInfo& other) const {
    return (other.style == style && other.icon == icon);
  }
};

class ClassRegistrar {
 public:
  static ClassRegistrar* GetInstance() {
    return Singleton<ClassRegistrar>::get();
  }

  ~ClassRegistrar() {
    for (RegisteredClasses::iterator i = registered_classes_.begin();
         i != registered_classes_.end(); ++i) {
      if (!UnregisterClass(i->name.c_str(), NULL)) {
        LOG(ERROR) << "Failed to unregister class " << i->name.c_str()
                   << ". Error = " << GetLastError();
      }
    }
  }

  // Puts the name for the class matching |class_info| in |class_name|, creating
  // a new name if the class is not yet known.
  // Returns true if this class was already known, false otherwise.
  bool RetrieveClassName(const ClassInfo& class_info, std::wstring* name) {
    for (RegisteredClasses::const_iterator i = registered_classes_.begin();
         i != registered_classes_.end(); ++i) {
      if (class_info.Equals(i->info)) {
        name->assign(i->name);
        return true;
      }
    }

    name->assign(string16(WindowImpl::kBaseClassName) +
        base::IntToString16(registered_count_++));
    return false;
  }

  void RegisterClass(const ClassInfo& class_info,
                     const std::wstring& name,
                     ATOM atom) {
    registered_classes_.push_back(RegisteredClass(class_info, name, atom));
  }

 private:
  // Represents a registered window class.
  struct RegisteredClass {
    RegisteredClass(const ClassInfo& info,
                    const std::wstring& name,
                    ATOM atom)
        : info(info),
          name(name),
          atom(atom) {
    }

    // Info used to create the class.
    ClassInfo info;

    // The name given to the window.
    std::wstring name;

    // The ATOM returned from creating the window.
    ATOM atom;
  };

  ClassRegistrar() : registered_count_(0) { }
  friend struct DefaultSingletonTraits<ClassRegistrar>;

  typedef std::list<RegisteredClass> RegisteredClasses;
  RegisteredClasses registered_classes_;

  // Counter of how many classes have been registered so far.
  int registered_count_;

  DISALLOW_COPY_AND_ASSIGN(ClassRegistrar);
};

///////////////////////////////////////////////////////////////////////////////
// WindowImpl, public

WindowImpl::WindowImpl()
    : window_style_(0),
      window_ex_style_(kWindowDefaultExStyle),
      class_style_(CS_DBLCLKS),
      hwnd_(NULL),
      got_create_(false),
      got_valid_hwnd_(false),
      destroyed_(NULL) {
}

WindowImpl::~WindowImpl() {
  if (destroyed_)
    *destroyed_ = true;
  if (::IsWindow(hwnd_))
    ui::SetWindowUserData(hwnd_, NULL);
}

void WindowImpl::Init(HWND parent, const gfx::Rect& bounds) {
  if (window_style_ == 0)
    window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle;

  if (parent == HWND_DESKTOP) {
    // Only non-child windows can have HWND_DESKTOP (0) as their parent.
    CHECK((window_style_ & WS_CHILD) == 0);
    parent = RootWindow(false);
  } else if (parent == ::GetDesktopWindow()) {
    // Any type of window can have the "Desktop Window" as their parent.
    parent = RootWindow(true);
  } else if (parent != HWND_MESSAGE) {
    CHECK(::IsWindow(parent));
  }

  int x, y, width, height;
  if (bounds.IsEmpty()) {
    x = y = width = height = CW_USEDEFAULT;
  } else {
    x = bounds.x();
    y = bounds.y();
    width = bounds.width();
    height = bounds.height();
  }

  std::wstring name(GetWindowClassName());
  bool destroyed = false;
  destroyed_ = &destroyed;
  HWND hwnd = CreateWindowEx(window_ex_style_, name.c_str(), NULL,
                             window_style_, x, y, width, height,
                             parent, NULL, NULL, this);
  if (!hwnd_) {
    base::debug::Alias(&destroyed);
    base::debug::Alias(&hwnd);
    DWORD last_error = GetLastError();
    base::debug::Alias(&last_error);
    bool got_create = got_create_;
    base::debug::Alias(&got_create);
    bool got_valid_hwnd = got_valid_hwnd_;
    base::debug::Alias(&got_valid_hwnd);
    CHECK(false);
  }
  if (!destroyed)
    destroyed_ = NULL;

  // The window procedure should have set the data for us.
  CHECK_EQ(this, ui::GetWindowUserData(hwnd));
}

HICON WindowImpl::GetDefaultWindowIcon() const {
  return NULL;
}

LRESULT WindowImpl::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) {
  LRESULT result = 0;

  // Handle the message if it's in our message map; otherwise, let the system
  // handle it.
  if (!ProcessWindowMessage(hwnd_, message, w_param, l_param, result))
    result = DefWindowProc(hwnd_, message, w_param, l_param);

  return result;
}

// static
LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd,
                                     UINT message,
                                     WPARAM w_param,
                                     LPARAM l_param) {
  if (message == WM_NCCREATE) {
    CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param);
    WindowImpl* window = reinterpret_cast<WindowImpl*>(cs->lpCreateParams);
    DCHECK(window);
    ui::SetWindowUserData(hwnd, window);
    window->hwnd_ = hwnd;
    window->got_create_ = true;
    if (hwnd)
      window->got_valid_hwnd_ = true;
    return TRUE;
  }

  WindowImpl* window = reinterpret_cast<WindowImpl*>(
      ui::GetWindowUserData(hwnd));
  if (!window)
    return 0;

  return window->OnWndProc(message, w_param, l_param);
}

std::wstring WindowImpl::GetWindowClassName() {
  HICON icon = GetDefaultWindowIcon();
  ClassInfo class_info(initial_class_style(), icon);
  std::wstring name;
  if (ClassRegistrar::GetInstance()->RetrieveClassName(class_info, &name))
    return name;

  // No class found, need to register one.
  HBRUSH background = NULL;
  WNDCLASSEX class_ex = {
    sizeof(WNDCLASSEX),
    class_info.style,
    base::win::WrappedWindowProc<&WindowImpl::WndProc>,
    0,
    0,
    NULL,
    icon,
    NULL,
    reinterpret_cast<HBRUSH>(background + 1),
    NULL,
    name.c_str(),
    icon
  };
  ATOM atom = RegisterClassEx(&class_ex);
  CHECK(atom) << GetLastError();

  ClassRegistrar::GetInstance()->RegisterClass(class_info, name, atom);

  return name;
}

}  // namespace ui
<commit_msg>Adds more debugging code to WindowImpl. Crash data seems to indicate the wndproc isn't getting called at all for this window. I'm curious to see if our windowproc is no longer registered. I'm also changing the HINSTNACE argument to RegisterClassEx to actually pass in a module.<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 "ui/base/win/window_impl.h"

#include <list>

#include "base/debug/alias.h"
#include "base/memory/singleton.h"
#include "base/string_number_conversions.h"
#include "base/win/wrapped_window_proc.h"
#include "ui/base/win/hwnd_util.h"

namespace {

extern "C" {
  typedef HWND (*GetRootWindow)();
}

HMODULE GetMetroDll() {
  static HMODULE hm = ::GetModuleHandleA("metro_driver.dll");
  return hm;
}

HWND RootWindow(bool is_child_window) {
  HMODULE metro = GetMetroDll();
  if (!metro) {
    return is_child_window ? ::GetDesktopWindow() : HWND_DESKTOP;
  }
  GetRootWindow get_root_window =
      reinterpret_cast<GetRootWindow>(::GetProcAddress(metro, "GetRootWindow"));
  return get_root_window();
}

}  // namespace

namespace ui {

static const DWORD kWindowDefaultChildStyle =
    WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
static const DWORD kWindowDefaultStyle = WS_OVERLAPPEDWINDOW;
static const DWORD kWindowDefaultExStyle = 0;

///////////////////////////////////////////////////////////////////////////////
// WindowImpl class tracking.

// Several external scripts rely explicitly on this base class name for
// acquiring the window handle and will break if this is modified!
// static
const wchar_t* const WindowImpl::kBaseClassName = L"Chrome_WidgetWin_";

// WindowImpl class information used for registering unique windows.
struct ClassInfo {
  UINT style;
  HICON icon;

  ClassInfo(int style, HICON icon)
      : style(style),
        icon(icon) {}

  // Compares two ClassInfos. Returns true if all members match.
  bool Equals(const ClassInfo& other) const {
    return (other.style == style && other.icon == icon);
  }
};

class ClassRegistrar {
 public:
  static ClassRegistrar* GetInstance() {
    return Singleton<ClassRegistrar>::get();
  }

  ~ClassRegistrar() {
    for (RegisteredClasses::iterator i = registered_classes_.begin();
         i != registered_classes_.end(); ++i) {
      if (!UnregisterClass(i->name.c_str(), NULL)) {
        LOG(ERROR) << "Failed to unregister class " << i->name.c_str()
                   << ". Error = " << GetLastError();
      }
    }
  }

  // Puts the name for the class matching |class_info| in |class_name|, creating
  // a new name if the class is not yet known.
  // Returns true if this class was already known, false otherwise.
  bool RetrieveClassName(const ClassInfo& class_info, std::wstring* name) {
    for (RegisteredClasses::const_iterator i = registered_classes_.begin();
         i != registered_classes_.end(); ++i) {
      if (class_info.Equals(i->info)) {
        name->assign(i->name);
        return true;
      }
    }

    name->assign(string16(WindowImpl::kBaseClassName) +
        base::IntToString16(registered_count_++));
    return false;
  }

  void RegisterClass(const ClassInfo& class_info,
                     const std::wstring& name,
                     ATOM atom) {
    registered_classes_.push_back(RegisteredClass(class_info, name, atom));
  }

 private:
  // Represents a registered window class.
  struct RegisteredClass {
    RegisteredClass(const ClassInfo& info,
                    const std::wstring& name,
                    ATOM atom)
        : info(info),
          name(name),
          atom(atom) {
    }

    // Info used to create the class.
    ClassInfo info;

    // The name given to the window.
    std::wstring name;

    // The ATOM returned from creating the window.
    ATOM atom;
  };

  ClassRegistrar() : registered_count_(0) { }
  friend struct DefaultSingletonTraits<ClassRegistrar>;

  typedef std::list<RegisteredClass> RegisteredClasses;
  RegisteredClasses registered_classes_;

  // Counter of how many classes have been registered so far.
  int registered_count_;

  DISALLOW_COPY_AND_ASSIGN(ClassRegistrar);
};

///////////////////////////////////////////////////////////////////////////////
// WindowImpl, public

WindowImpl::WindowImpl()
    : window_style_(0),
      window_ex_style_(kWindowDefaultExStyle),
      class_style_(CS_DBLCLKS),
      hwnd_(NULL),
      got_create_(false),
      got_valid_hwnd_(false),
      destroyed_(NULL) {
}

WindowImpl::~WindowImpl() {
  if (destroyed_)
    *destroyed_ = true;
  if (::IsWindow(hwnd_))
    ui::SetWindowUserData(hwnd_, NULL);
}

void WindowImpl::Init(HWND parent, const gfx::Rect& bounds) {
  if (window_style_ == 0)
    window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle;

  if (parent == HWND_DESKTOP) {
    // Only non-child windows can have HWND_DESKTOP (0) as their parent.
    CHECK((window_style_ & WS_CHILD) == 0);
    parent = RootWindow(false);
  } else if (parent == ::GetDesktopWindow()) {
    // Any type of window can have the "Desktop Window" as their parent.
    parent = RootWindow(true);
  } else if (parent != HWND_MESSAGE) {
    CHECK(::IsWindow(parent));
  }

  int x, y, width, height;
  if (bounds.IsEmpty()) {
    x = y = width = height = CW_USEDEFAULT;
  } else {
    x = bounds.x();
    y = bounds.y();
    width = bounds.width();
    height = bounds.height();
  }

  std::wstring name(GetWindowClassName());
  bool destroyed = false;
  destroyed_ = &destroyed;
  HWND hwnd = CreateWindowEx(window_ex_style_, name.c_str(), NULL,
                             window_style_, x, y, width, height,
                             parent, NULL, NULL, this);
  if (!hwnd_ && GetLastError() == 0) {
    base::debug::Alias(&destroyed);
    base::debug::Alias(&hwnd);
    bool got_create = got_create_;
    base::debug::Alias(&got_create);
    bool got_valid_hwnd = got_valid_hwnd_;
    base::debug::Alias(&got_valid_hwnd);
    WNDCLASSEX class_info;
    memset(&class_info, 0, sizeof(WNDCLASSEX));
    class_info.cbSize = sizeof(WNDCLASSEX);
    BOOL got_class = GetClassInfoEx(
        GetModuleHandle(NULL), name.c_str(), &class_info);
    base::debug::Alias(&got_class);
    bool procs_match = got_class && class_info.lpfnWndProc ==
        base::win::WrappedWindowProc<&WindowImpl::WndProc>;
    base::debug::Alias(&procs_match);
    CHECK(false);
  }
  if (!destroyed)
    destroyed_ = NULL;

  CheckWindowCreated(hwnd_);

  // The window procedure should have set the data for us.
  CHECK_EQ(this, ui::GetWindowUserData(hwnd));
}

HICON WindowImpl::GetDefaultWindowIcon() const {
  return NULL;
}

LRESULT WindowImpl::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) {
  LRESULT result = 0;

  // Handle the message if it's in our message map; otherwise, let the system
  // handle it.
  if (!ProcessWindowMessage(hwnd_, message, w_param, l_param, result))
    result = DefWindowProc(hwnd_, message, w_param, l_param);

  return result;
}

// static
LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd,
                                     UINT message,
                                     WPARAM w_param,
                                     LPARAM l_param) {
  if (message == WM_NCCREATE) {
    CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param);
    WindowImpl* window = reinterpret_cast<WindowImpl*>(cs->lpCreateParams);
    DCHECK(window);
    ui::SetWindowUserData(hwnd, window);
    window->hwnd_ = hwnd;
    window->got_create_ = true;
    if (hwnd)
      window->got_valid_hwnd_ = true;
    return TRUE;
  }

  WindowImpl* window = reinterpret_cast<WindowImpl*>(
      ui::GetWindowUserData(hwnd));
  if (!window)
    return 0;

  return window->OnWndProc(message, w_param, l_param);
}

std::wstring WindowImpl::GetWindowClassName() {
  HICON icon = GetDefaultWindowIcon();
  ClassInfo class_info(initial_class_style(), icon);
  std::wstring name;
  if (ClassRegistrar::GetInstance()->RetrieveClassName(class_info, &name))
    return name;

  // No class found, need to register one.
  HBRUSH background = NULL;
  WNDCLASSEX class_ex = {
    sizeof(WNDCLASSEX),
    class_info.style,
    base::win::WrappedWindowProc<&WindowImpl::WndProc>,
    0,
    0,
    GetModuleHandle(NULL),
    icon,
    NULL,
    reinterpret_cast<HBRUSH>(background + 1),
    NULL,
    name.c_str(),
    icon
  };
  ATOM atom = RegisterClassEx(&class_ex);
  CHECK(atom) << GetLastError();

  ClassRegistrar::GetInstance()->RegisterClass(class_info, name, atom);

  return name;
}

}  // namespace ui
<|endoftext|>