<commit_before>/*
/*TeamSpeak 3 plugin development kit
Copyright (c) 2008-2016 TeamSpeak Systems GmbH
Copyright (c) 2016 Sean McNamara <smcnam@gmail.com>

Available to the general public at https://www.teamspeak.com/downloads with no specified license.
The author of kynnaugh-cc does not claim to license this file under the Apache License, version 2.0.
This file is a derivative work of the example in the Plugin SDK.
*/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <teamspeak/public_definitions.h>
#include <plugin_definitions.h>
#include <ts3_functions.h>
#include <kynnaugh.h>
#include <sampledef.h>
#include <QtCore>
#include <QtWidgets>
#include <tuple>
#include "dbg.h"
#include "speechrec.h"
#include "kynnconfigdlg.h"

#define PLUGIN_API_VERSION 21
#define PATH_BUFSIZE 512
#define COMMAND_BUFSIZE 128
#define INFODATA_BUFSIZE 128
#define SERVERINFO_BUFSIZE 256
#define CHANNELINFO_BUFSIZE 512
#define RETURNCODE_BUFSIZE 128

struct TS3Functions *ts3func::funcs = nullptr;
bool ts3func::useTeamspeaksQt = true;
static struct TS3Functions ts3Functions;
static QString *pluginID = NULL;
static QHash<std::tuple<quint64, anyID, qint32>, sampledef*> sampledefs = QHash<std::tuple<quint64, anyID, qint32>, sampledef*>();

#define STATIC_STRING(x) static QString var = x; static QByteArray arr = var.toUtf8(); return arr.constData();

/*********************************** Required functions ************************************/
/*
 * If any of these required functions is not implemented, TS3 will refuse to load the plugin
 */

/* Unique name identifying this plugin */
const char* ts3plugin_name() {
    STATIC_STRING("Kynnaugh")
}

/* Plugin version */
const char* ts3plugin_version() {
    STATIC_STRING("1.0")
}

/* Plugin API version. Must be the same as the clients API major version, else the plugin fails to load. */
int ts3plugin_apiVersion() {
    return PLUGIN_API_VERSION;
}

/* Plugin author */
const char* ts3plugin_author() {
    STATIC_STRING("Sean McNamara / Coorbin Faydedar <smcnam@gmail.com>")
}

/* Plugin description */
const char* ts3plugin_description() {
    STATIC_STRING("Speech recognition and text to speech for deaf users.")
}

/* Set TeamSpeak 3 callback functions */
void ts3plugin_setFunctionPointers(const struct TS3Functions funcs) {
    ts3Functions = funcs;
    ts3func::funcs = &ts3Functions;
}

/*
 * Custom code called right after loading the plugin. Returns 0 on success, 1 on failure.
 * If the function returns 1 on failure, the plugin will be unloaded again.
 */
int ts3plugin_init() {
    char appPath[PATH_BUFSIZE];
    char resourcesPath[PATH_BUFSIZE];
    char configPath[PATH_BUFSIZE];
    char pluginPath[PATH_BUFSIZE];

    /* Your plugin init code here */
    printf("KYNNAUGH PLUGIN: init\n");

    /* Example on how to query application, resources and configuration paths from client */
    /* Note: Console client returns empty string for app and resources path */
    ts3Functions.getAppPath(appPath, PATH_BUFSIZE);
    ts3Functions.getResourcesPath(resourcesPath, PATH_BUFSIZE);
    ts3Functions.getConfigPath(configPath, PATH_BUFSIZE);
    ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE);

    //This code hacks around situations (only possible on OS X and Windows) where two versions of Qt are loaded in the same address space.
    //Teamspeak's own Qt creates its own QApplication, but we have to make *another* if "our" Qt isn't TeamSpeak's Qt.
    //This *never* occurs on Linux because of the lack of a "Side-by-side" library compatibility subsystem.
    int argc = 1;
    char *first = const_cast<char*>("a");
    char **argv = &first;
    QCoreApplication *app = QApplication::instance();
    if(app == nullptr)
    {
        ts3func::useTeamspeaksQt = false;
        app = new QApplication(argc, argv);
    }

    //Here's where we initialize QSettings. Can't use it before now!
    QApplication::setOrganizationName("rootaccessorg");
    QApplication::setApplicationName("kynnaugh-cc");

#if defined(_WIN32) && defined(KYNNAUGH_DEBUG)
    //Redirect stdout and stderr to a log file because TS handles them weirdly/badly on Windows
    QString stdoutlogfile = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QDir::separator() + "kynnaugh-cc-stdout-log.txt";
    QString stderrlogfile = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QDir::separator() + "kynnaugh-cc-stderr-log.txt";
    freopen(qPrintable(stdoutlogfile),"w",stdout);
    freopen(qPrintable(stderrlogfile),"w",stderr);
#endif

    return 0;  /* 0 = success, 1 = failure, -2 = failure but client will not show a "failed to load" warning */
    /* -2 is a very special case and should only be used if a plugin displays a dialog (e.g. overlay) asking the user to disable
     * the plugin again, avoiding the show another dialog by the client telling the user the plugin failed to load.
     * For normal case, if a plugin really failed to load because of an error, the correct return value is 1. */
}

/* Custom code called right before the plugin is unloaded */
void ts3plugin_shutdown() {
    /* Your plugin cleanup code here */
    qWarning("KYNNAUGH PLUGIN: shutdown\n");

    /*
     * Note:
     * If your plugin implements a settings dialog, it must be closed and deleted here, else the
     * TeamSpeak client will most likely crash (DLL removed but dialog from DLL code still open).
     */

    /* Free pluginID if we registered it */
    if(pluginID) {
        free(pluginID);
        pluginID = NULL;
    }
}

/*
 * If the plugin wants to use error return codes, plugin commands, hotkeys or menu items, it needs to register a command ID. This function will be
 * automatically called after the plugin was initialized. This function is optional. If you don't use these features, this function can be omitted.
 * Note the passed pluginID parameter is no longer valid after calling this function, so you must copy it and store it in the plugin.
 */
void ts3plugin_registerPluginID(const char* id) {
    qInstallMessageHandler(0);
    pluginID = new QString(id);
    dbg::qStdOut() << "KYNNAUGH PLUGIN: registerPluginID: " << pluginID;
}

/* Required to release the memory for parameter "data" allocated in ts3plugin_infoData and ts3plugin_initMenus */
void ts3plugin_freeMemory(void* data) {
    free(data);
}

/*
 * Plugin requests to be always automatically loaded by the TeamSpeak 3 client unless
 * the user manually disabled it in the plugin dialog.
 * This function is optional. If missing, no autoload is assumed.
 */
int ts3plugin_requestAutoload() {
    return 1;  /* 1 = request autoloaded, 0 = do not request autoload */
}

void ts3plugin_onEditPlaybackVoiceDataEvent(uint64 serverConnectionHandlerID, anyID clientID, short *samples,
                                       int sampleCount, int channels) {

    //The below logging message is printed _very_ frequently; only use if you're not sure if this callback is being called at all.
    //ts3Functions.printMessageToCurrentTab("ts3plugin_onEditPlaybackVoiceDataEvent");

    std::tuple<quint64, anyID, qint32> key = sampledef::getKey(serverConnectionHandlerID, clientID, channels);
    if(sampledefs.contains(key))
    {
        sampledefs[key]->update(samples, sampleCount);
    }
    else
    {
        char *nickname;
        ts3Functions.getClientVariableAsString(serverConnectionHandlerID, clientID, ClientProperties::CLIENT_NICKNAME, &nickname);
        dbg::qStdOut() << "KYNNAUGH PLUGIN: New sampledef for client #" << clientID << ", " << nickname << " with " << channels << " channels.\n";
        ts3Functions.freeMemory(nickname);
        sampledef *def = new sampledef(0, serverConnectionHandlerID, clientID, channels);
        sampledefs.insert(key, def);
        def->update(samples, sampleCount);
    }
}

/* Tell client if plugin offers a configuration window.
 * If this function is not implemented, it's an assumed "does not offer" (PLUGIN_OFFERS_NO_CONFIGURE). */
int ts3plugin_offersConfigure() {
    printf("KYNNAUGH: offersConfigure\n");
    /*
     * Return values:
     * PLUGIN_OFFERS_NO_CONFIGURE         - Plugin does not implement ts3plugin_configure
     * PLUGIN_OFFERS_CONFIGURE_NEW_THREAD - Plugin does implement ts3plugin_configure and requests to run this function in an own thread
     * PLUGIN_OFFERS_CONFIGURE_QT_THREAD  - Plugin does implement ts3plugin_configure and requests to run this function in the Qt GUI thread
     */
    if(ts3func::useTeamspeaksQt)
    {
        return PLUGIN_OFFERS_CONFIGURE_QT_THREAD;
    }
    else
    {
        return PLUGIN_OFFERS_CONFIGURE_NEW_THREAD;
    }
}

/* Plugin might offer a configuration window. If ts3plugin_offersConfigure returns 0, this function does not need to be implemented. */
void ts3plugin_configure(void* handle, void* qParentWidget) {
    printf("KYNNAUGH: configure\n");
    if(ts3func::useTeamspeaksQt)
    {
        //Use qParentWidget, which is a QDialog*
        static KynnConfigDlg *confdlg_tsqt = new KynnConfigDlg(static_cast<QWidget*>(qParentWidget));
        confdlg_tsqt->exec();
    }
    else
    {
        //Use handle, which is an opaque handle to a parent window
        static KynnConfigDlg *confdlg_opaque = new KynnConfigDlg(nullptr);
        confdlg_opaque->exec();
    }
}

namespace std
{
    inline uint qHash(const std::tuple<quint64, anyID, qint32> &key, uint seed = 0)
    {
        const quint64 &one = std::get<0>(key);
        const anyID   &two = std::get<1>(key);
        const qint32  &three = std::get<2>(key);

        return ::qHash(one, seed) ^ ::qHash(two, seed) ^ ::qHash(three, seed);
    }
}
<commit_msg>Take Bob's suggestion and use IniFormat everywhere for QSettings.<commit_after>/*
/*TeamSpeak 3 plugin development kit
Copyright (c) 2008-2016 TeamSpeak Systems GmbH
Copyright (c) 2016 Sean McNamara <smcnam@gmail.com>

Available to the general public at https://www.teamspeak.com/downloads with no specified license.
The author of kynnaugh-cc does not claim to license this file under the Apache License, version 2.0.
This file is a derivative work of the example in the Plugin SDK.
*/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <teamspeak/public_definitions.h>
#include <plugin_definitions.h>
#include <ts3_functions.h>
#include <kynnaugh.h>
#include <sampledef.h>
#include <QtCore>
#include <QtWidgets>
#include <tuple>
#include "dbg.h"
#include "speechrec.h"
#include "kynnconfigdlg.h"

#define PLUGIN_API_VERSION 21
#define PATH_BUFSIZE 512
#define COMMAND_BUFSIZE 128
#define INFODATA_BUFSIZE 128
#define SERVERINFO_BUFSIZE 256
#define CHANNELINFO_BUFSIZE 512
#define RETURNCODE_BUFSIZE 128

struct TS3Functions *ts3func::funcs = nullptr;
bool ts3func::useTeamspeaksQt = true;
static struct TS3Functions ts3Functions;
static QString *pluginID = NULL;
static QHash<std::tuple<quint64, anyID, qint32>, sampledef*> sampledefs = QHash<std::tuple<quint64, anyID, qint32>, sampledef*>();

#define STATIC_STRING(x) static QString var = x; static QByteArray arr = var.toUtf8(); return arr.constData();

/*********************************** Required functions ************************************/
/*
 * If any of these required functions is not implemented, TS3 will refuse to load the plugin
 */

/* Unique name identifying this plugin */
const char* ts3plugin_name() {
    STATIC_STRING("Kynnaugh")
}

/* Plugin version */
const char* ts3plugin_version() {
    STATIC_STRING("1.0")
}

/* Plugin API version. Must be the same as the clients API major version, else the plugin fails to load. */
int ts3plugin_apiVersion() {
    return PLUGIN_API_VERSION;
}

/* Plugin author */
const char* ts3plugin_author() {
    STATIC_STRING("Sean McNamara / Coorbin Faydedar <smcnam@gmail.com>")
}

/* Plugin description */
const char* ts3plugin_description() {
    STATIC_STRING("Speech recognition and text to speech for deaf users.")
}

/* Set TeamSpeak 3 callback functions */
void ts3plugin_setFunctionPointers(const struct TS3Functions funcs) {
    ts3Functions = funcs;
    ts3func::funcs = &ts3Functions;
}

/*
 * Custom code called right after loading the plugin. Returns 0 on success, 1 on failure.
 * If the function returns 1 on failure, the plugin will be unloaded again.
 */
int ts3plugin_init() {
    char appPath[PATH_BUFSIZE];
    char resourcesPath[PATH_BUFSIZE];
    char configPath[PATH_BUFSIZE];
    char pluginPath[PATH_BUFSIZE];

    /* Your plugin init code here */
    printf("KYNNAUGH PLUGIN: init\n");

    /* Example on how to query application, resources and configuration paths from client */
    /* Note: Console client returns empty string for app and resources path */
    ts3Functions.getAppPath(appPath, PATH_BUFSIZE);
    ts3Functions.getResourcesPath(resourcesPath, PATH_BUFSIZE);
    ts3Functions.getConfigPath(configPath, PATH_BUFSIZE);
    ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE);

    //This code hacks around situations (only possible on OS X and Windows) where two versions of Qt are loaded in the same address space.
    //Teamspeak's own Qt creates its own QApplication, but we have to make *another* if "our" Qt isn't TeamSpeak's Qt.
    //This *never* occurs on Linux because of the lack of a "Side-by-side" library compatibility subsystem.
    int argc = 1;
    char *first = const_cast<char*>("a");
    char **argv = &first;
    QCoreApplication *app = QApplication::instance();
    if(app == nullptr)
    {
        ts3func::useTeamspeaksQt = false;
        app = new QApplication(argc, argv);
    }

    QSettings::setDefaultFormat(QSettings::IniFormat);
    //Here's where we initialize QSettings. Can't use it before now!
    QApplication::setOrganizationName("rootaccessorg");
    QApplication::setApplicationName("kynnaugh-cc");

#if defined(_WIN32) && defined(KYNNAUGH_DEBUG)
    //Redirect stdout and stderr to a log file because TS handles them weirdly/badly on Windows
    QString stdoutlogfile = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QDir::separator() + "kynnaugh-cc-stdout-log.txt";
    QString stderrlogfile = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + QDir::separator() + "kynnaugh-cc-stderr-log.txt";
    freopen(qPrintable(stdoutlogfile),"w",stdout);
    freopen(qPrintable(stderrlogfile),"w",stderr);
#endif

    return 0;  /* 0 = success, 1 = failure, -2 = failure but client will not show a "failed to load" warning */
    /* -2 is a very special case and should only be used if a plugin displays a dialog (e.g. overlay) asking the user to disable
     * the plugin again, avoiding the show another dialog by the client telling the user the plugin failed to load.
     * For normal case, if a plugin really failed to load because of an error, the correct return value is 1. */
}

/* Custom code called right before the plugin is unloaded */
void ts3plugin_shutdown() {
    /* Your plugin cleanup code here */
    qWarning("KYNNAUGH PLUGIN: shutdown\n");

    /*
     * Note:
     * If your plugin implements a settings dialog, it must be closed and deleted here, else the
     * TeamSpeak client will most likely crash (DLL removed but dialog from DLL code still open).
     */

    /* Free pluginID if we registered it */
    if(pluginID) {
        free(pluginID);
        pluginID = NULL;
    }
}

/*
 * If the plugin wants to use error return codes, plugin commands, hotkeys or menu items, it needs to register a command ID. This function will be
 * automatically called after the plugin was initialized. This function is optional. If you don't use these features, this function can be omitted.
 * Note the passed pluginID parameter is no longer valid after calling this function, so you must copy it and store it in the plugin.
 */
void ts3plugin_registerPluginID(const char* id) {
    qInstallMessageHandler(0);
    pluginID = new QString(id);
    dbg::qStdOut() << "KYNNAUGH PLUGIN: registerPluginID: " << pluginID;
}

/* Required to release the memory for parameter "data" allocated in ts3plugin_infoData and ts3plugin_initMenus */
void ts3plugin_freeMemory(void* data) {
    free(data);
}

/*
 * Plugin requests to be always automatically loaded by the TeamSpeak 3 client unless
 * the user manually disabled it in the plugin dialog.
 * This function is optional. If missing, no autoload is assumed.
 */
int ts3plugin_requestAutoload() {
    return 1;  /* 1 = request autoloaded, 0 = do not request autoload */
}

void ts3plugin_onEditPlaybackVoiceDataEvent(uint64 serverConnectionHandlerID, anyID clientID, short *samples,
                                       int sampleCount, int channels) {

    //The below logging message is printed _very_ frequently; only use if you're not sure if this callback is being called at all.
    //ts3Functions.printMessageToCurrentTab("ts3plugin_onEditPlaybackVoiceDataEvent");

    std::tuple<quint64, anyID, qint32> key = sampledef::getKey(serverConnectionHandlerID, clientID, channels);
    if(sampledefs.contains(key))
    {
        sampledefs[key]->update(samples, sampleCount);
    }
    else
    {
        char *nickname;
        ts3Functions.getClientVariableAsString(serverConnectionHandlerID, clientID, ClientProperties::CLIENT_NICKNAME, &nickname);
        dbg::qStdOut() << "KYNNAUGH PLUGIN: New sampledef for client #" << clientID << ", " << nickname << " with " << channels << " channels.\n";
        ts3Functions.freeMemory(nickname);
        sampledef *def = new sampledef(0, serverConnectionHandlerID, clientID, channels);
        sampledefs.insert(key, def);
        def->update(samples, sampleCount);
    }
}

/* Tell client if plugin offers a configuration window.
 * If this function is not implemented, it's an assumed "does not offer" (PLUGIN_OFFERS_NO_CONFIGURE). */
int ts3plugin_offersConfigure() {
    printf("KYNNAUGH: offersConfigure\n");
    /*
     * Return values:
     * PLUGIN_OFFERS_NO_CONFIGURE         - Plugin does not implement ts3plugin_configure
     * PLUGIN_OFFERS_CONFIGURE_NEW_THREAD - Plugin does implement ts3plugin_configure and requests to run this function in an own thread
     * PLUGIN_OFFERS_CONFIGURE_QT_THREAD  - Plugin does implement ts3plugin_configure and requests to run this function in the Qt GUI thread
     */
    if(ts3func::useTeamspeaksQt)
    {
        return PLUGIN_OFFERS_CONFIGURE_QT_THREAD;
    }
    else
    {
        return PLUGIN_OFFERS_CONFIGURE_NEW_THREAD;
    }
}

/* Plugin might offer a configuration window. If ts3plugin_offersConfigure returns 0, this function does not need to be implemented. */
void ts3plugin_configure(void* handle, void* qParentWidget) {
    printf("KYNNAUGH: configure\n");
    if(ts3func::useTeamspeaksQt)
    {
        //Use qParentWidget, which is a QDialog*
        static KynnConfigDlg *confdlg_tsqt = new KynnConfigDlg(static_cast<QWidget*>(qParentWidget));
        confdlg_tsqt->exec();
    }
    else
    {
        //Use handle, which is an opaque handle to a parent window
        static KynnConfigDlg *confdlg_opaque = new KynnConfigDlg(nullptr);
        confdlg_opaque->exec();
    }
}

namespace std
{
    inline uint qHash(const std::tuple<quint64, anyID, qint32> &key, uint seed = 0)
    {
        const quint64 &one = std::get<0>(key);
        const anyID   &two = std::get<1>(key);
        const qint32  &three = std::get<2>(key);

        return ::qHash(one, seed) ^ ::qHash(two, seed) ^ ::qHash(three, seed);
    }
}
<|endoftext|>


<commit_before>/***
 * testDeadState
 * ------------------------
 * Test that DeadState works correctly
 *
 * Note: to setup the initial conditions for the DeadState, the InitState is used in the test.
 * Therefore, please check InitState test if any error related to the initial conditions is found.
 *
 */

#include "gtest/gtest.h"
#include <string>
#include <vector>

#include "StateMachine.hpp"
#include "StateMachineBuilder.hpp"
#include "RdUtils.hpp"
#include "DeadState.hpp"
#include "InitState.hpp"

#include "MockupNetworkManager.hpp"
#include "RdMockupImageManager.hpp"
#include "MockupInputManager.hpp"
#include "RdMentalMap.hpp"
#include "RdMockupRobotManager.hpp"
#include "MockupAudioManager.hpp"
#include "MockupState.hpp"
#include "MockupInputEventListener.hpp"

#include <yarp/sig/all.h>
#include <yarp/os/Network.h>
#include <yarp/os/Time.h>

using namespace rd;

//-- Class for the setup of the enviroment for all the tests
//----------------------------------------------------------------------------------------
//-- This is required since MockupStates are used (and require yarp ports to be open)

class DeadStateTestEnvironment : public testing::Environment
{
    public:
        DeadStateTestEnvironment(int argc, char ** argv)
        {
            this->argc = argc;
            this->argv = argv;
        }

        virtual void SetUp()
        {
            //-- Init yarp network & server
            yarp::os::NetworkBase::setLocalMode(true);
            yarp::os::Network::init();
        }

        virtual void TearDown()
        {
            yarp::os::Network::fini();
        }

    private:
        int argc;
        char ** argv;

};

//-- Class for the setup of each test
//--------------------------------------------------------------------------------------
class DeadStateTest : public testing::Test
{
    public:
        virtual void SetUp()
        {
            //-- Start YARP network
            yarp::os::Network::init();

            //-- Register managers to be used:
            MockupNetworkManager::RegisterManager();
            RdMockupImageManager::RegisterManager();
            MockupInputManager::RegisterManager();
            MockupAudioManager::RegisterManager();

            //-- Create managers
            networkManager = RdNetworkManager::getNetworkManager("MOCKUP");
            mockupNetworkManager = dynamic_cast<MockupNetworkManager *>(networkManager);
            ASSERT_NE((RdNetworkManager*) NULL, networkManager);
            ASSERT_NE((MockupNetworkManager*) NULL, mockupNetworkManager);

            imageManager = RdImageManager::getImageManager("MOCKUP");
            mockupImageManager = dynamic_cast<RdMockupImageManager *>(imageManager);
            ASSERT_NE((RdImageManager*) NULL, imageManager);
            ASSERT_NE((RdMockupImageManager*) NULL, mockupImageManager);
            //-- Load test image
            RdImage test_frame;
            yarp::sig::file::read(test_frame, "../../share/images/test_frame.ppm");
            mockupImageManager->receiveImage(test_frame);

            inputManager = RdInputManager::getInputManager("MOCKUP");
            mockupInputManager = dynamic_cast<MockupInputManager *>(inputManager);
            ASSERT_NE((RdInputManager*) NULL, inputManager);
            ASSERT_NE((MockupInputManager*) NULL, mockupInputManager);

            audioManager = AudioManager::getAudioManager("MOCKUP");
            mockupAudioManager = dynamic_cast<MockupAudioManager *>(audioManager);
            ASSERT_NE((AudioManager*) NULL, audioManager);
            ASSERT_NE((MockupAudioManager*) NULL, mockupAudioManager);
            mockupAudioManager->load("RD_THEME","RD_THEME", AudioManager::MUSIC);
            mockupAudioManager->load("RD_DEAD","RD_DEAD", AudioManager::MUSIC);

            mentalMap = RdMentalMap::getMentalMap();
            ASSERT_NE((RdMentalMap*) NULL, mentalMap);
            ASSERT_TRUE(mentalMap->configure(1));

            //-- Insert dead player for testing
            std::vector<RdPlayer> players;
            players.push_back(RdPlayer(1,"test_player", 0,MAX_HEALTH,0,0) );
            ASSERT_TRUE(mentalMap->updatePlayers(players));
            mentalMap->addWeapon(RdWeapon("Default gun", 10, 5));

            mockupRobotManager = new RdMockupRobotManager("MOCKUP");
            robotManager = (RdRobotManager *) mockupRobotManager;
            ASSERT_NE((RdMockupRobotManager*) NULL, mockupRobotManager);
            ASSERT_NE((RdRobotManager*) NULL, robotManager);

            //-- Setup managers to the required initial state:
            //-- Note: For simplicity, I'm using InitState here and manually calling
            //-- the correct initialization sequence. The testInitState allows to test
            //-- if InitState works correctly.
            State * initState = new InitState(networkManager, imageManager, inputManager,
                                              mentalMap, robotManager, audioManager);
            initState->setup();
            dynamic_cast<RdInputEventListener *>(initState)->onKeyUp(MockupKey(RdKey::KEY_ENTER));
            initState->loop();
            initState->cleanup();
            delete initState;
            initState = NULL;

            //-- Finish setup of the modules that start at game state:
            mockupImageManager->start();

            listener = new MockupInputEventListener;
            mockupInputManager->addInputEventListener(listener);

            audioManager->start();
            audioManager->play("RD_THEME", -1);

        }

        virtual void TearDown()
        {
            //-- Close YARP network
            yarp::os::Network::fini();

            //-- Delete things
            RdNetworkManager::destroyNetworkManager();
            networkManager = NULL;
            mockupNetworkManager = NULL;
            RdImageManager::destroyImageManager();
            imageManager = NULL;
            mockupImageManager = NULL;
            RdInputManager::destroyInputManager();
            AudioManager::destroyAudioManager();

            RdMentalMap::destroyMentalMap();

            delete mockupRobotManager;
            mockupRobotManager = NULL;

            delete listener;
            listener=NULL;

        }

    static const int MAX_HEALTH;

    protected:
        FiniteStateMachine *fsm;

        RdNetworkManager * networkManager;
        MockupNetworkManager * mockupNetworkManager;

        RdImageManager * imageManager;
        RdMockupImageManager * mockupImageManager;

        RdInputManager * inputManager;
        MockupInputManager * mockupInputManager;

        AudioManager * audioManager;
        MockupAudioManager * mockupAudioManager;

        RdMentalMap * mentalMap;

        RdMockupRobotManager * mockupRobotManager;
        RdRobotManager * robotManager;

        MockupInputEventListener * listener;
};

const int DeadStateTest::MAX_HEALTH = 100;

//--- Tests ------------------------------------------------------------------------------------------
TEST_F(DeadStateTest, DeadStateGoesToRespawn)
{
    //-- Create fsm with DeadState
    StateMachineBuilder builder;
    ASSERT_TRUE(builder.setDirectorType("YARP"));

    int dead_state_id = builder.addState(new DeadState(networkManager, imageManager, inputManager,
                                                       mentalMap, robotManager, audioManager));
    ASSERT_NE(-1, dead_state_id);
    int game_state_id = builder.addState(new MockupState(1));
    ASSERT_NE(-1, game_state_id);
    int exit_state_id = builder.addState(State::getEndState());

    ASSERT_TRUE(builder.addTransition(dead_state_id, game_state_id, DeadState::RESPAWN_SELECTED));
    ASSERT_TRUE(builder.addTransition(dead_state_id, exit_state_id, DeadState::EXIT_SELECTED));
    ASSERT_TRUE(builder.setInitialState(dead_state_id));

    fsm = builder.buildStateMachine();
    ASSERT_NE((FiniteStateMachine*)NULL, fsm);

    //-- Check things that should happen before fsm starts (before setup):
    // Player is dead
    // Stuff is enabled
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_FALSE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    //ASSERT_FALSE(mockupRobotManager->isStopped()); //-- Not correctly implemented
    //ASSERT_FALSE(mockupRobotManager->isConnected());

    //-- Start state machine
    ASSERT_TRUE(fsm->start());

    //-- Check things that should happen in dead state before time runs out (setup):
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_TRUE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    //ASSERT_TRUE(mockupRobotManager->isStopped()); //-- Not correctly implemented
    //ASSERT_FALSE(mockupRobotManager->isConnected());

    //-- Check that deadState is active
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When enter is pressed, but the countdown is still active, input is ignored
    yarp::os::Time::delay(0.5);
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ENTER));
    yarp::os::Time::delay(0.5);
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When time is up, and enter is pressed, the system should go to respawn state:
    yarp::os::Time::delay(10);
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ENTER));
    yarp::os::Time::delay(0.5);

    //-- Check that it has restored things (health, enable stuff)
    //-- and it is in the game state (cleanup):
    ASSERT_EQ(DeadStateTest::MAX_HEALTH, mentalMap->getMyself().getHealth());
    ASSERT_FALSE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners()); //-- Game sets its own listener
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    //ASSERT_FALSE(mockupRobotManager->isStopped()); //-- Not correctly implemented
    //ASSERT_FALSE(mockupRobotManager->isConnected());

    //-- Check that gameState is active
    ASSERT_EQ(game_state_id, fsm->getCurrentState());

}

TEST_F(DeadStateTest, DeadStateGoesToLogout)
{
    //-- Create fsm with DeadState
    StateMachineBuilder builder;
    ASSERT_TRUE(builder.setDirectorType("YARP"));

    int dead_state_id = builder.addState(new DeadState(networkManager, imageManager, inputManager,
                                                       mentalMap, robotManager, audioManager));
    ASSERT_NE(-1, dead_state_id);
    int game_state_id = builder.addState(new MockupState(1));
    ASSERT_NE(-1, game_state_id);
    int exit_state_id = builder.addState(State::getEndState());
    ASSERT_NE(-1, exit_state_id);

    ASSERT_TRUE(builder.addTransition(dead_state_id, game_state_id, DeadState::RESPAWN_SELECTED));
    ASSERT_TRUE(builder.addTransition(dead_state_id, exit_state_id, DeadState::EXIT_SELECTED));
    ASSERT_TRUE(builder.setInitialState(dead_state_id));

    fsm = builder.buildStateMachine();
    ASSERT_NE((FiniteStateMachine*)NULL, fsm);

    //-- Check things that should happen before fsm starts (before setup):
    // Player is dead
    // Stuff is enabled
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_FALSE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    //ASSERT_FALSE(mockupRobotManager->isStopped()); //-- Not correctly implemented
    //ASSERT_FALSE(mockupRobotManager->isConnected());

    //-- Start state machine
    ASSERT_TRUE(fsm->start());

    //-- Check things that should happen in dead state before time runs out (setup):
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_TRUE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    //ASSERT_TRUE(mockupRobotManager->isStopped()); //-- Not correctly implemented
    //ASSERT_FALSE(mockupRobotManager->isConnected());

    //-- Check that deadState is active
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When enter is pressed, but the countdown is still active, input is ignored
    yarp::os::Time::delay(0.5);
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ENTER));
    yarp::os::Time::delay(0.5);
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When time is up, and esc is pressed, the system should exit the game:
    yarp::os::Time::delay(10);
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ESCAPE));
    yarp::os::Time::delay(0.5);

    //-- Check that it has stopped things and it is in the final state (cleanup):
    ASSERT_EQ(0, mentalMap->getMyself().getHealth());
    ASSERT_TRUE(mockupImageManager->isStopped());
    ASSERT_TRUE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners());
    ASSERT_TRUE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_TRUE(mockupNetworkManager->isStopped());
    ASSERT_FALSE(mockupNetworkManager->isLoggedIn());
    //ASSERT_FALSE(mockupRobotManager->isStopped()); //-- Not correctly implemented
    //ASSERT_FALSE(mockupRobotManager->isConnected());

    //-- Check that end state is active
    ASSERT_EQ(-1, fsm->getCurrentState()); //-- (When FSM is ended, no state is active, hence -1)
}

//--- Main -------------------------------------------------------------------------------------------
int main(int argc, char **argv)
{
  testing::InitGoogleTest(&argc, argv);
  testing::Environment* env = testing::AddGlobalTestEnvironment(new DeadStateTestEnvironment(argc, argv));
  return RUN_ALL_TESTS();
}
<commit_msg>Add failing test for RobotManager support on DeadState<commit_after>/***
 * testDeadState
 * ------------------------
 * Test that DeadState works correctly
 *
 * Note: to setup the initial conditions for the DeadState, the InitState is used in the test.
 * Therefore, please check InitState test if any error related to the initial conditions is found.
 *
 */

#include "gtest/gtest.h"
#include <string>
#include <vector>

#include "StateMachine.hpp"
#include "StateMachineBuilder.hpp"
#include "RdUtils.hpp"
#include "DeadState.hpp"
#include "InitState.hpp"

#include "MockupNetworkManager.hpp"
#include "RdMockupImageManager.hpp"
#include "MockupInputManager.hpp"
#include "RdMentalMap.hpp"
#include "RdMockupRobotManager.hpp"
#include "MockupAudioManager.hpp"
#include "MockupState.hpp"
#include "MockupInputEventListener.hpp"

#include <yarp/sig/all.h>
#include <yarp/os/Network.h>
#include <yarp/os/Time.h>

using namespace rd;

//-- Class for the setup of the enviroment for all the tests
//----------------------------------------------------------------------------------------
//-- This is required since MockupStates are used (and require yarp ports to be open)

class DeadStateTestEnvironment : public testing::Environment
{
    public:
        DeadStateTestEnvironment(int argc, char ** argv)
        {
            this->argc = argc;
            this->argv = argv;
        }

        virtual void SetUp()
        {
            //-- Init yarp network & server
            yarp::os::NetworkBase::setLocalMode(true);
            yarp::os::Network::init();
        }

        virtual void TearDown()
        {
            yarp::os::Network::fini();
        }

    private:
        int argc;
        char ** argv;

};

//-- Class for the setup of each test
//--------------------------------------------------------------------------------------
class DeadStateTest : public testing::Test
{
    public:
        virtual void SetUp()
        {
            //-- Start YARP network
            yarp::os::Network::init();

            //-- Register managers to be used:
            MockupNetworkManager::RegisterManager();
            RdMockupImageManager::RegisterManager();
            MockupInputManager::RegisterManager();
            MockupAudioManager::RegisterManager();

            //-- Create managers
            networkManager = RdNetworkManager::getNetworkManager("MOCKUP");
            mockupNetworkManager = dynamic_cast<MockupNetworkManager *>(networkManager);
            ASSERT_NE((RdNetworkManager*) NULL, networkManager);
            ASSERT_NE((MockupNetworkManager*) NULL, mockupNetworkManager);

            imageManager = RdImageManager::getImageManager("MOCKUP");
            mockupImageManager = dynamic_cast<RdMockupImageManager *>(imageManager);
            ASSERT_NE((RdImageManager*) NULL, imageManager);
            ASSERT_NE((RdMockupImageManager*) NULL, mockupImageManager);
            //-- Load test image
            RdImage test_frame;
            yarp::sig::file::read(test_frame, "../../share/images/test_frame.ppm");
            mockupImageManager->receiveImage(test_frame);

            inputManager = RdInputManager::getInputManager("MOCKUP");
            mockupInputManager = dynamic_cast<MockupInputManager *>(inputManager);
            ASSERT_NE((RdInputManager*) NULL, inputManager);
            ASSERT_NE((MockupInputManager*) NULL, mockupInputManager);

            audioManager = AudioManager::getAudioManager("MOCKUP");
            mockupAudioManager = dynamic_cast<MockupAudioManager *>(audioManager);
            ASSERT_NE((AudioManager*) NULL, audioManager);
            ASSERT_NE((MockupAudioManager*) NULL, mockupAudioManager);
            mockupAudioManager->load("RD_THEME","RD_THEME", AudioManager::MUSIC);
            mockupAudioManager->load("RD_DEAD","RD_DEAD", AudioManager::MUSIC);

            mentalMap = RdMentalMap::getMentalMap();
            ASSERT_NE((RdMentalMap*) NULL, mentalMap);
            ASSERT_TRUE(mentalMap->configure(1));

            //-- Insert dead player for testing
            std::vector<RdPlayer> players;
            players.push_back(RdPlayer(1,"test_player", 0,MAX_HEALTH,0,0) );
            ASSERT_TRUE(mentalMap->updatePlayers(players));
            mentalMap->addWeapon(RdWeapon("Default gun", 10, 5));

            mockupRobotManager = new RdMockupRobotManager("MOCKUP");
            robotManager = (RdRobotManager *) mockupRobotManager;
            ASSERT_NE((RdMockupRobotManager*) NULL, mockupRobotManager);
            ASSERT_NE((RdRobotManager*) NULL, robotManager);

            //-- Setup managers to the required initial state:
            //-- Note: For simplicity, I'm using InitState here and manually calling
            //-- the correct initialization sequence. The testInitState allows to test
            //-- if InitState works correctly.
            State * initState = new InitState(networkManager, imageManager, inputManager,
                                              mentalMap, robotManager, audioManager);
            initState->setup();
            dynamic_cast<RdInputEventListener *>(initState)->onKeyUp(MockupKey(RdKey::KEY_ENTER));
            initState->loop();
            initState->cleanup();
            delete initState;
            initState = NULL;

            //-- Finish setup of the modules that start at game state:
            //-- Note: we can change this to use GameState (as previously) if we want someday
            mockupImageManager->start();
            listener = new MockupInputEventListener;
            mockupInputManager->addInputEventListener(listener);
            audioManager->start();
            audioManager->play("RD_THEME", -1);
            mockupRobotManager->setEnabled(true);

        }

        virtual void TearDown()
        {
            //-- Close YARP network
            yarp::os::Network::fini();

            //-- Delete things
            RdNetworkManager::destroyNetworkManager();
            networkManager = NULL;
            mockupNetworkManager = NULL;
            RdImageManager::destroyImageManager();
            imageManager = NULL;
            mockupImageManager = NULL;
            RdInputManager::destroyInputManager();
            AudioManager::destroyAudioManager();

            RdMentalMap::destroyMentalMap();

            delete mockupRobotManager;
            mockupRobotManager = NULL;

            delete listener;
            listener=NULL;

        }

    static const int MAX_HEALTH;

    protected:
        FiniteStateMachine *fsm;

        RdNetworkManager * networkManager;
        MockupNetworkManager * mockupNetworkManager;

        RdImageManager * imageManager;
        RdMockupImageManager * mockupImageManager;

        RdInputManager * inputManager;
        MockupInputManager * mockupInputManager;

        AudioManager * audioManager;
        MockupAudioManager * mockupAudioManager;

        RdMentalMap * mentalMap;

        RdMockupRobotManager * mockupRobotManager;
        RdRobotManager * robotManager;

        MockupInputEventListener * listener;
};

const int DeadStateTest::MAX_HEALTH = 100;

//--- Tests ------------------------------------------------------------------------------------------
TEST_F(DeadStateTest, DeadStateGoesToRespawn)
{
    //-- Create fsm with DeadState
    StateMachineBuilder builder;
    ASSERT_TRUE(builder.setDirectorType("YARP"));

    int dead_state_id = builder.addState(new DeadState(networkManager, imageManager, inputManager,
                                                       mentalMap, robotManager, audioManager));
    ASSERT_NE(-1, dead_state_id);
    int game_state_id = builder.addState(new MockupState(1));
    ASSERT_NE(-1, game_state_id);
    int exit_state_id = builder.addState(State::getEndState());

    ASSERT_TRUE(builder.addTransition(dead_state_id, game_state_id, DeadState::RESPAWN_SELECTED));
    ASSERT_TRUE(builder.addTransition(dead_state_id, exit_state_id, DeadState::EXIT_SELECTED));
    ASSERT_TRUE(builder.setInitialState(dead_state_id));

    fsm = builder.buildStateMachine();
    ASSERT_NE((FiniteStateMachine*)NULL, fsm);

    //-- Check things that should happen before fsm starts (before setup):
    // Player is dead
    // Stuff is enabled
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_FALSE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    ASSERT_TRUE(mockupRobotManager->isConnected());
    ASSERT_TRUE(mockupRobotManager->isEnabled());

    //-- Start state machine
    ASSERT_TRUE(fsm->start());

    //-- Check things that should happen in dead state before time runs out (setup):
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_TRUE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    ASSERT_TRUE(mockupRobotManager->isConnected());
    ASSERT_FALSE(mockupRobotManager->isEnabled());

    //-- Check that deadState is active
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When enter is pressed, but the countdown is still active, input is ignored
    yarp::os::Time::delay(0.5);
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ENTER));
    yarp::os::Time::delay(0.5);
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When time is up, and enter is pressed, the system should go to respawn state:
    yarp::os::Time::delay(10);
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ENTER));
    yarp::os::Time::delay(0.5);

    //-- Check that it has restored things (health, enable stuff)
    //-- and it is in the game state (cleanup):
    ASSERT_EQ(DeadStateTest::MAX_HEALTH, mentalMap->getMyself().getHealth());
    ASSERT_FALSE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners()); //-- Game sets its own listener
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    ASSERT_TRUE(mockupRobotManager->isConnected());
    ASSERT_FALSE(mockupRobotManager->isEnabled());

    //-- Check that gameState is active
    ASSERT_EQ(game_state_id, fsm->getCurrentState());

}

TEST_F(DeadStateTest, DeadStateGoesToLogout)
{
    //-- Create fsm with DeadState
    StateMachineBuilder builder;
    ASSERT_TRUE(builder.setDirectorType("YARP"));

    int dead_state_id = builder.addState(new DeadState(networkManager, imageManager, inputManager,
                                                       mentalMap, robotManager, audioManager));
    ASSERT_NE(-1, dead_state_id);
    int game_state_id = builder.addState(new MockupState(1));
    ASSERT_NE(-1, game_state_id);
    int exit_state_id = builder.addState(State::getEndState());
    ASSERT_NE(-1, exit_state_id);

    ASSERT_TRUE(builder.addTransition(dead_state_id, game_state_id, DeadState::RESPAWN_SELECTED));
    ASSERT_TRUE(builder.addTransition(dead_state_id, exit_state_id, DeadState::EXIT_SELECTED));
    ASSERT_TRUE(builder.setInitialState(dead_state_id));

    fsm = builder.buildStateMachine();
    ASSERT_NE((FiniteStateMachine*)NULL, fsm);

    //-- Check things that should happen before fsm starts (before setup):
    // Player is dead
    // Stuff is enabled
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_FALSE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    ASSERT_TRUE(mockupRobotManager->isConnected());
    ASSERT_FALSE(mockupRobotManager->isEnabled());

    //-- Start state machine
    ASSERT_TRUE(fsm->start());

    //-- Check things that should happen in dead state before time runs out (setup):
    ASSERT_EQ(0, mentalMap->getMyself().getHealth()); //-- Important thing to check
    ASSERT_TRUE(mockupImageManager->isStopped());
    ASSERT_FALSE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners());
    ASSERT_FALSE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_TRUE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_FALSE(mockupNetworkManager->isStopped());
    ASSERT_TRUE(mockupNetworkManager->isLoggedIn());
    ASSERT_TRUE(mockupRobotManager->isConnected());
    ASSERT_FALSE(mockupRobotManager->isEnabled());

    //-- Check that deadState is active
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When enter is pressed, but the countdown is still active, input is ignored
    yarp::os::Time::delay(0.5);
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ENTER));
    yarp::os::Time::delay(0.5);
    ASSERT_EQ(dead_state_id, fsm->getCurrentState());

    //-- When time is up, and esc is pressed, the system should exit the game:
    yarp::os::Time::delay(10);
    ASSERT_EQ(1, mockupInputManager->getNumListeners());
    mockupInputManager->sendKeyPress(MockupKey(RdKey::KEY_ESCAPE));
    yarp::os::Time::delay(0.5);

    //-- Check that it has stopped things and it is in the final state (cleanup):
    ASSERT_EQ(0, mentalMap->getMyself().getHealth());
    ASSERT_TRUE(mockupImageManager->isStopped());
    ASSERT_TRUE(mockupInputManager->isStopped());
    ASSERT_EQ(0, mockupInputManager->getNumListeners());
    ASSERT_TRUE(mockupAudioManager->isStopped());
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_THEME"));
    ASSERT_FALSE(mockupAudioManager->isPlaying("RD_DEAD"));
    ASSERT_TRUE(mockupNetworkManager->isStopped());
    ASSERT_FALSE(mockupNetworkManager->isLoggedIn());
    ASSERT_FALSE(mockupRobotManager->isConnected());
    ASSERT_FALSE(mockupRobotManager->isEnabled());

    //-- Check that end state is active
    ASSERT_EQ(-1, fsm->getCurrentState()); //-- (When FSM is ended, no state is active, hence -1)
}

//--- Main -------------------------------------------------------------------------------------------
int main(int argc, char **argv)
{
  testing::InitGoogleTest(&argc, argv);
  testing::Environment* env = testing::AddGlobalTestEnvironment(new DeadStateTestEnvironment(argc, argv));
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014 Johannes Hggqvist

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.
*/
#include "WaveFile.h"

#include <iostream>
#include <string>
#include <fstream>

void print_usage()
{
	std::cout << "Usage: wav2raw file1.wav [file2.wav] [file3.wav] ..." << std::endl;
}

void process_file(const std::string &filename)
{
	std::cout << "Processing \"" << filename << "\"..." << std::endl;
	WaveFile wavFile(filename);
	if (wavFile.IsLoaded())
	{
		std::string audioFormat = "Unknown";
		switch (wavFile.GetAudioFormat())
		{
		case WaveFile::PCM: audioFormat = "PCM"; break;
		}

		std::cout <<
			"Meta data:\n"
			" - Audio format : " << audioFormat << "\n"
			" - Channels     : " << wavFile.GetNumChannels() << "\n"
			" - Sample rate  : " << wavFile.GetSampleRate() << "\n"
			" - Sample size  : " << wavFile.GetBitsPerSample() << " bits" << std::endl;

		std::string filenameSansExt = filename.substr(0, filename.find_last_of('.'));
		std::string filenameRaw = filenameSansExt + ".raw";
		std::fstream rawFile(filenameRaw, std::ios::out | std::ios::trunc | std::ios::binary);

		if (!rawFile.is_open())
		{
			std::cerr << "Error: Failed to open output file \"" << filenameRaw << "\"." << std::endl;
			return;
		}

		const char *rawData = wavFile.GetData();
		std::size_t rawSize = wavFile.GetDataSize();
		rawFile.write(rawData, rawSize);
		std::cout << "Wrote \"" << filenameRaw << "\"." << std::endl;
	}
}

int main(int argc, char *argv[])
{
	if (argc < 2)
	{
		print_usage();
		return 0;
	}

	for (int i = 1; i < argc; ++i)
	{
		std::string filename = argv[i];
		process_file(filename);
	}

	return 0;
}<commit_msg>Renamed functions in main.cpp to follow conventions<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014 Johannes Hggqvist

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.
*/
#include "WaveFile.h"

#include <iostream>
#include <string>
#include <fstream>

void PrintUsage()
{
	std::cout << "Usage: wav2raw file1.wav [file2.wav] [file3.wav] ..." << std::endl;
}

void ProcessFile(const std::string &filename)
{
	std::cout << "Processing \"" << filename << "\"..." << std::endl;
	WaveFile wavFile(filename);
	if (wavFile.IsLoaded())
	{
		std::string audioFormat = "Unknown";
		switch (wavFile.GetAudioFormat())
		{
		case WaveFile::PCM: audioFormat = "PCM"; break;
		}

		std::cout <<
			"Meta data:\n"
			" - Audio format : " << audioFormat << "\n"
			" - Channels     : " << wavFile.GetNumChannels() << "\n"
			" - Sample rate  : " << wavFile.GetSampleRate() << "\n"
			" - Sample size  : " << wavFile.GetBitsPerSample() << " bits" << std::endl;

		std::string filenameSansExt = filename.substr(0, filename.find_last_of('.'));
		std::string filenameRaw = filenameSansExt + ".raw";
		std::fstream rawFile(filenameRaw, std::ios::out | std::ios::trunc | std::ios::binary);

		if (!rawFile.is_open())
		{
			std::cerr << "Error: Failed to open output file \"" << filenameRaw << "\"." << std::endl;
			return;
		}

		const char *rawData = wavFile.GetData();
		std::size_t rawSize = wavFile.GetDataSize();
		rawFile.write(rawData, rawSize);
		std::cout << "Wrote \"" << filenameRaw << "\"." << std::endl;
	}
}

int main(int argc, char *argv[])
{
	if (argc < 2)
	{
		PrintUsage();
		return 0;
	}

	for (int i = 1; i < argc; ++i)
	{
		std::string filename = argv[i];
		ProcessFile(filename);
	}

	return 0;
}<|endoftext|>


<commit_before>/*
 * Source MUD
 * Copyright (C) 2000-2005  Sean Middleditch
 * See the file COPYING for license details
 * http://www.sourcemud.org
 */

extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

#include "lua/core.h"
#include "lua/print.h"
#include "common/log.h"

// globals
namespace Lua {
	extern lua_State* state;
	IStreamSink* sink;
}

// the public interface
void Lua::setPrint(IStreamSink* sink)
{
	Lua::sink = sink;
}

// this is our actual print function
namespace {
	int do_print(lua_State* s)
	{
		Log::Info << "print: " << lua_gettop(s);
		// check that we have a stream sink
		if (!Lua::sink) {
			lua_pushstring(s, "print() is not allowed in this context");
			lua_error(s);
		}

		// print each argument to our printer
		for (int i = 1, e = lua_gettop(s); i <= e; ++i) {
			size_t len;
			const char* str = lua_tolstring(s, i, &len);
			Lua::sink->stream_put(str, len);
		}

		// done; no return values
		return 0;
	}
}

// our initialization routine
namespace Lua {
	bool initializePrint()
	{
		// register our print function as 'print'
		lua_register(Lua::state, "print", do_print);
		return true;
	}
}
<commit_msg>remove debug msg<commit_after>/*
 * Source MUD
 * Copyright (C) 2000-2005  Sean Middleditch
 * See the file COPYING for license details
 * http://www.sourcemud.org
 */

extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

#include "lua/core.h"
#include "lua/print.h"

// globals
namespace Lua {
	extern lua_State* state;
	IStreamSink* sink;
}

// the public interface
void Lua::setPrint(IStreamSink* sink)
{
	Lua::sink = sink;
}

// this is our actual print function
namespace {
	int do_print(lua_State* s)
	{
		// check that we have a stream sink
		if (!Lua::sink) {
			lua_pushstring(s, "print() is not allowed in this context");
			lua_error(s);
		}

		// print each argument to our printer
		for (int i = 1, e = lua_gettop(s); i <= e; ++i) {
			size_t len;
			const char* str = lua_tolstring(s, i, &len);
			Lua::sink->stream_put(str, len);
		}

		// done; no return values
		return 0;
	}
}

// our initialization routine
namespace Lua {
	bool initializePrint()
	{
		// register our print function as 'print'
		lua_register(Lua::state, "print", do_print);
		return true;
	}
}
<|endoftext|>


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

#include "chrome/renderer/content_settings_observer.h"

#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"

using WebKit::WebDataSource;
using WebKit::WebFrame;
using WebKit::WebFrameClient;
using WebKit::WebSecurityOrigin;
using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebView;
using content::NavigationState;

namespace {

// True if |frame| contains content that is white-listed for content settings.
static bool IsWhitelistedForContentSettings(WebFrame* frame) {
  WebSecurityOrigin origin = frame->document().securityOrigin();
  if (origin.isEmpty())
    return false;  // Uninitialized document?

  if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
    return true;  // Browser UI elements should still work.

  // If the scheme is ftp: or file:, an empty file name indicates a directory
  // listing, which requires JavaScript to function properly.
  GURL document_url = frame->document().url();
  const char* kDirProtocols[] = { chrome::kFtpScheme, chrome::kFileScheme };
  for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
    if (EqualsASCII(origin.protocol(), kDirProtocols[i])) {
      return document_url.SchemeIs(kDirProtocols[i]) &&
             document_url.ExtractFileName().empty();
    }
  }

  return false;
}

GURL GetOriginOrURL(const WebFrame* frame) {
  WebString top_origin = frame->top()->document().securityOrigin().toString();
  // The the |top_origin| is unique ("null") e.g., for file:// URLs. Use the
  // document URL as the primary URL in those cases.
  if (top_origin == "null")
    return frame->document().url();
  return GURL(top_origin);
}

}  // namespace

ContentSettingsObserver::ContentSettingsObserver(
    content::RenderView* render_view)
    : content::RenderViewObserver(render_view),
      content::RenderViewObserverTracker<ContentSettingsObserver>(render_view),
      default_content_settings_(NULL),
      image_setting_rules_(NULL),
      plugins_temporarily_allowed_(false) {
  ClearBlockedContentSettings();
}

ContentSettingsObserver::~ContentSettingsObserver() {
}

void ContentSettingsObserver::SetContentSettings(
    const ContentSettings& settings) {
  current_content_settings_ = settings;
}

void ContentSettingsObserver::SetDefaultContentSettings(
    const ContentSettings* settings) {
  default_content_settings_ = settings;
}

void ContentSettingsObserver::SetImageSettingRules(
    const ContentSettingsForOneType* image_setting_rules) {
  image_setting_rules_ = image_setting_rules;
}

ContentSetting ContentSettingsObserver::GetContentSetting(
    ContentSettingsType type) {
  // Don't call this for plug-ins.
  DCHECK_NE(CONTENT_SETTINGS_TYPE_PLUGINS, type);
  return current_content_settings_.settings[type];
}

void ContentSettingsObserver::DidBlockContentType(
    ContentSettingsType settings_type,
    const std::string& resource_identifier) {
  // Always send a message when |resource_identifier| is not empty, to tell the
  // browser which resource was blocked (otherwise the browser will only show
  // the first resource to be blocked, and none that are blocked at a later
  // time).
  if (!content_blocked_[settings_type] || !resource_identifier.empty()) {
    content_blocked_[settings_type] = true;
    Send(new ChromeViewHostMsg_ContentBlocked(routing_id(), settings_type,
                                        resource_identifier));
  }
}

bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message)
    // Don't swallow LoadBlockedPlugins messages, as they're sent to every
    // blocked plugin.
    IPC_MESSAGE_HANDLER_GENERIC(ChromeViewMsg_LoadBlockedPlugins,
                                OnLoadBlockedPlugins(); handled = false)
    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForLoadingURL,
                        OnSetContentSettingsForLoadingURL)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ContentSettingsObserver::DidCommitProvisionalLoad(
    WebFrame* frame, bool is_new_navigation) {
  if (frame->parent())
    return; // Not a top-level navigation.

  NavigationState* state = NavigationState::FromDataSource(frame->dataSource());
  if (!state->was_within_same_page()) {
    // Clear "block" flags for the new page. This needs to happen before any of
    // allowScripts(), allowImage(), allowPlugins() is called for the new page
    // so that these functions can correctly detect that a piece of content
    // flipped from "not blocked" to "blocked".
    ClearBlockedContentSettings();
    plugins_temporarily_allowed_ = false;
  }

  GURL url = frame->document().url();

  if (frame->document().securityOrigin().toString() == "null" &&
      !url.SchemeIs(chrome::kFileScheme)) {
    // The Frame has a unique security origin. Instead of granting the frame
    // privileges based on it's URL, we fall back to the default content
    // settings.

    // We exempt file URLs here because we sandbox them by default, but folks
    // might reasonably want to supply non-default content settings for various
    // file URLs.
    if (default_content_settings_)
      SetContentSettings(*default_content_settings_);
    return;
  }

  // If we start failing this DCHECK, please makes sure we don't regress
  // this bug: http://code.google.com/p/chromium/issues/detail?id=79304
  DCHECK(!url.SchemeIs(chrome::kDataScheme));

  // Set content settings. Default them from the parent window if one exists.
  // This makes sure about:blank windows work as expected.
  HostContentSettings::iterator host_content_settings =
      host_content_settings_.find(url);
  if (host_content_settings != host_content_settings_.end()) {
    SetContentSettings(host_content_settings->second);

    // These content settings were merely recorded transiently for this load.
    // We can erase them now.  If at some point we reload this page, the
    // browser will send us new, up-to-date content settings.
    host_content_settings_.erase(host_content_settings);
  } else if (frame->opener()) {
    // The opener's view is not guaranteed to be non-null (it could be
    // detached from its page but not yet destructed).
    if (WebView* opener_view = frame->opener()->view()) {
      content::RenderView* opener =
          content::RenderView::FromWebView(opener_view);
      ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener);
      SetContentSettings(observer->current_content_settings_);
    }
  }
}

bool ContentSettingsObserver::AllowDatabase(WebFrame* frame,
                                            const WebString& name,
                                            const WebString& display_name,
                                            unsigned long estimated_size) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.

  bool result = false;
  Send(new ChromeViewHostMsg_AllowDatabase(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()),
      name, display_name, &result));
  return result;
}

bool ContentSettingsObserver::AllowFileSystem(WebFrame* frame) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.

  bool result = false;
  Send(new ChromeViewHostMsg_AllowFileSystem(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()), &result));
  return result;
}

bool ContentSettingsObserver::AllowImage(WebFrame* frame,
                                         bool enabled_per_settings,
                                         const WebURL& image_url) {
  if (IsWhitelistedForContentSettings(frame))
    return true;

  bool allow = enabled_per_settings;
  const GURL& primary_url = GetOriginOrURL(frame);
  GURL secondary_url(image_url);
  if (image_setting_rules_ &&
      enabled_per_settings) {
    ContentSettingsForOneType::const_iterator it;
    for (it = image_setting_rules_->begin();
         it != image_setting_rules_->end(); ++it) {
      if (it->primary_pattern.Matches(primary_url) &&
          it->secondary_pattern.Matches(secondary_url)) {
        allow = (it->setting != CONTENT_SETTING_BLOCK);
        break;
      }
    }
  }

  if (!allow)
    DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
  return allow;
}

bool ContentSettingsObserver::AllowIndexedDB(WebFrame* frame,
                                             const WebString& name,
                                             const WebSecurityOrigin& origin) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.

  bool result = false;
  Send(new ChromeViewHostMsg_AllowIndexedDB(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()),
      name, &result));
  return result;
}

bool ContentSettingsObserver::AllowPlugins(WebFrame* frame,
                                           bool enabled_per_settings) {
  return enabled_per_settings;
}

bool ContentSettingsObserver::AllowScript(WebFrame* frame,
                                          bool enabled_per_settings) {
  if (enabled_per_settings &&
      AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT)) {
    return true;
  }

  if (IsWhitelistedForContentSettings(frame))
    return true;

  return false;  // Other protocols fall through here.
}

bool ContentSettingsObserver::AllowStorage(WebFrame* frame, bool local) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.
  bool result = false;

  StoragePermissionsKey key(
      GURL(frame->document().securityOrigin().toString()), local);
  std::map<StoragePermissionsKey, bool>::const_iterator permissions =
      cached_storage_permissions_.find(key);
  if (permissions != cached_storage_permissions_.end())
    return permissions->second;

  Send(new ChromeViewHostMsg_AllowDOMStorage(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()),
      local ? DOM_STORAGE_LOCAL : DOM_STORAGE_SESSION,
      &result));
  cached_storage_permissions_[key] = result;
  return result;
}

void ContentSettingsObserver::DidNotAllowPlugins(WebFrame* frame) {
  DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
}

void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) {
  DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
}

void ContentSettingsObserver::OnSetContentSettingsForLoadingURL(
    const GURL& url,
    const ContentSettings& content_settings) {
  host_content_settings_[url] = content_settings;
}

void ContentSettingsObserver::OnLoadBlockedPlugins() {
  plugins_temporarily_allowed_ = true;
}

bool ContentSettingsObserver::AllowContentType(
    ContentSettingsType settings_type) {
  // CONTENT_SETTING_ASK is only valid for cookies.
  return current_content_settings_.settings[settings_type] !=
      CONTENT_SETTING_BLOCK;
}

void ContentSettingsObserver::ClearBlockedContentSettings() {
  for (size_t i = 0; i < arraysize(content_blocked_); ++i)
    content_blocked_[i] = false;
  cached_storage_permissions_.clear();
}
<commit_msg>DevTools: add chrome-devtools to the content settings whitelist.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/content_settings_observer.h"

#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"

using WebKit::WebDataSource;
using WebKit::WebFrame;
using WebKit::WebFrameClient;
using WebKit::WebSecurityOrigin;
using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebView;
using content::NavigationState;

namespace {

// True if |frame| contains content that is white-listed for content settings.
static bool IsWhitelistedForContentSettings(WebFrame* frame) {
  WebSecurityOrigin origin = frame->document().securityOrigin();
  if (origin.isEmpty())
    return false;  // Uninitialized document?

  if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
    return true;  // Browser UI elements should still work.

  if (EqualsASCII(origin.protocol(), chrome::kChromeDevToolsScheme))
    return true;  // DevTools UI elements should still work.

  // If the scheme is ftp: or file:, an empty file name indicates a directory
  // listing, which requires JavaScript to function properly.
  GURL document_url = frame->document().url();
  const char* kDirProtocols[] = { chrome::kFtpScheme, chrome::kFileScheme };
  for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
    if (EqualsASCII(origin.protocol(), kDirProtocols[i])) {
      return document_url.SchemeIs(kDirProtocols[i]) &&
             document_url.ExtractFileName().empty();
    }
  }

  return false;
}

GURL GetOriginOrURL(const WebFrame* frame) {
  WebString top_origin = frame->top()->document().securityOrigin().toString();
  // The the |top_origin| is unique ("null") e.g., for file:// URLs. Use the
  // document URL as the primary URL in those cases.
  if (top_origin == "null")
    return frame->document().url();
  return GURL(top_origin);
}

}  // namespace

ContentSettingsObserver::ContentSettingsObserver(
    content::RenderView* render_view)
    : content::RenderViewObserver(render_view),
      content::RenderViewObserverTracker<ContentSettingsObserver>(render_view),
      default_content_settings_(NULL),
      image_setting_rules_(NULL),
      plugins_temporarily_allowed_(false) {
  ClearBlockedContentSettings();
}

ContentSettingsObserver::~ContentSettingsObserver() {
}

void ContentSettingsObserver::SetContentSettings(
    const ContentSettings& settings) {
  current_content_settings_ = settings;
}

void ContentSettingsObserver::SetDefaultContentSettings(
    const ContentSettings* settings) {
  default_content_settings_ = settings;
}

void ContentSettingsObserver::SetImageSettingRules(
    const ContentSettingsForOneType* image_setting_rules) {
  image_setting_rules_ = image_setting_rules;
}

ContentSetting ContentSettingsObserver::GetContentSetting(
    ContentSettingsType type) {
  // Don't call this for plug-ins.
  DCHECK_NE(CONTENT_SETTINGS_TYPE_PLUGINS, type);
  return current_content_settings_.settings[type];
}

void ContentSettingsObserver::DidBlockContentType(
    ContentSettingsType settings_type,
    const std::string& resource_identifier) {
  // Always send a message when |resource_identifier| is not empty, to tell the
  // browser which resource was blocked (otherwise the browser will only show
  // the first resource to be blocked, and none that are blocked at a later
  // time).
  if (!content_blocked_[settings_type] || !resource_identifier.empty()) {
    content_blocked_[settings_type] = true;
    Send(new ChromeViewHostMsg_ContentBlocked(routing_id(), settings_type,
                                        resource_identifier));
  }
}

bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message)
    // Don't swallow LoadBlockedPlugins messages, as they're sent to every
    // blocked plugin.
    IPC_MESSAGE_HANDLER_GENERIC(ChromeViewMsg_LoadBlockedPlugins,
                                OnLoadBlockedPlugins(); handled = false)
    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForLoadingURL,
                        OnSetContentSettingsForLoadingURL)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ContentSettingsObserver::DidCommitProvisionalLoad(
    WebFrame* frame, bool is_new_navigation) {
  if (frame->parent())
    return; // Not a top-level navigation.

  NavigationState* state = NavigationState::FromDataSource(frame->dataSource());
  if (!state->was_within_same_page()) {
    // Clear "block" flags for the new page. This needs to happen before any of
    // allowScripts(), allowImage(), allowPlugins() is called for the new page
    // so that these functions can correctly detect that a piece of content
    // flipped from "not blocked" to "blocked".
    ClearBlockedContentSettings();
    plugins_temporarily_allowed_ = false;
  }

  GURL url = frame->document().url();

  if (frame->document().securityOrigin().toString() == "null" &&
      !url.SchemeIs(chrome::kFileScheme)) {
    // The Frame has a unique security origin. Instead of granting the frame
    // privileges based on it's URL, we fall back to the default content
    // settings.

    // We exempt file URLs here because we sandbox them by default, but folks
    // might reasonably want to supply non-default content settings for various
    // file URLs.
    if (default_content_settings_)
      SetContentSettings(*default_content_settings_);
    return;
  }

  // If we start failing this DCHECK, please makes sure we don't regress
  // this bug: http://code.google.com/p/chromium/issues/detail?id=79304
  DCHECK(!url.SchemeIs(chrome::kDataScheme));

  // Set content settings. Default them from the parent window if one exists.
  // This makes sure about:blank windows work as expected.
  HostContentSettings::iterator host_content_settings =
      host_content_settings_.find(url);
  if (host_content_settings != host_content_settings_.end()) {
    SetContentSettings(host_content_settings->second);

    // These content settings were merely recorded transiently for this load.
    // We can erase them now.  If at some point we reload this page, the
    // browser will send us new, up-to-date content settings.
    host_content_settings_.erase(host_content_settings);
  } else if (frame->opener()) {
    // The opener's view is not guaranteed to be non-null (it could be
    // detached from its page but not yet destructed).
    if (WebView* opener_view = frame->opener()->view()) {
      content::RenderView* opener =
          content::RenderView::FromWebView(opener_view);
      ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener);
      SetContentSettings(observer->current_content_settings_);
    }
  }
}

bool ContentSettingsObserver::AllowDatabase(WebFrame* frame,
                                            const WebString& name,
                                            const WebString& display_name,
                                            unsigned long estimated_size) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.

  bool result = false;
  Send(new ChromeViewHostMsg_AllowDatabase(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()),
      name, display_name, &result));
  return result;
}

bool ContentSettingsObserver::AllowFileSystem(WebFrame* frame) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.

  bool result = false;
  Send(new ChromeViewHostMsg_AllowFileSystem(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()), &result));
  return result;
}

bool ContentSettingsObserver::AllowImage(WebFrame* frame,
                                         bool enabled_per_settings,
                                         const WebURL& image_url) {
  if (IsWhitelistedForContentSettings(frame))
    return true;

  bool allow = enabled_per_settings;
  const GURL& primary_url = GetOriginOrURL(frame);
  GURL secondary_url(image_url);
  if (image_setting_rules_ &&
      enabled_per_settings) {
    ContentSettingsForOneType::const_iterator it;
    for (it = image_setting_rules_->begin();
         it != image_setting_rules_->end(); ++it) {
      if (it->primary_pattern.Matches(primary_url) &&
          it->secondary_pattern.Matches(secondary_url)) {
        allow = (it->setting != CONTENT_SETTING_BLOCK);
        break;
      }
    }
  }

  if (!allow)
    DidBlockContentType(CONTENT_SETTINGS_TYPE_IMAGES, std::string());
  return allow;
}

bool ContentSettingsObserver::AllowIndexedDB(WebFrame* frame,
                                             const WebString& name,
                                             const WebSecurityOrigin& origin) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.

  bool result = false;
  Send(new ChromeViewHostMsg_AllowIndexedDB(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()),
      name, &result));
  return result;
}

bool ContentSettingsObserver::AllowPlugins(WebFrame* frame,
                                           bool enabled_per_settings) {
  return enabled_per_settings;
}

bool ContentSettingsObserver::AllowScript(WebFrame* frame,
                                          bool enabled_per_settings) {
  if (enabled_per_settings &&
      AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT)) {
    return true;
  }

  if (IsWhitelistedForContentSettings(frame))
    return true;

  return false;  // Other protocols fall through here.
}

bool ContentSettingsObserver::AllowStorage(WebFrame* frame, bool local) {
  if (frame->document().securityOrigin().isEmpty() ||
      frame->top()->document().securityOrigin().isEmpty())
    return false; // Uninitialized document.
  bool result = false;

  StoragePermissionsKey key(
      GURL(frame->document().securityOrigin().toString()), local);
  std::map<StoragePermissionsKey, bool>::const_iterator permissions =
      cached_storage_permissions_.find(key);
  if (permissions != cached_storage_permissions_.end())
    return permissions->second;

  Send(new ChromeViewHostMsg_AllowDOMStorage(
      routing_id(), GURL(frame->document().securityOrigin().toString()),
      GURL(frame->top()->document().securityOrigin().toString()),
      local ? DOM_STORAGE_LOCAL : DOM_STORAGE_SESSION,
      &result));
  cached_storage_permissions_[key] = result;
  return result;
}

void ContentSettingsObserver::DidNotAllowPlugins(WebFrame* frame) {
  DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS, std::string());
}

void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) {
  DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string());
}

void ContentSettingsObserver::OnSetContentSettingsForLoadingURL(
    const GURL& url,
    const ContentSettings& content_settings) {
  host_content_settings_[url] = content_settings;
}

void ContentSettingsObserver::OnLoadBlockedPlugins() {
  plugins_temporarily_allowed_ = true;
}

bool ContentSettingsObserver::AllowContentType(
    ContentSettingsType settings_type) {
  // CONTENT_SETTING_ASK is only valid for cookies.
  return current_content_settings_.settings[settings_type] !=
      CONTENT_SETTING_BLOCK;
}

void ContentSettingsObserver::ClearBlockedContentSettings() {
  for (size_t i = 0; i < arraysize(content_blocked_); ++i)
    content_blocked_[i] = false;
  cached_storage_permissions_.clear();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2003-2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307  USA
 */

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#include "base/Log.h"
#include "base/util/utils.h"

bool saveFile(const char *filename, const char *buffer, size_t len, bool binary)
{
	const char *mode = binary ? "wb" : "w" ;

    FILE *f = fopen(filename, "w");

    if(!f)
        return false;

    if (fwrite(buffer, sizeof(char), len, f) != len) {
        fclose(f);
        return false;
    }
    fclose(f);

    return true;
}

bool readFile(const char* path, char **message, size_t *len, bool binary)
{
    FILE *f = NULL;
    size_t msglen=0;
    char *msg=0;
    const char *mode = binary ? "rb" : "r" ;
    struct stat buf;
    bool res = false;

    f = fopen(path, mode);
    if ( !f ) {
        goto done;
    }
    if ( fstat(fileno(f), &buf) ) {
        goto done;
    }

    msglen = buf.st_size;
    msg = new char[msglen+1];
    msg[msglen] = 0;

    *len=fread(msg, sizeof(char), msglen, f);
    if ( ferror(f) || *len < msglen ){
        goto done;
    }

    // Set return parameters
    *message=msg;
    msg = 0;
    res = true;

  done:
    if (f) {
        fclose(f);
    }
    if (msg) {
        delete [] msg;
    }

    return res;
}

char** readDir(char* name, int *count, bool onlyCount) {
    char **entries = NULL;
    *count = 0;

    // count entries
    int total = 0;
    DIR *dir = opendir(name);
    if (dir) {
        struct dirent *entry = readdir(dir);
        while (entry) {
            if (strcmp(entry->d_name, ".") &&
                strcmp(entry->d_name, "..")) {
                total++;
            }
            entry = readdir(dir);
        }

        if (!onlyCount && total) {
            entries = new char *[total];

            rewinddir(dir);
            entry = readdir(dir);
            while (entry && *count < total) {
                if (strcmp(entry->d_name, ".") &&
                    strcmp(entry->d_name, "..")) {
                    entries[*count] = stringdup(entry->d_name);
                    ++*count;
                }
                entry = readdir(dir);
            }
        }
    }

    return entries;
}

unsigned long getFileModTime(const char* name)
{
    struct stat buf;

    return stat(name, &buf) ? 0 :
        buf.st_ctime > buf.st_mtime ? buf.st_ctime :
        buf.st_mtime;
}

// TODO: convert to the specified encoding, assuming wc is UTF-8
char* toMultibyte(const WCHAR *wc, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = wcstombs(NULL, wc, 0) + 1;
    if(length == -1) {
        LOG.error("toMultibyte: invalid string.");
        return strdup("");
    }
    char* ret = new char[length];
    wcstombs(ret, wc, length);

    return ret;
#else
    return stringdup(wc);
#endif
}

// TODO: convert to UTF-8 from the specified encoding
WCHAR* toWideChar(const char *mb, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = mbstowcs(NULL, mb, 0) + 1;
    if(length == -1) {
        LOG.error("toWideChar: invalid string.");
        return wcsdup(TEXT(""));
    }
    WCHAR* ret = new WCHAR[length];
    mbstowcs(ret, mb, length);

    return ret;
#else
    return stringdup(mb);
#endif
}

#ifdef USE_WCHAR
// FIXME-----------------------------------------------------------------------
//Overloading thread-safe version of wcstok (defined in Linux) to make it
//work like the non-thread safe version available on Windows (same as strtok).
// FIXME: adjust VOCL code to NOT use this but String::split and remove it!!
//-----------------------------------------------------------------------------
WCHAR *wcstok(WCHAR *s, const WCHAR *delim)
{
    static WCHAR *state = 0;
    return wcstok(s, delim, &state);
}
#endif

// Implemented using mkstemp() with a template hard-coded
// to /tmp. Because the API of mkTempFileName() cannot return
// an open file, the file has to be closed. This exposes
// the possibility for an attacker to replace the file
// before it is opened again if /tmp has incorrect permissions.
char *mkTempFileName(const char *name)
{
    char *filename = new char[strlen("/tmp/") + strlen(name) + strlen(".XXXXXX") + 1];
    int fd;

    sprintf(filename, "/tmp/%s.XXXXXX", name );
    fd = mkstemp(filename);
    if (fd == -1) {
        delete [] filename;
        return NULL;
    } else {
        close(fd);
        return filename;
    }
}

<commit_msg>use wstrdup instead of wcsdup<commit_after>/*
 * Copyright (C) 2003-2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307  USA
 */

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

#include "base/Log.h"
#include "base/util/utils.h"

bool saveFile(const char *filename, const char *buffer, size_t len, bool binary)
{
	const char *mode = binary ? "wb" : "w" ;

    FILE *f = fopen(filename, "w");

    if(!f)
        return false;

    if (fwrite(buffer, sizeof(char), len, f) != len) {
        fclose(f);
        return false;
    }
    fclose(f);

    return true;
}

bool readFile(const char* path, char **message, size_t *len, bool binary)
{
    FILE *f = NULL;
    size_t msglen=0;
    char *msg=0;
    const char *mode = binary ? "rb" : "r" ;
    struct stat buf;
    bool res = false;

    f = fopen(path, mode);
    if ( !f ) {
        goto done;
    }
    if ( fstat(fileno(f), &buf) ) {
        goto done;
    }

    msglen = buf.st_size;
    msg = new char[msglen+1];
    msg[msglen] = 0;

    *len=fread(msg, sizeof(char), msglen, f);
    if ( ferror(f) || *len < msglen ){
        goto done;
    }

    // Set return parameters
    *message=msg;
    msg = 0;
    res = true;

  done:
    if (f) {
        fclose(f);
    }
    if (msg) {
        delete [] msg;
    }

    return res;
}

char** readDir(char* name, int *count, bool onlyCount) {
    char **entries = NULL;
    *count = 0;

    // count entries
    int total = 0;
    DIR *dir = opendir(name);
    if (dir) {
        struct dirent *entry = readdir(dir);
        while (entry) {
            if (strcmp(entry->d_name, ".") &&
                strcmp(entry->d_name, "..")) {
                total++;
            }
            entry = readdir(dir);
        }

        if (!onlyCount && total) {
            entries = new char *[total];

            rewinddir(dir);
            entry = readdir(dir);
            while (entry && *count < total) {
                if (strcmp(entry->d_name, ".") &&
                    strcmp(entry->d_name, "..")) {
                    entries[*count] = stringdup(entry->d_name);
                    ++*count;
                }
                entry = readdir(dir);
            }
        }
    }

    return entries;
}

unsigned long getFileModTime(const char* name)
{
    struct stat buf;

    return stat(name, &buf) ? 0 :
        buf.st_ctime > buf.st_mtime ? buf.st_ctime :
        buf.st_mtime;
}

// TODO: convert to the specified encoding, assuming wc is UTF-8
char* toMultibyte(const WCHAR *wc, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = wcstombs(NULL, wc, 0) + 1;
    if(length == -1) {
        LOG.error("toMultibyte: invalid string.");
        return strdup("");
    }
    char* ret = new char[length];
    wcstombs(ret, wc, length);

    return ret;
#else
    return stringdup(wc);
#endif
}

// TODO: convert to UTF-8 from the specified encoding
WCHAR* toWideChar(const char *mb, const char *encoding)
{
#ifdef USE_WCHAR
    size_t length = mbstowcs(NULL, mb, 0) + 1;
    if(length == -1) {
        LOG.error("toWideChar: invalid string.");
        return wstrdup(TEXT(""));
    }
    WCHAR* ret = new WCHAR[length];
    mbstowcs(ret, mb, length);

    return ret;
#else
    return stringdup(mb);
#endif
}

#ifdef USE_WCHAR
// FIXME-----------------------------------------------------------------------
//Overloading thread-safe version of wcstok (defined in Linux) to make it
//work like the non-thread safe version available on Windows (same as strtok).
// FIXME: adjust VOCL code to NOT use this but String::split and remove it!!
//-----------------------------------------------------------------------------
WCHAR *wcstok(WCHAR *s, const WCHAR *delim)
{
    static WCHAR *state = 0;
    return wcstok(s, delim, &state);
}
#endif

// Implemented using mkstemp() with a template hard-coded
// to /tmp. Because the API of mkTempFileName() cannot return
// an open file, the file has to be closed. This exposes
// the possibility for an attacker to replace the file
// before it is opened again if /tmp has incorrect permissions.
char *mkTempFileName(const char *name)
{
    char *filename = new char[strlen("/tmp/") + strlen(name) + strlen(".XXXXXX") + 1];
    int fd;

    sprintf(filename, "/tmp/%s.XXXXXX", name );
    fd = mkstemp(filename);
    if (fd == -1) {
        delete [] filename;
        return NULL;
    } else {
        close(fd);
        return filename;
    }
}

<|endoftext|>