<commit_before>/*
 * The NewReality Blockchain Project.
 * Copyright (C) 2013, 2016 Swirly Cloud Limited.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
#ifndef MVSD_MONGOOSE_HPP
#define MVSD_MONGOOSE_HPP

#include <bitcoin/explorer/dispatch.hpp>
#include "mongoose/mongoose.h"

#include <mvs/http/String.hpp>
#include <mvs/http/Exception_error.hpp>

/**
 * @addtogroup Web
 * @{
 */

namespace http {
namespace mg {

#define SESSION_COOKIE_NAME "mvss"

inline std::string_view operator+(const mg_str& str) noexcept
{
    return {str.p, str.len};
}

inline std::string_view operator+(const websocket_message& msg) noexcept
{
    return {reinterpret_cast<char*>(msg.data), msg.size};
}

class ToCommandArg{
public:
    auto argv() const noexcept { return argv_; }
    auto argc() const noexcept { return argc_; }
    void setargv0(std::string&& outside);

    static const int max_paramters{24};
protected:

    virtual void data_to_arg() noexcept = 0;
    const char* argv_[max_paramters]{{nullptr}};
    int argc_{0};

    std::vector<std::string> vargv_;
};

class HttpMessage : public ToCommandArg{
public:
    HttpMessage(http_message* impl) noexcept : impl_{impl} {}
    ~HttpMessage() noexcept = default;

    // Copy.
    // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1778
    HttpMessage(const HttpMessage&) noexcept = default;
    HttpMessage& operator=(const HttpMessage&) noexcept = default;

    // Move.
    HttpMessage(HttpMessage&&) noexcept = default;
    HttpMessage& operator=(HttpMessage&&) noexcept = default;

    auto get() const noexcept { return impl_; }
    auto method() const noexcept { return +impl_->method; }
    auto uri() const noexcept { return +impl_->uri; }
    auto proto() const noexcept { return +impl_->proto; }
    auto queryString() const noexcept { return +impl_->query_string; }
    auto header(const char* name) const noexcept
    {
      auto* val = mg_get_http_header(impl_, name);
      return val ? +*val : std::string_view{};
    }
    auto body() const noexcept { return +impl_->body; }

    void data_to_arg() noexcept override;

private:

    http_message* impl_;
};

class WebsocketMessage:public ToCommandArg { // connect to bx command-tool
public:
    WebsocketMessage(websocket_message* impl) noexcept : impl_{impl} {}
    ~WebsocketMessage() noexcept = default;

    // Copy.
    WebsocketMessage(const WebsocketMessage&) noexcept = default;
    WebsocketMessage& operator=(const WebsocketMessage&) noexcept = default;

    // Move.
    WebsocketMessage(WebsocketMessage&&) noexcept = default;
    WebsocketMessage& operator=(WebsocketMessage&&) noexcept = default;

    auto get() const noexcept { return impl_; }
    auto data() const noexcept { return reinterpret_cast<char*>(impl_->data); }
    auto size() const noexcept { return impl_->size; }

    void data_to_arg() noexcept override;
private:
    websocket_message* impl_;
};

struct Session{
        Session() = default;
        Session(uint64_t a1, double a2, double a3,
                std::string&& a4, uint16_t a5):
            id(a1), created(a2), last_used(a3), user(a4), state(a5){}
        ~Session() = default;

        uint64_t        id;
        double          created;
        double          last_used;
        std::string     user;
        uint16_t        state;
};

template <typename DerivedT>
class Mgr {
public:
    // Copy.
    Mgr(const Mgr&) = delete;
    Mgr& operator=(const Mgr&) = delete;

    // Move.
    Mgr(Mgr&&) = delete;
    Mgr& operator=(Mgr&&) = delete;

    mg_connection& bind(const char* addr)
    {
      auto* conn = mg_bind(&mgr_, addr, handler);
      if (!conn)
        throw Error{"mg_bind() failed"};
      conn->user_data = this;
      return *conn;
    }
    time_t poll(int milli) { return mg_mgr_poll(&mgr_, milli); }

    // session control
    static void login_handler(mg_connection* conn, int ev, void* data){
       http_message* hm = static_cast<http_message*>(data);
       auto* self = static_cast<DerivedT*>(conn->user_data);

       if (mg_vcmp(&hm->method, "POST") != 0) {
           mg_serve_http(conn, hm, self->get_httpoptions());
       }else{
           char user[50], pass[50];
           auto ul = mg_get_http_var(&hm->body, "user", user, sizeof(user));
           auto pl = mg_get_http_var(&hm->body, "pass", pass, sizeof(pass));
           if (ul > 0 && pl > 0) {
              if(!self->user_auth({user, std::strlen(user)}, {pass, std::strlen(pass)})){
                mg_printf(conn, "HTTP/1.0 403 Unauthorized\r\n\r\nWrong password.\r\n");
              }

              auto ret = self->push_session({user, std::strlen(user)}, hm);
              std::ostringstream shead;
              shead<<"Set-Cookie: " SESSION_COOKIE_NAME "="<<ret->id<<"; path=/";
              mg_http_send_redirect(conn, 302, mg_mk_str("/"), mg_mk_str(shead.str().c_str()));

           } else {
              mg_printf(conn, "HTTP/1.0 400 Bad Request\r\n\r\nuser, pass required.\r\n");
           }
       }
       conn->flags |= MG_F_SEND_AND_CLOSE;
    }

    static void logout_handler(mg_connection* conn, int ev, void* data){
       http_message* hm = static_cast<http_message*>(data);
       auto* self = static_cast<DerivedT*>(conn->user_data);
    }

    constexpr static const double session_check_interval = 5.0;

protected:
    Mgr() noexcept { mg_mgr_init(&mgr_, this); }
    ~Mgr() noexcept { mg_mgr_free(&mgr_); }

private:

    static void handler(mg_connection* conn, int event, void* data)
    {
       http_message* hm = static_cast<http_message*>(data);
       websocket_message* ws = static_cast<websocket_message*>(data);
       auto* self = static_cast<DerivedT*>(conn->user_data);

       switch (event) {
       case MG_EV_CLOSE:{
            if (conn->flags & MG_F_IS_WEBSOCKET) {
                //self->websocketBroadcast(*conn, "left", 4);
            }else{
                conn->user_data = nullptr;
            }
            break;
        }
       case MG_EV_HTTP_REQUEST:{
            // rpc call
            if (mg_ncasecmp((&hm->uri)->p, "/rpc", 4u) == 0){
                self->httpRpcRequest(*conn, hm);
                break;
            }
            // register call
            if (mg_ncasecmp((&hm->uri)->p, "/api/getnewaccount", 18u) == 0) {
                self->httpRequest(*conn, hm);
                break;
            }

            // login required for other calls
            if (!self->get_from_session_list(hm)) {
                mg_http_send_redirect(conn, 302, mg_mk_str("/login.html"),
                        mg_mk_str(nullptr));
                conn->flags |= MG_F_SEND_AND_CLOSE;
                break;
            }

            // logined, http request process
            if (mg_ncasecmp((&hm->uri)->p, "/api", 4u) == 0) {
                self->httpRequest(*conn, hm);
            }else{
                self->httpStatic(*conn, hm);
                conn->flags |= MG_F_SEND_AND_CLOSE;
            }
            break;
        }
        case MG_EV_WEBSOCKET_HANDSHAKE_DONE:{
            self->websocketSend(conn, "connected", 9);
            break;
        }
        case MG_EV_WEBSOCKET_FRAME:{
            self->websocketSend(*conn, ws);
            break;
        }
        case MG_EV_SSI_CALL:{
        }
        case MG_EV_TIMER:{
            self->check_sessions();
            mg_set_timer(conn, mg_time() + self->session_check_interval);
            break;
        }
       }// switch
    }// handler

    mg_mgr mgr_;
};

} // mg
} // http

/** @} */

#endif // MVSD_MONGOOSE_HPP
<commit_msg>fix bugs for paramters input<commit_after>/*
 * The NewReality Blockchain Project.
 * Copyright (C) 2013, 2016 Swirly Cloud Limited.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
#ifndef MVSD_MONGOOSE_HPP
#define MVSD_MONGOOSE_HPP

#include <bitcoin/explorer/dispatch.hpp>
#include "mongoose/mongoose.h"

#include <mvs/http/String.hpp>
#include <mvs/http/Exception_error.hpp>

/**
 * @addtogroup Web
 * @{
 */

namespace http {
namespace mg {

#define SESSION_COOKIE_NAME "mvss"

inline std::string_view operator+(const mg_str& str) noexcept
{
    return {str.p, str.len};
}

inline std::string_view operator+(const websocket_message& msg) noexcept
{
    return {reinterpret_cast<char*>(msg.data), msg.size};
}

class ToCommandArg{
public:
    auto argv() const noexcept { return argv_; }
    auto argc() const noexcept { return argc_; }
    void setargv0(std::string&& outside);

    static const int max_paramters{32};
protected:

    virtual void data_to_arg() noexcept = 0;
    const char* argv_[max_paramters]{{nullptr}};
    int argc_{0};

    std::vector<std::string> vargv_;
};

class HttpMessage : public ToCommandArg{
public:
    HttpMessage(http_message* impl) noexcept : impl_{impl} {}
    ~HttpMessage() noexcept = default;

    // Copy.
    // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1778
    HttpMessage(const HttpMessage&) noexcept = default;
    HttpMessage& operator=(const HttpMessage&) noexcept = default;

    // Move.
    HttpMessage(HttpMessage&&) noexcept = default;
    HttpMessage& operator=(HttpMessage&&) noexcept = default;

    auto get() const noexcept { return impl_; }
    auto method() const noexcept { return +impl_->method; }
    auto uri() const noexcept { return +impl_->uri; }
    auto proto() const noexcept { return +impl_->proto; }
    auto queryString() const noexcept { return +impl_->query_string; }
    auto header(const char* name) const noexcept
    {
      auto* val = mg_get_http_header(impl_, name);
      return val ? +*val : std::string_view{};
    }
    auto body() const noexcept { return +impl_->body; }

    void data_to_arg() noexcept override;

private:

    http_message* impl_;
};

class WebsocketMessage:public ToCommandArg { // connect to bx command-tool
public:
    WebsocketMessage(websocket_message* impl) noexcept : impl_{impl} {}
    ~WebsocketMessage() noexcept = default;

    // Copy.
    WebsocketMessage(const WebsocketMessage&) noexcept = default;
    WebsocketMessage& operator=(const WebsocketMessage&) noexcept = default;

    // Move.
    WebsocketMessage(WebsocketMessage&&) noexcept = default;
    WebsocketMessage& operator=(WebsocketMessage&&) noexcept = default;

    auto get() const noexcept { return impl_; }
    auto data() const noexcept { return reinterpret_cast<char*>(impl_->data); }
    auto size() const noexcept { return impl_->size; }

    void data_to_arg() noexcept override;
private:
    websocket_message* impl_;
};

struct Session{
        Session() = default;
        Session(uint64_t a1, double a2, double a3,
                std::string&& a4, uint16_t a5):
            id(a1), created(a2), last_used(a3), user(a4), state(a5){}
        ~Session() = default;

        uint64_t        id;
        double          created;
        double          last_used;
        std::string     user;
        uint16_t        state;
};

template <typename DerivedT>
class Mgr {
public:
    // Copy.
    Mgr(const Mgr&) = delete;
    Mgr& operator=(const Mgr&) = delete;

    // Move.
    Mgr(Mgr&&) = delete;
    Mgr& operator=(Mgr&&) = delete;

    mg_connection& bind(const char* addr)
    {
      auto* conn = mg_bind(&mgr_, addr, handler);
      if (!conn)
        throw Error{"mg_bind() failed"};
      conn->user_data = this;
      return *conn;
    }
    time_t poll(int milli) { return mg_mgr_poll(&mgr_, milli); }

    // session control
    static void login_handler(mg_connection* conn, int ev, void* data){
       http_message* hm = static_cast<http_message*>(data);
       auto* self = static_cast<DerivedT*>(conn->user_data);

       if (mg_vcmp(&hm->method, "POST") != 0) {
           mg_serve_http(conn, hm, self->get_httpoptions());
       }else{
           char user[50], pass[50];
           auto ul = mg_get_http_var(&hm->body, "user", user, sizeof(user));
           auto pl = mg_get_http_var(&hm->body, "pass", pass, sizeof(pass));
           if (ul > 0 && pl > 0) {
              if(!self->user_auth({user, std::strlen(user)}, {pass, std::strlen(pass)})){
                mg_printf(conn, "HTTP/1.0 403 Unauthorized\r\n\r\nWrong password.\r\n");
              }

              auto ret = self->push_session({user, std::strlen(user)}, hm);
              std::ostringstream shead;
              shead<<"Set-Cookie: " SESSION_COOKIE_NAME "="<<ret->id<<"; path=/";
              mg_http_send_redirect(conn, 302, mg_mk_str("/"), mg_mk_str(shead.str().c_str()));

           } else {
              mg_printf(conn, "HTTP/1.0 400 Bad Request\r\n\r\nuser, pass required.\r\n");
           }
       }
       conn->flags |= MG_F_SEND_AND_CLOSE;
    }

    static void logout_handler(mg_connection* conn, int ev, void* data){
       http_message* hm = static_cast<http_message*>(data);
       auto* self = static_cast<DerivedT*>(conn->user_data);
    }

    constexpr static const double session_check_interval = 5.0;

protected:
    Mgr() noexcept { mg_mgr_init(&mgr_, this); }
    ~Mgr() noexcept { mg_mgr_free(&mgr_); }

private:

    static void handler(mg_connection* conn, int event, void* data)
    {
       http_message* hm = static_cast<http_message*>(data);
       websocket_message* ws = static_cast<websocket_message*>(data);
       auto* self = static_cast<DerivedT*>(conn->user_data);

       switch (event) {
       case MG_EV_CLOSE:{
            if (conn->flags & MG_F_IS_WEBSOCKET) {
                //self->websocketBroadcast(*conn, "left", 4);
            }else{
                conn->user_data = nullptr;
            }
            break;
        }
       case MG_EV_HTTP_REQUEST:{
            // rpc call
            if (mg_ncasecmp((&hm->uri)->p, "/rpc", 4u) == 0){
                self->httpRpcRequest(*conn, hm);
                break;
            }
            // register call
            if (mg_ncasecmp((&hm->uri)->p, "/api/getnewaccount", 18u) == 0) {
                self->httpRequest(*conn, hm);
                break;
            }

            // login required for other calls
            if (!self->get_from_session_list(hm)) {
                mg_http_send_redirect(conn, 302, mg_mk_str("/login.html"),
                        mg_mk_str(nullptr));
                conn->flags |= MG_F_SEND_AND_CLOSE;
                break;
            }

            // logined, http request process
            if (mg_ncasecmp((&hm->uri)->p, "/api", 4u) == 0) {
                self->httpRequest(*conn, hm);
            }else{
                self->httpStatic(*conn, hm);
                conn->flags |= MG_F_SEND_AND_CLOSE;
            }
            break;
        }
        case MG_EV_WEBSOCKET_HANDSHAKE_DONE:{
            self->websocketSend(conn, "connected", 9);
            break;
        }
        case MG_EV_WEBSOCKET_FRAME:{
            self->websocketSend(*conn, ws);
            break;
        }
        case MG_EV_SSI_CALL:{
        }
        case MG_EV_TIMER:{
            self->check_sessions();
            mg_set_timer(conn, mg_time() + self->session_check_interval);
            break;
        }
       }// switch
    }// handler

    mg_mgr mgr_;
};

} // mg
} // http

/** @} */

#endif // MVSD_MONGOOSE_HPP
<|endoftext|>


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

#include "chrome/browser/chrome_elf_init_win.h"

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_reg_util_win.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome_elf/chrome_elf_constants.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/variations_associated_data.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "version.h"  // NOLINT

namespace {

const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled";

class ChromeBlacklistTrialTest : public testing::Test {
 protected:
  ChromeBlacklistTrialTest() {}
  ~ChromeBlacklistTrialTest() override {}

  void SetUp() override {
    testing::Test::SetUp();

    override_manager_.OverrideRegistry(HKEY_CURRENT_USER);

    blacklist_registry_key_.reset(
        new base::win::RegKey(HKEY_CURRENT_USER,
                              blacklist::kRegistryBeaconPath,
                              KEY_QUERY_VALUE | KEY_SET_VALUE));
  }

  DWORD GetBlacklistState() {
    DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX;
    blacklist_registry_key_->ReadValueDW(blacklist::kBeaconState,
                                         &blacklist_state);

    return blacklist_state;
  }

  base::string16 GetBlacklistVersion() {
    base::string16 blacklist_version;
    blacklist_registry_key_->ReadValue(blacklist::kBeaconVersion,
                                       &blacklist_version);

    return blacklist_version;
  }

  scoped_ptr<base::win::RegKey> blacklist_registry_key_;
  registry_util::RegistryOverrideManager override_manager_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ChromeBlacklistTrialTest);
};

// Ensure that the default trial sets up the blacklist beacons.
TEST_F(ChromeBlacklistTrialTest, DefaultRun) {
  // Set some dummy values as beacons.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_DISABLED);
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, L"Data");

  // This setup code should result in the default group, which should have
  // the blacklist set up.
  InitializeChromeElf();

  // Ensure the beacon values are now correct, indicating the
  // blacklist beacon was setup.
  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());
  chrome::VersionInfo version_info;
  base::string16 version(base::UTF8ToUTF16(version_info.Version()));
  ASSERT_EQ(version, GetBlacklistVersion());
}

// Ensure that the blacklist is disabled for any users in the
// "BlacklistDisabled" finch group.
TEST_F(ChromeBlacklistTrialTest, BlacklistDisabledRun) {
  // Set the beacons to enabled values.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_ENABLED);
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, L"Data");

  // Create the field trial with the blacklist disabled group.
  base::FieldTrialList field_trial_list(
    new metrics::SHA1EntropyProvider("test"));

  scoped_refptr<base::FieldTrial> trial(
    base::FieldTrialList::CreateFieldTrial(
      kBrowserBlacklistTrialName, kBrowserBlacklistTrialDisabledGroupName));

  // This setup code should now delete any existing blacklist beacons.
  InitializeChromeElf();

  // Ensure invalid values are returned to indicate that the beacon
  // values are indeed gone.
  ASSERT_EQ(blacklist::BLACKLIST_STATE_MAX, GetBlacklistState());
  ASSERT_EQ(base::string16(), GetBlacklistVersion());
}

TEST_F(ChromeBlacklistTrialTest, VerifyFirstRun) {
  BrowserBlacklistBeaconSetup();

  // Verify the state is properly set after the first run.
  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());

  chrome::VersionInfo version_info;
  base::string16 version(base::UTF8ToUTF16(version_info.Version()));
  ASSERT_EQ(version, GetBlacklistVersion());
}

TEST_F(ChromeBlacklistTrialTest, BlacklistFailed) {
  // Ensure when the blacklist set up failed we set the state to disabled for
  // future runs.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion,
                                      TEXT(CHROME_VERSION_STRING));
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_SETUP_FAILED);

  BrowserBlacklistBeaconSetup();

  ASSERT_EQ(blacklist::BLACKLIST_DISABLED, GetBlacklistState());
}

TEST_F(ChromeBlacklistTrialTest, VersionChanged) {
  // Mark the blacklist as disabled for an older version, it should
  // get enabled for this new version.  Also record a non-zero number of
  // setup failures, which should be reset to zero.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion,
                                      L"old_version");
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_DISABLED);
  blacklist_registry_key_->WriteValue(blacklist::kBeaconAttemptCount,
                                      blacklist::kBeaconMaxAttempts);

  BrowserBlacklistBeaconSetup();

  // The beacon should now be marked as enabled for the current version.
  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());

  chrome::VersionInfo version_info;
  base::string16 expected_version(base::UTF8ToUTF16(version_info.Version()));
  ASSERT_EQ(expected_version, GetBlacklistVersion());

  // The counter should be reset.
  DWORD attempt_count = blacklist::kBeaconMaxAttempts;
  blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount,
                                       &attempt_count);
  ASSERT_EQ(static_cast<DWORD>(0), attempt_count);
}

TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) {
  // Create the field trial with the blacklist enabled group.
  base::FieldTrialList field_trial_list(
      new metrics::SHA1EntropyProvider("test"));

  scoped_refptr<base::FieldTrial> trial(base::FieldTrialList::CreateFieldTrial(
      kBrowserBlacklistTrialName, kBrowserBlacklistTrialEnabledGroupName));

  // Set up the trial with the desired parameters.
  std::map<std::string, std::string> desired_params;
  desired_params["TestDllName1"] = "TestDll1.dll";
  desired_params["TestDllName2"] = "TestDll2.dll";

  variations::AssociateVariationParams(
      kBrowserBlacklistTrialName,
      kBrowserBlacklistTrialEnabledGroupName,
      desired_params);

  // This should add the dlls in those parameters to the registry.
  AddFinchBlacklistToRegistry();

  // Check that all the values in desired_params were added to the registry.
  base::win::RegKey finch_blacklist_registry_key(
      HKEY_CURRENT_USER,
      blacklist::kRegistryFinchListPath,
      KEY_QUERY_VALUE | KEY_SET_VALUE);

  ASSERT_EQ(desired_params.size(),
            finch_blacklist_registry_key.GetValueCount());

  for (std::map<std::string, std::string>::iterator it = desired_params.begin();
       it != desired_params.end();
       ++it) {
    std::wstring name = base::UTF8ToWide(it->first);
    ASSERT_TRUE(finch_blacklist_registry_key.HasValue(name.c_str()));
  }
}

}  // namespace
<commit_msg>Add TestBrowserThreadBundle to ChromeBlacklistTrialTest.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chrome_elf_init_win.h"

#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_reg_util_win.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome_elf/chrome_elf_constants.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "version.h"  // NOLINT

namespace {

const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled";

class ChromeBlacklistTrialTest : public testing::Test {
 protected:
  ChromeBlacklistTrialTest() {}
  ~ChromeBlacklistTrialTest() override {}

  void SetUp() override {
    testing::Test::SetUp();

    override_manager_.OverrideRegistry(HKEY_CURRENT_USER);

    blacklist_registry_key_.reset(
        new base::win::RegKey(HKEY_CURRENT_USER,
                              blacklist::kRegistryBeaconPath,
                              KEY_QUERY_VALUE | KEY_SET_VALUE));
  }

  DWORD GetBlacklistState() {
    DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX;
    blacklist_registry_key_->ReadValueDW(blacklist::kBeaconState,
                                         &blacklist_state);

    return blacklist_state;
  }

  base::string16 GetBlacklistVersion() {
    base::string16 blacklist_version;
    blacklist_registry_key_->ReadValue(blacklist::kBeaconVersion,
                                       &blacklist_version);

    return blacklist_version;
  }

  scoped_ptr<base::win::RegKey> blacklist_registry_key_;
  registry_util::RegistryOverrideManager override_manager_;
  content::TestBrowserThreadBundle test_browser_thread_bundle_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ChromeBlacklistTrialTest);
};

// Ensure that the default trial sets up the blacklist beacons.
TEST_F(ChromeBlacklistTrialTest, DefaultRun) {
  // Set some dummy values as beacons.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_DISABLED);
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, L"Data");

  // This setup code should result in the default group, which should have
  // the blacklist set up.
  InitializeChromeElf();

  // Ensure the beacon values are now correct, indicating the
  // blacklist beacon was setup.
  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());
  chrome::VersionInfo version_info;
  base::string16 version(base::UTF8ToUTF16(version_info.Version()));
  ASSERT_EQ(version, GetBlacklistVersion());
}

// Ensure that the blacklist is disabled for any users in the
// "BlacklistDisabled" finch group.
TEST_F(ChromeBlacklistTrialTest, BlacklistDisabledRun) {
  // Set the beacons to enabled values.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_ENABLED);
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, L"Data");

  // Create the field trial with the blacklist disabled group.
  base::FieldTrialList field_trial_list(
    new metrics::SHA1EntropyProvider("test"));

  scoped_refptr<base::FieldTrial> trial(
    base::FieldTrialList::CreateFieldTrial(
      kBrowserBlacklistTrialName, kBrowserBlacklistTrialDisabledGroupName));

  // This setup code should now delete any existing blacklist beacons.
  InitializeChromeElf();

  // Ensure invalid values are returned to indicate that the beacon
  // values are indeed gone.
  ASSERT_EQ(blacklist::BLACKLIST_STATE_MAX, GetBlacklistState());
  ASSERT_EQ(base::string16(), GetBlacklistVersion());
}

TEST_F(ChromeBlacklistTrialTest, VerifyFirstRun) {
  BrowserBlacklistBeaconSetup();

  // Verify the state is properly set after the first run.
  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());

  chrome::VersionInfo version_info;
  base::string16 version(base::UTF8ToUTF16(version_info.Version()));
  ASSERT_EQ(version, GetBlacklistVersion());
}

TEST_F(ChromeBlacklistTrialTest, BlacklistFailed) {
  // Ensure when the blacklist set up failed we set the state to disabled for
  // future runs.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion,
                                      TEXT(CHROME_VERSION_STRING));
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_SETUP_FAILED);

  BrowserBlacklistBeaconSetup();

  ASSERT_EQ(blacklist::BLACKLIST_DISABLED, GetBlacklistState());
}

TEST_F(ChromeBlacklistTrialTest, VersionChanged) {
  // Mark the blacklist as disabled for an older version, it should
  // get enabled for this new version.  Also record a non-zero number of
  // setup failures, which should be reset to zero.
  blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion,
                                      L"old_version");
  blacklist_registry_key_->WriteValue(blacklist::kBeaconState,
                                      blacklist::BLACKLIST_DISABLED);
  blacklist_registry_key_->WriteValue(blacklist::kBeaconAttemptCount,
                                      blacklist::kBeaconMaxAttempts);

  BrowserBlacklistBeaconSetup();

  // The beacon should now be marked as enabled for the current version.
  ASSERT_EQ(blacklist::BLACKLIST_ENABLED, GetBlacklistState());

  chrome::VersionInfo version_info;
  base::string16 expected_version(base::UTF8ToUTF16(version_info.Version()));
  ASSERT_EQ(expected_version, GetBlacklistVersion());

  // The counter should be reset.
  DWORD attempt_count = blacklist::kBeaconMaxAttempts;
  blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount,
                                       &attempt_count);
  ASSERT_EQ(static_cast<DWORD>(0), attempt_count);
}

TEST_F(ChromeBlacklistTrialTest, AddFinchBlacklistToRegistry) {
  // Create the field trial with the blacklist enabled group.
  base::FieldTrialList field_trial_list(
      new metrics::SHA1EntropyProvider("test"));

  scoped_refptr<base::FieldTrial> trial(base::FieldTrialList::CreateFieldTrial(
      kBrowserBlacklistTrialName, kBrowserBlacklistTrialEnabledGroupName));

  // Set up the trial with the desired parameters.
  std::map<std::string, std::string> desired_params;
  desired_params["TestDllName1"] = "TestDll1.dll";
  desired_params["TestDllName2"] = "TestDll2.dll";

  variations::AssociateVariationParams(
      kBrowserBlacklistTrialName,
      kBrowserBlacklistTrialEnabledGroupName,
      desired_params);

  // This should add the dlls in those parameters to the registry.
  AddFinchBlacklistToRegistry();

  // Check that all the values in desired_params were added to the registry.
  base::win::RegKey finch_blacklist_registry_key(
      HKEY_CURRENT_USER,
      blacklist::kRegistryFinchListPath,
      KEY_QUERY_VALUE | KEY_SET_VALUE);

  ASSERT_EQ(desired_params.size(),
            finch_blacklist_registry_key.GetValueCount());

  for (std::map<std::string, std::string>::iterator it = desired_params.begin();
       it != desired_params.end();
       ++it) {
    std::wstring name = base::UTF8ToWide(it->first);
    ASSERT_TRUE(finch_blacklist_registry_key.HasValue(name.c_str()));
  }
}

}  // namespace
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// condor includes
#include "condor_common.h"
#include "condor_qmgr.h"
#include "condor_config.h"

// local includes
#include "AviaryScheddPlugin.h"
#include "Axis2SoapProvider.h"
#include "SchedulerObject.h"

// Global from the condor_schedd, it's name
extern char * Name;

// Any key that begins with the '0' char is either the
// header or a cluster, i.e. not a job
#define IS_JOB(key) ((key) && '0' != (key)[0])

using namespace std;
using namespace aviary::job;
using namespace aviary::soap;

// global SchedulerObject
// TODO: convert to singleton
Axis2SoapProvider* provider = NULL;
SchedulerObject* schedulerObj = NULL;

void
AviaryScheddPlugin::earlyInitialize()
{

    // Since this plugin is registered with multiple
    // PluginManagers it may be initialized more than once,
    // and we don't want that
	static bool skip = false;
	if (skip) return; skip = true;

	// config then env for our all-important axis2 repo dir
    const char* log_file = "./aviary_job.axis2.log";
	string repo_path;
	char *tmp = NULL;
	if (tmp = param("WSFCPP_HOME")) {
		repo_path = tmp;
		free(tmp);
	}
	else if (tmp = getenv("WSFCPP_HOME")) {
		repo_path = tmp;
	}
	else {
		EXCEPT("No WSFCPP_HOME in config or env");
	}

	int port = param_integer("HTTP_PORT",9090);
	int level = param_integer("AXIS2_DEBUG_LEVEL",AXIS2_LOG_LEVEL_CRITICAL);

    // init transport here
    provider = new Axis2SoapProvider(level,log_file,repo_path.c_str());
    string axis_error;
    if (!provider->init(9090,AXIS2_HTTP_DEFAULT_SO_TIMEOUT,axis_error)) {
		dprintf(D_ALWAYS, "%s\n",axis_error.c_str());
        EXCEPT("Failed to initialize Axis2SoapProvider");
    }

	schedulerObj = SchedulerObject::getInstance();

	dirtyJobs = new DirtyJobsType();

	isHandlerRegistered = false;

	ReliSock *sock = new ReliSock;
	if (!sock) {
		EXCEPT("Failed to allocate transport socket");
	}
	if (!sock->assign(provider->getHttpListenerSocket())) {
		EXCEPT("Failed to bind transport socket");
	}
	int index;
	if (-1 == (index =
			   daemonCore->Register_Socket((Stream *) sock,
										   "Aviary Method Socket",
										   (SocketHandlercpp) ( &AviaryScheddPlugin::HandleTransportSocket ),
										   "Handler for Aviary Methods.",
										   this))) {
		EXCEPT("Failed to register transport socket");
	}

	dprintf(D_ALWAYS,"Axis2 listener on http port: %d\n",port);

	m_initialized = false;
}

void
AviaryScheddPlugin::initialize()
{
		// Since this plugin is registered with multiple
		// PluginManagers it may be initialized more than once,
		// and we don't want that
	static bool skip = false;
	if (skip) return; skip = true;

		// WalkJobQueue(int (*func)(ClassAd *))
	ClassAd *ad = GetNextJob(1);
	while (ad != NULL) {
		MyString key;
		PROC_ID id;
		int value;

		if (!ad->LookupInteger(ATTR_CLUSTER_ID, id.cluster)) {
			EXCEPT("%s on job is missing or not an integer", ATTR_CLUSTER_ID);
		}
		if (!ad->LookupInteger(ATTR_PROC_ID, id.proc)) {
			EXCEPT("%s on job is missing or not an integer", ATTR_PROC_ID);
		}
		if (!ad->LookupInteger(ATTR_JOB_STATUS, value)) {
			EXCEPT("%s on job is missing or not an integer", ATTR_JOB_STATUS);
		}

		key.sprintf("%d.%d", id.cluster, id.proc);

		processJob(key.Value(), ATTR_JOB_STATUS, value);

		FreeJobAd(ad);
		ad = GetNextJob(0);
	}

	m_initialized = true;
}

void
AviaryScheddPlugin::shutdown()
{
		// Since this plugin is registered with multiple
		// PluginManagers (eg, shadow) it may be shutdown
		// more than once, and we don't want that
	static bool skip = false;
	if (skip) return; skip = true;

	dprintf(D_FULLDEBUG, "AviaryScheddPlugin: shutting down...\n");

	if (schedulerObj) {
		delete schedulerObj;
		schedulerObj = NULL;
	}
}

void
AviaryScheddPlugin::update(int cmd, const ClassAd *ad)
{
	MyString hashKey;

	switch (cmd) {
	case UPDATE_SCHEDD_AD:
		dprintf(D_FULLDEBUG, "Received UPDATE_SCHEDD_AD\n");
		schedulerObj->update(*ad);
		break;
	default:
		dprintf(D_FULLDEBUG, "Unsupported command: %s\n",
				getCollectorCommandString(cmd));
	}
}

void
AviaryScheddPlugin::archive(const ClassAd */*ad*/) { };

void
AviaryScheddPlugin::newClassAd(const char */*key*/) { };

void
AviaryScheddPlugin::setAttribute(const char *key,
							   const char *name,
							   const char *value)
{
	if (!m_initialized) return;

//	dprintf(D_FULLDEBUG, "setAttribute: %s[%s] = %s\n", key, name, value);

	markDirty(key, name, value);
}

void
AviaryScheddPlugin::destroyClassAd(const char *_key)
{
	if (!m_initialized) return;

//	dprintf(D_FULLDEBUG, "destroyClassAd: %s\n", key);

	if (!IS_JOB(_key)) return;

		// If we wait to process the deletion the job ad will be gone
		// and we won't be able to lookup the Submission. So, we must
		// process the job immediately, but that also means we need to
		// process all pending changes for the job as well.
	DirtyJobsType::iterator entry = dirtyJobs->begin();
	while (dirtyJobs->end() != entry) {
		string key = (*entry).first;
		string name = (*entry).second.first;
		int value = (*entry).second.second;

		if (key == _key) {
			processJob(key.c_str(), name.c_str(), value);

				// No need to process this entry again later
			entry = dirtyJobs->erase(entry);
		} else {
			entry++;
		}
	}
}

void
AviaryScheddPlugin::deleteAttribute(const char */*key*/,
								  const char */*name*/) { }

int
AviaryScheddPlugin::HandleTransportSocket(Stream *)
{
    // TODO: respond to a transport callback here?
    string provider_error;
    if (!provider->processHttpRequest(provider_error)) {
        dprintf (D_ALWAYS,"Error processing request: %s\n",provider_error.c_str());
    }

    return KEEP_STREAM;
}

void
AviaryScheddPlugin::processDirtyJobs()
{
	BeginTransaction();

	while (!dirtyJobs->empty()) {
		DirtyJobEntry entry = dirtyJobs->front(); dirtyJobs->pop_front();
		string key = entry.first;
		string name = entry.second.first;
		int value = entry.second.second;

		processJob(key.c_str(), name.c_str(), value);
	}

	CommitTransaction();

	isHandlerRegistered = false;
}

bool
AviaryScheddPlugin::processJob(const char *key,
							 const char *name,
							 int value)
{
	PROC_ID id;
	ClassAd *jobAd;

		// Skip any key that doesn't point to an actual job
	if (!IS_JOB(key)) return false;

//	dprintf(D_FULLDEBUG, "Processing: %s\n", key);

	id = getProcByString(key);
	if (id.cluster < 0 || id.proc < 0) {
		dprintf(D_FULLDEBUG, "Failed to parse key: %s - skipping\n", key);
		return false;
	}

		// Lookup the job ad assocaited with the key. If it is not
		// present, skip the key
	if (NULL == (jobAd = ::GetJobAd(id.cluster, id.proc, false))) {
		dprintf(D_ALWAYS,
				"NOTICE: Failed to lookup ad for %s - maybe deleted\n",
				key);
		return false;
	}

		// Store two pieces of information in the Job, 1. the
		// Submission's name, 2. the Submission's id
		//
		// Submissions indexed on their name, the id is present
		// for reconstruction of the Submission

		// XXX: Use the jobAd instead of GetAttribute below, gets us $$() expansion

	MyString submissionName;
	if (GetAttributeString(id.cluster, id.proc,
						   ATTR_JOB_SUBMISSION,
						   submissionName) < 0) {
			// Provide a default name for the Submission

			// If we are a DAG node, we default to our DAG group
		PROC_ID dagman;
		if (GetAttributeInt(id.cluster, id.proc,
							ATTR_DAGMAN_JOB_ID,
							&dagman.cluster) >= 0) {
			dagman.proc = 0;

			if (GetAttributeString(dagman.cluster, dagman.proc,
								   ATTR_JOB_SUBMISSION,
								   submissionName) < 0) {
					// This can only happen if the DAGMan job was
					// removed, and we remained, which should not
					// happen, but could. In such a case we are
					// orphaned, and we'll make a guess. We'll be
					// wrong if the DAGMan job didn't use the
					// default, but it is better to be wrong than
					// to fail entirely, which is the alternative.
				submissionName.sprintf("%s#%d", Name, dagman.cluster);
			}
		} else {
			submissionName.sprintf("%s#%d", Name, id.cluster);
		}

		MyString tmp;
		tmp += "\"";
		tmp += submissionName;
		tmp += "\"";
		SetAttribute(id.cluster, id.proc,
					 ATTR_JOB_SUBMISSION,
					 tmp.Value());
	}
}

void
AviaryScheddPlugin::markDirty(const char *key,
							const char *name,
							const char *value)
{
	if (!IS_JOB(key)) return;
	if (!(strcasecmp(name, ATTR_JOB_STATUS) == 0 ||
		  strcasecmp(name, ATTR_LAST_JOB_STATUS) == 0)) return;

	DirtyJobStatus status(name, atoi(value));
	DirtyJobEntry entry(key, status);
	dirtyJobs->push_back(DirtyJobEntry(key, DirtyJobStatus(name, atoi(value))));

	if (!isHandlerRegistered) {
			// To test destroyClassAd, set the timeout here to a few
			// seconds, submit a job and immediately delete it.
		daemonCore->Register_Timer(0,
								   (TimerHandlercpp)
								   &AviaryScheddPlugin::processDirtyJobs,
								   "Process Dirty",
								   this);
		isHandlerRegistered = true;
	}
}
<commit_msg>Fixed a minor bug where the axis2 port was hardcoded in the aviary init()<commit_after>/*
 * Copyright 2009-2011 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// condor includes
#include "condor_common.h"
#include "condor_qmgr.h"
#include "condor_config.h"

// local includes
#include "AviaryScheddPlugin.h"
#include "Axis2SoapProvider.h"
#include "SchedulerObject.h"

// Global from the condor_schedd, it's name
extern char * Name;

// Any key that begins with the '0' char is either the
// header or a cluster, i.e. not a job
#define IS_JOB(key) ((key) && '0' != (key)[0])

using namespace std;
using namespace aviary::job;
using namespace aviary::soap;

// global SchedulerObject
// TODO: convert to singleton
Axis2SoapProvider* provider = NULL;
SchedulerObject* schedulerObj = NULL;

void
AviaryScheddPlugin::earlyInitialize()
{

    // Since this plugin is registered with multiple
    // PluginManagers it may be initialized more than once,
    // and we don't want that
	static bool skip = false;
	if (skip) return; skip = true;

	// config then env for our all-important axis2 repo dir
    const char* log_file = "./aviary_job.axis2.log";
	string repo_path;
	char *tmp = NULL;
	if (tmp = param("WSFCPP_HOME")) {
		repo_path = tmp;
		free(tmp);
	}
	else if (tmp = getenv("WSFCPP_HOME")) {
		repo_path = tmp;
	}
	else {
		EXCEPT("No WSFCPP_HOME in config or env");
	}

	int port = param_integer("HTTP_PORT",9090);
	int level = param_integer("AXIS2_DEBUG_LEVEL",AXIS2_LOG_LEVEL_CRITICAL);

    // init transport here
    provider = new Axis2SoapProvider(level,log_file,repo_path.c_str());
    string axis_error;
    if (!provider->init(port,AXIS2_HTTP_DEFAULT_SO_TIMEOUT,axis_error)) {
		dprintf(D_ALWAYS, "%s\n",axis_error.c_str());
        EXCEPT("Failed to initialize Axis2SoapProvider");
    }

	schedulerObj = SchedulerObject::getInstance();

	dirtyJobs = new DirtyJobsType();

	isHandlerRegistered = false;

	ReliSock *sock = new ReliSock;
	if (!sock) {
		EXCEPT("Failed to allocate transport socket");
	}
	if (!sock->assign(provider->getHttpListenerSocket())) {
		EXCEPT("Failed to bind transport socket");
	}
	int index;
	if (-1 == (index =
			   daemonCore->Register_Socket((Stream *) sock,
										   "Aviary Method Socket",
										   (SocketHandlercpp) ( &AviaryScheddPlugin::HandleTransportSocket ),
										   "Handler for Aviary Methods.",
										   this))) {
		EXCEPT("Failed to register transport socket");
	}

	dprintf(D_ALWAYS,"Axis2 listener on http port: %d\n",port);

	m_initialized = false;
}

void
AviaryScheddPlugin::initialize()
{
		// Since this plugin is registered with multiple
		// PluginManagers it may be initialized more than once,
		// and we don't want that
	static bool skip = false;
	if (skip) return; skip = true;

		// WalkJobQueue(int (*func)(ClassAd *))
	ClassAd *ad = GetNextJob(1);
	while (ad != NULL) {
		MyString key;
		PROC_ID id;
		int value;

		if (!ad->LookupInteger(ATTR_CLUSTER_ID, id.cluster)) {
			EXCEPT("%s on job is missing or not an integer", ATTR_CLUSTER_ID);
		}
		if (!ad->LookupInteger(ATTR_PROC_ID, id.proc)) {
			EXCEPT("%s on job is missing or not an integer", ATTR_PROC_ID);
		}
		if (!ad->LookupInteger(ATTR_JOB_STATUS, value)) {
			EXCEPT("%s on job is missing or not an integer", ATTR_JOB_STATUS);
		}

		key.sprintf("%d.%d", id.cluster, id.proc);

		processJob(key.Value(), ATTR_JOB_STATUS, value);

		FreeJobAd(ad);
		ad = GetNextJob(0);
	}

	m_initialized = true;
}

void
AviaryScheddPlugin::shutdown()
{
		// Since this plugin is registered with multiple
		// PluginManagers (eg, shadow) it may be shutdown
		// more than once, and we don't want that
	static bool skip = false;
	if (skip) return; skip = true;

	dprintf(D_FULLDEBUG, "AviaryScheddPlugin: shutting down...\n");

	if (schedulerObj) {
		delete schedulerObj;
		schedulerObj = NULL;
	}
}

void
AviaryScheddPlugin::update(int cmd, const ClassAd *ad)
{
	MyString hashKey;

	switch (cmd) {
	case UPDATE_SCHEDD_AD:
		dprintf(D_FULLDEBUG, "Received UPDATE_SCHEDD_AD\n");
		schedulerObj->update(*ad);
		break;
	default:
		dprintf(D_FULLDEBUG, "Unsupported command: %s\n",
				getCollectorCommandString(cmd));
	}
}

void
AviaryScheddPlugin::archive(const ClassAd */*ad*/) { };

void
AviaryScheddPlugin::newClassAd(const char */*key*/) { };

void
AviaryScheddPlugin::setAttribute(const char *key,
							   const char *name,
							   const char *value)
{
	if (!m_initialized) return;

//	dprintf(D_FULLDEBUG, "setAttribute: %s[%s] = %s\n", key, name, value);

	markDirty(key, name, value);
}

void
AviaryScheddPlugin::destroyClassAd(const char *_key)
{
	if (!m_initialized) return;

//	dprintf(D_FULLDEBUG, "destroyClassAd: %s\n", key);

	if (!IS_JOB(_key)) return;

		// If we wait to process the deletion the job ad will be gone
		// and we won't be able to lookup the Submission. So, we must
		// process the job immediately, but that also means we need to
		// process all pending changes for the job as well.
	DirtyJobsType::iterator entry = dirtyJobs->begin();
	while (dirtyJobs->end() != entry) {
		string key = (*entry).first;
		string name = (*entry).second.first;
		int value = (*entry).second.second;

		if (key == _key) {
			processJob(key.c_str(), name.c_str(), value);

				// No need to process this entry again later
			entry = dirtyJobs->erase(entry);
		} else {
			entry++;
		}
	}
}

void
AviaryScheddPlugin::deleteAttribute(const char */*key*/,
								  const char */*name*/) { }

int
AviaryScheddPlugin::HandleTransportSocket(Stream *)
{
    // TODO: respond to a transport callback here?
    string provider_error;
    if (!provider->processHttpRequest(provider_error)) {
        dprintf (D_ALWAYS,"Error processing request: %s\n",provider_error.c_str());
    }

    return KEEP_STREAM;
}

void
AviaryScheddPlugin::processDirtyJobs()
{
	BeginTransaction();

	while (!dirtyJobs->empty()) {
		DirtyJobEntry entry = dirtyJobs->front(); dirtyJobs->pop_front();
		string key = entry.first;
		string name = entry.second.first;
		int value = entry.second.second;

		processJob(key.c_str(), name.c_str(), value);
	}

	CommitTransaction();

	isHandlerRegistered = false;
}

bool
AviaryScheddPlugin::processJob(const char *key,
							 const char *name,
							 int value)
{
	PROC_ID id;
	ClassAd *jobAd;

		// Skip any key that doesn't point to an actual job
	if (!IS_JOB(key)) return false;

//	dprintf(D_FULLDEBUG, "Processing: %s\n", key);

	id = getProcByString(key);
	if (id.cluster < 0 || id.proc < 0) {
		dprintf(D_FULLDEBUG, "Failed to parse key: %s - skipping\n", key);
		return false;
	}

		// Lookup the job ad assocaited with the key. If it is not
		// present, skip the key
	if (NULL == (jobAd = ::GetJobAd(id.cluster, id.proc, false))) {
		dprintf(D_ALWAYS,
				"NOTICE: Failed to lookup ad for %s - maybe deleted\n",
				key);
		return false;
	}

		// Store two pieces of information in the Job, 1. the
		// Submission's name, 2. the Submission's id
		//
		// Submissions indexed on their name, the id is present
		// for reconstruction of the Submission

		// XXX: Use the jobAd instead of GetAttribute below, gets us $$() expansion

	MyString submissionName;
	if (GetAttributeString(id.cluster, id.proc,
						   ATTR_JOB_SUBMISSION,
						   submissionName) < 0) {
			// Provide a default name for the Submission

			// If we are a DAG node, we default to our DAG group
		PROC_ID dagman;
		if (GetAttributeInt(id.cluster, id.proc,
							ATTR_DAGMAN_JOB_ID,
							&dagman.cluster) >= 0) {
			dagman.proc = 0;

			if (GetAttributeString(dagman.cluster, dagman.proc,
								   ATTR_JOB_SUBMISSION,
								   submissionName) < 0) {
					// This can only happen if the DAGMan job was
					// removed, and we remained, which should not
					// happen, but could. In such a case we are
					// orphaned, and we'll make a guess. We'll be
					// wrong if the DAGMan job didn't use the
					// default, but it is better to be wrong than
					// to fail entirely, which is the alternative.
				submissionName.sprintf("%s#%d", Name, dagman.cluster);
			}
		} else {
			submissionName.sprintf("%s#%d", Name, id.cluster);
		}

		MyString tmp;
		tmp += "\"";
		tmp += submissionName;
		tmp += "\"";
		SetAttribute(id.cluster, id.proc,
					 ATTR_JOB_SUBMISSION,
					 tmp.Value());
	}
}

void
AviaryScheddPlugin::markDirty(const char *key,
							const char *name,
							const char *value)
{
	if (!IS_JOB(key)) return;
	if (!(strcasecmp(name, ATTR_JOB_STATUS) == 0 ||
		  strcasecmp(name, ATTR_LAST_JOB_STATUS) == 0)) return;

	DirtyJobStatus status(name, atoi(value));
	DirtyJobEntry entry(key, status);
	dirtyJobs->push_back(DirtyJobEntry(key, DirtyJobStatus(name, atoi(value))));

	if (!isHandlerRegistered) {
			// To test destroyClassAd, set the timeout here to a few
			// seconds, submit a job and immediately delete it.
		daemonCore->Register_Timer(0,
								   (TimerHandlercpp)
								   &AviaryScheddPlugin::processDirtyJobs,
								   "Process Dirty",
								   this);
		isHandlerRegistered = true;
	}
}
<|endoftext|>


<commit_before>#ifndef PROTOCOL_MESSAGES_HPP_
#define PROTOCOL_MESSAGES_HPP_

#include <cstdint>

namespace protocol {
namespace message {

struct heartbeat_message_t {
  enum { ID = 0x00 };

  std::uint8_t seq;
} __attribute__((packed));

struct log_message_t {
  enum { ID = 0x01 };

  char data[255];
} __attribute__((packed));

struct attitude_message_t {
  enum { ID = 0x02 };

  float dcm[9];
} __attribute__((packed));

struct set_arm_state_message_t {
  enum { ID = 0x03 };

  bool armed;
} __attribute__((packed));

struct set_control_mode_message_t {
  enum { ID = 0x04 };

  enum class ControlMode {
    MANUAL,
    OFFBOARD
  };

  ControlMode mode;
} __attribute__((packed));

struct offboard_attitude_control_message_t {
  enum { ID = 0x05 };

  float roll;
  float pitch;
  float yaw;
  float throttle;
  uint16_t buttons;   // Bitfield of buttons
  uint8_t mode;
} __attribute__((packed));

struct motor_throttle_message_t {
  enum { ID = 0x06 };

  float throttles[4];
} __attribute__((packed));

inline std::uint16_t length(int id) {
  // TODO(kyle): sizeof(empty struct) is 1 in C++...
  switch(id) {
    case heartbeat_message_t::ID:
      return sizeof(heartbeat_message_t);
    case log_message_t::ID:
      return sizeof(log_message_t);
    case attitude_message_t::ID:
      return sizeof(attitude_message_t);
    case set_arm_state_message_t::ID:
      return sizeof(set_arm_state_message_t);
    case set_control_mode_message_t::ID:
      return sizeof(set_control_mode_message_t);
    case offboard_attitude_control_message_t::ID:
      return sizeof(offboard_attitude_control_message_t);
    case motor_throttle_message_t::ID:
      return sizeof(motor_throttle_message_t);
  }

  return 0; // TODO(kyle): Return something more meaningful?
}

}
}

#endif // MESSAGES_HPP_

<commit_msg>Add sensor calibration messages.<commit_after>#ifndef PROTOCOL_MESSAGES_HPP_
#define PROTOCOL_MESSAGES_HPP_

#include <cstdint>

namespace protocol {
namespace message {

struct heartbeat_message_t {
  enum { ID = 0x00 };

  std::uint8_t seq;
} __attribute__((packed));

struct log_message_t {
  enum { ID = 0x01 };

  char data[255];
} __attribute__((packed));

struct attitude_message_t {
  enum { ID = 0x02 };

  float dcm[9];
} __attribute__((packed));

struct set_arm_state_message_t {
  enum { ID = 0x03 };

  bool armed;
} __attribute__((packed));

struct set_control_mode_message_t {
  enum { ID = 0x04 };

  enum class ControlMode {
    MANUAL,
    OFFBOARD
  };

  ControlMode mode;
} __attribute__((packed));

struct offboard_attitude_control_message_t {
  enum { ID = 0x05 };

  float roll;
  float pitch;
  float yaw;
  float throttle;
  uint16_t buttons;   // Bitfield of buttons
  uint8_t mode;
} __attribute__((packed));

struct motor_throttle_message_t {
  enum { ID = 0x06 };

  float throttles[4];
} __attribute__((packed));

struct sensor_calibration_request_message_t {
  enum { ID = 0x07 };
} __attribute__((packed));

struct sensor_calibration_response_message_t {
  enum { ID = 0x08 };

  enum class SensorType {
    ACCEL,
    GYRO,
    MAG
  };

  SensorType type;
  float offsets[3];
} __attribute__((packed));

inline std::uint16_t length(int id) {
  // TODO(kyle): sizeof(empty struct) is 1 in C++...
  switch(id) {
    case heartbeat_message_t::ID:
      return sizeof(heartbeat_message_t);
    case log_message_t::ID:
      return sizeof(log_message_t);
    case attitude_message_t::ID:
      return sizeof(attitude_message_t);
    case set_arm_state_message_t::ID:
      return sizeof(set_arm_state_message_t);
    case set_control_mode_message_t::ID:
      return sizeof(set_control_mode_message_t);
    case offboard_attitude_control_message_t::ID:
      return sizeof(offboard_attitude_control_message_t);
    case motor_throttle_message_t::ID:
      return sizeof(motor_throttle_message_t);
    case sensor_calibration_request_message_t::ID:
      return sizeof(sensor_calibration_request_message_t);
    case sensor_calibration_response_message_t::ID:
      return sizeof(sensor_calibration_response_message_t);
  }

  return 0; // TODO(kyle): Return something more meaningful?
}

}
}

#endif // MESSAGES_HPP_

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "timelinezoomcontrol.h"

namespace Timeline {

TimelineZoomControl::TimelineZoomControl(QObject *parent) : QObject(parent), m_traceStart(-1), m_traceEnd(-1),
    m_windowStart(-1), m_windowEnd(-1), m_rangeStart(-1), m_rangeEnd(-1), m_windowLocked(false)
{
    connect(&m_timer, &QTimer::timeout, this, &TimelineZoomControl::moveWindow);
}

void TimelineZoomControl::clear()
{
    m_timer.stop();
    setWindowLocked(false);
    setRange(-1, -1);
    setTrace(-1, -1);
}

void TimelineZoomControl::setTraceStart(qint64 start)
{
    if (start != m_traceStart) {
        if (m_traceEnd < start)
            m_traceEnd = start;
        m_traceStart = start;
        emit traceChanged(start, m_traceEnd);
        rebuildWindow();
    }
}

void TimelineZoomControl::setTraceEnd(qint64 end)
{
    if (end != m_traceEnd) {
        if (m_traceStart > end)
            m_traceStart = end;
        m_traceEnd = end;
        emit traceChanged(m_traceStart, end);
        rebuildWindow();
    }
}

void TimelineZoomControl::setTrace(qint64 start, qint64 end)
{
    Q_ASSERT(start <= end);
    if (start != m_traceStart || end != m_traceEnd) {
        m_traceStart = start;
        m_traceEnd = end;
        emit traceChanged(start, end);
        rebuildWindow();
    }
}

void TimelineZoomControl::setRange(qint64 start, qint64 end)
{
    Q_ASSERT(start <= end);
    if (m_rangeStart != start || m_rangeEnd != end) {
        m_timer.stop();
        m_rangeStart = start;
        m_rangeEnd = end;
        rebuildWindow();
        emit rangeChanged(start, end);
    }
}

void TimelineZoomControl::setWindowLocked(bool windowLocked)
{
    if (windowLocked  != m_windowLocked) {
        m_windowLocked = windowLocked;
        emit windowLockedChanged(windowLocked);
    }
}

void TimelineZoomControl::rebuildWindow()
{
    qint64 minDuration = 1; // qMax needs equal data types, so literal 1 won't do
    qint64 shownDuration = qMax(rangeDuration(), minDuration);

    qint64 oldWindowStart = m_windowStart;
    qint64 oldWindowEnd = m_windowEnd;
    if (traceDuration() / shownDuration < MAX_ZOOM_FACTOR) {
        m_windowStart = m_traceStart;
        m_windowEnd = m_traceEnd;
    } else if (windowDuration() / shownDuration > MAX_ZOOM_FACTOR ||
               windowDuration() / shownDuration * 2 < MAX_ZOOM_FACTOR) {
        qint64 keep = shownDuration * MAX_ZOOM_FACTOR / 2 - shownDuration;
        m_windowStart = m_rangeStart - keep;
        if (m_windowStart < m_traceStart) {
            keep += m_traceStart - m_windowStart;
            m_windowStart = m_traceStart;
        }

        m_windowEnd = m_rangeEnd + keep;
        if (m_windowEnd > m_traceEnd) {
            m_windowStart = qMax(m_traceStart, m_windowStart - m_windowEnd - m_traceEnd);
            m_windowEnd = m_traceEnd;
        }
    } else {
        m_timer.start(500);
    }
    if (oldWindowStart != m_windowStart || oldWindowEnd != m_windowEnd) {
        clampRangeToWindow();
        emit windowChanged(m_windowStart, m_windowEnd);
    }
}

void TimelineZoomControl::moveWindow()
{
    if (m_windowLocked)
        return;
    m_timer.stop();

    qint64 offset = (m_rangeEnd - m_windowEnd + m_rangeStart - m_windowStart) / 2;
    if (offset == 0 || (offset < 0 && m_windowStart == m_traceStart) ||
            (offset > 0 && m_windowEnd == m_traceEnd)) {
        return;
    } else if (offset > rangeDuration()) {
        offset = (offset + rangeDuration()) / 2;
    } else if (offset < -rangeDuration()) {
        offset = (offset - rangeDuration()) / 2;
    }
    m_windowStart += offset;
    if (m_windowStart < m_traceStart) {
        m_windowEnd += m_traceStart - m_windowStart;
        m_windowStart = m_traceStart;
    }
    m_windowEnd += offset;
    if (m_windowEnd > m_traceEnd) {
        m_windowStart -= m_windowEnd - m_traceEnd;
        m_windowEnd = m_traceEnd;
    }

    clampRangeToWindow();
    emit windowChanged(m_windowStart, m_windowEnd);
    m_timer.start(100);
}

void TimelineZoomControl::clampRangeToWindow()
{
    qint64 rangeStart = qMin(qMax(m_rangeStart, m_windowStart), m_windowEnd);
    qint64 rangeEnd = qMin(qMax(rangeStart, m_rangeEnd), m_windowEnd);
    if (rangeStart != m_rangeStart || rangeEnd != m_rangeEnd)
        setRange(rangeStart, rangeEnd);
}

} // namespace Timeline
<commit_msg>Timeline: Add some forgotten braces<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "timelinezoomcontrol.h"

namespace Timeline {

TimelineZoomControl::TimelineZoomControl(QObject *parent) : QObject(parent), m_traceStart(-1), m_traceEnd(-1),
    m_windowStart(-1), m_windowEnd(-1), m_rangeStart(-1), m_rangeEnd(-1), m_windowLocked(false)
{
    connect(&m_timer, &QTimer::timeout, this, &TimelineZoomControl::moveWindow);
}

void TimelineZoomControl::clear()
{
    m_timer.stop();
    setWindowLocked(false);
    setRange(-1, -1);
    setTrace(-1, -1);
}

void TimelineZoomControl::setTraceStart(qint64 start)
{
    if (start != m_traceStart) {
        if (m_traceEnd < start)
            m_traceEnd = start;
        m_traceStart = start;
        emit traceChanged(start, m_traceEnd);
        rebuildWindow();
    }
}

void TimelineZoomControl::setTraceEnd(qint64 end)
{
    if (end != m_traceEnd) {
        if (m_traceStart > end)
            m_traceStart = end;
        m_traceEnd = end;
        emit traceChanged(m_traceStart, end);
        rebuildWindow();
    }
}

void TimelineZoomControl::setTrace(qint64 start, qint64 end)
{
    Q_ASSERT(start <= end);
    if (start != m_traceStart || end != m_traceEnd) {
        m_traceStart = start;
        m_traceEnd = end;
        emit traceChanged(start, end);
        rebuildWindow();
    }
}

void TimelineZoomControl::setRange(qint64 start, qint64 end)
{
    Q_ASSERT(start <= end);
    if (m_rangeStart != start || m_rangeEnd != end) {
        m_timer.stop();
        m_rangeStart = start;
        m_rangeEnd = end;
        rebuildWindow();
        emit rangeChanged(start, end);
    }
}

void TimelineZoomControl::setWindowLocked(bool windowLocked)
{
    if (windowLocked  != m_windowLocked) {
        m_windowLocked = windowLocked;
        emit windowLockedChanged(windowLocked);
    }
}

void TimelineZoomControl::rebuildWindow()
{
    qint64 minDuration = 1; // qMax needs equal data types, so literal 1 won't do
    qint64 shownDuration = qMax(rangeDuration(), minDuration);

    qint64 oldWindowStart = m_windowStart;
    qint64 oldWindowEnd = m_windowEnd;
    if (traceDuration() / shownDuration < MAX_ZOOM_FACTOR) {
        m_windowStart = m_traceStart;
        m_windowEnd = m_traceEnd;
    } else if (windowDuration() / shownDuration > MAX_ZOOM_FACTOR ||
               windowDuration() / shownDuration * 2 < MAX_ZOOM_FACTOR) {
        qint64 keep = shownDuration * MAX_ZOOM_FACTOR / 2 - shownDuration;
        m_windowStart = m_rangeStart - keep;
        if (m_windowStart < m_traceStart) {
            keep += m_traceStart - m_windowStart;
            m_windowStart = m_traceStart;
        }

        m_windowEnd = m_rangeEnd + keep;
        if (m_windowEnd > m_traceEnd) {
            m_windowStart = qMax(m_traceStart, m_windowStart - (m_windowEnd - m_traceEnd));
            m_windowEnd = m_traceEnd;
        }
    } else {
        m_timer.start(500);
    }
    if (oldWindowStart != m_windowStart || oldWindowEnd != m_windowEnd) {
        clampRangeToWindow();
        emit windowChanged(m_windowStart, m_windowEnd);
    }
}

void TimelineZoomControl::moveWindow()
{
    if (m_windowLocked)
        return;
    m_timer.stop();

    qint64 offset = (m_rangeEnd - m_windowEnd + m_rangeStart - m_windowStart) / 2;
    if (offset == 0 || (offset < 0 && m_windowStart == m_traceStart) ||
            (offset > 0 && m_windowEnd == m_traceEnd)) {
        return;
    } else if (offset > rangeDuration()) {
        offset = (offset + rangeDuration()) / 2;
    } else if (offset < -rangeDuration()) {
        offset = (offset - rangeDuration()) / 2;
    }
    m_windowStart += offset;
    if (m_windowStart < m_traceStart) {
        m_windowEnd += m_traceStart - m_windowStart;
        m_windowStart = m_traceStart;
    }
    m_windowEnd += offset;
    if (m_windowEnd > m_traceEnd) {
        m_windowStart -= m_windowEnd - m_traceEnd;
        m_windowEnd = m_traceEnd;
    }

    clampRangeToWindow();
    emit windowChanged(m_windowStart, m_windowEnd);
    m_timer.start(100);
}

void TimelineZoomControl::clampRangeToWindow()
{
    qint64 rangeStart = qMin(qMax(m_rangeStart, m_windowStart), m_windowEnd);
    qint64 rangeEnd = qMin(qMax(rangeStart, m_rangeEnd), m_windowEnd);
    if (rangeStart != m_rangeStart || rangeEnd != m_rangeEnd)
        setRange(rangeStart, rangeEnd);
}

} // namespace Timeline
<|endoftext|>


<commit_before>#include "camerafilter.h"

#include "cameraframegrabber.h"

//#include <QCameraViewfinder>
#include <QCameraInfo>

#include <QtDebug>

CameraFilter::CameraFilter(QSize resolution):camera_(),
  cameraFrameGrabber_(),
  resolution_(resolution)
{
  name_ = "CamF";
  camera_ = new QCamera(QCameraInfo::defaultCamera());
  cameraFrameGrabber_ = new CameraFrameGrabber();

  Q_ASSERT(camera_ && cameraFrameGrabber_);

  camera_->setViewfinder(cameraFrameGrabber_);

  connect(cameraFrameGrabber_, SIGNAL(frameAvailable(QVideoFrame)), this, SLOT(handleFrame(QVideoFrame)));

  camera_->start();
}

CameraFilter::~CameraFilter()
{
  delete camera_;
  delete cameraFrameGrabber_;
}

void CameraFilter::process()
{
  // do nothing because camera input is handled via camera signal
}

void CameraFilter::stop()
{
  camera_->stop();
  Filter::stop();
}

void CameraFilter::handleFrame(const QVideoFrame &frame)
{
  QVideoFrame cloneFrame(frame);
  cloneFrame.map(QAbstractVideoBuffer::ReadOnly);

  QVideoFrame::PixelFormat pf = cloneFrame.pixelFormat();

  Q_ASSERT(pf == QVideoFrame::Format_RGB32);

  Data * newImage = new Data;

  newImage->type = RGB32VIDEO;
  std::unique_ptr<uchar> uu(new uchar[cloneFrame.mappedBytes()]);
  newImage->data = std::unique_ptr<uchar[]>(new uchar[cloneFrame.mappedBytes()]);

  uchar *bits = cloneFrame.bits();

  memcpy(newImage->data.get(), bits, cloneFrame.mappedBytes());
  newImage->data_size = cloneFrame.mappedBytes();
  newImage->width = cloneFrame.width();
  newImage->height = cloneFrame.height();

  QImage image(
        newImage->data.get(),
        newImage->width,
        newImage->height,
        QImage::Format_RGB32);

  QImage image2 = image.scaled(resolution_);
  memcpy(newImage->data.get(), image2.bits(), image2.byteCount());
  newImage->width = resolution_.width();
  newImage->height = resolution_.height();
  newImage->data_size = image2.byteCount();
  //qDebug() << "Frame generated. Format: " << pf
  //         << " width: " << newImage->width << ", height: " << newImage->height;

  std::unique_ptr<Data> u_newImage( newImage );
  cloneFrame.unmap();

  Q_ASSERT(u_newImage->data);
  sendOutput(std::move(u_newImage));
}
<commit_msg>Fixed a scaling crash when scaling image upwards.<commit_after>#include "camerafilter.h"

#include "cameraframegrabber.h"

//#include <QCameraViewfinder>
#include <QCameraInfo>

#include <QtDebug>

CameraFilter::CameraFilter(QSize resolution):camera_(),
  cameraFrameGrabber_(),
  resolution_(resolution)
{
  name_ = "CamF";
  camera_ = new QCamera(QCameraInfo::defaultCamera());
  cameraFrameGrabber_ = new CameraFrameGrabber();

  Q_ASSERT(camera_ && cameraFrameGrabber_);

  camera_->setViewfinder(cameraFrameGrabber_);

  connect(cameraFrameGrabber_, SIGNAL(frameAvailable(QVideoFrame)), this, SLOT(handleFrame(QVideoFrame)));

  camera_->start();
}

CameraFilter::~CameraFilter()
{
  delete camera_;
  delete cameraFrameGrabber_;
}

void CameraFilter::process()
{
  // do nothing because camera input is handled via camera signal
}

void CameraFilter::stop()
{
  camera_->stop();
  Filter::stop();
}

void CameraFilter::handleFrame(const QVideoFrame &frame)
{
  QVideoFrame cloneFrame(frame);
  cloneFrame.map(QAbstractVideoBuffer::ReadOnly);

  QVideoFrame::PixelFormat pf = cloneFrame.pixelFormat();

  Q_ASSERT(pf == QVideoFrame::Format_RGB32);

  // capture the frame data
  Data * newImage = new Data;
  newImage->type = RGB32VIDEO;
  std::unique_ptr<uchar> uu(new uchar[cloneFrame.mappedBytes()]);
  newImage->data = std::unique_ptr<uchar[]>(new uchar[cloneFrame.mappedBytes()]);

  uchar *bits = cloneFrame.bits();

  memcpy(newImage->data.get(), bits, cloneFrame.mappedBytes());
  newImage->data_size = cloneFrame.mappedBytes();
  newImage->width = cloneFrame.width();
  newImage->height = cloneFrame.height();

  // scale the image and copy to new data
  if(resolution_ != cloneFrame.size())
  {
    QImage image(
          newImage->data.get(),
          newImage->width,
          newImage->height,
          QImage::Format_RGB32);

    QImage image2 = image.scaled(resolution_);
    if(resolution_.width() * resolution_.height()
       > cloneFrame.size().width() * cloneFrame.size().height())
    {
      newImage->data = std::unique_ptr<uchar[]>(new uchar[image2.byteCount()]);
    }
    memcpy(newImage->data.get(), image2.bits(), image2.byteCount());
    newImage->width = resolution_.width();
    newImage->height = resolution_.height();
    newImage->data_size = image2.byteCount();
  }

  //qDebug() << "Frame generated. Format: " << pf
  //         << " width: " << newImage->width << ", height: " << newImage->height;

  std::unique_ptr<Data> u_newImage( newImage );
  cloneFrame.unmap();

  Q_ASSERT(u_newImage->data);
  sendOutput(std::move(u_newImage));
}
<|endoftext|>


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

#include "chrome/browser/diagnostics/diagnostics_main.h"

#include "app/app_paths.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/string_util.h"
#include "base/time.h"
#include "chrome/browser/diagnostics/diagnostics_model.h"
#include "chrome/common/chrome_paths.h"

#if defined(OS_WIN)
#include "base/win_util.h"

namespace {
// This is a minimalistic class to wrap the windows console operating
// in high-level IO mode. This will be eventually replaced by a view
// that can be subclassed for each platform and that the approved look
// and feel.
class SimpleConsole {
 public:
  // The ctor allocates a console always. This avoids having to ask
  // the user to start chrome from a command prompt.
  SimpleConsole()
      : std_out_(INVALID_HANDLE_VALUE),
        std_in_(INVALID_HANDLE_VALUE)  {
  }

  ~SimpleConsole() {
    ::FreeConsole();
  }
  // Init must be called before using any other method. If it returns
  // false there would be no console output.
  bool Init() {
    ::AllocConsole();
    return SetIOHandles();
  }

  // Writes a string to the console with the current color.
  bool Write(const std::wstring& txt) {
    DWORD sz = txt.size();
    return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
  }

  // Reads a string from the console. Internally it is limited to 256
  // characters.
  bool Read(std::wstring* txt) {
    wchar_t buf[256];
    DWORD read = sizeof(buf) - sizeof(buf[0]);
    if (!::ReadConsoleW(std_in_, buf, read, &read, NULL))
      return false;
    // Note that |read| is in bytes.
    txt->assign(buf, read/2);
    return true;
  }

  // Sets the foreground and backgroudn color. See |kRedFG| or |kGreenFG|
  // below for examples how to combine colors.
  bool SetColor(uint16 color_combo) {
    return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
  }

 private:
  bool SetIOHandles() {
    std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
    std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
    return ((std_out_ != INVALID_HANDLE_VALUE) &&
            (std_in_ != INVALID_HANDLE_VALUE));
  }

  // The input and output handles to the screen. They seem to be
  // implemented as pipes but they have non-documented protocol.
  HANDLE std_out_;
  HANDLE std_in_;

  DISALLOW_COPY_AND_ASSIGN(SimpleConsole);
};

// This class wraps a SimpleConsole for the specific use case of
// writing the results of the diagnostic tests.
// TODO(cpu) figure out the localization strategy.
class TestWriter {
 public:
  // The |console| must be valid and properly initialized. This
  // class does not own it.
  explicit TestWriter(SimpleConsole* console) : console_(console) {
  }

  // Write an informational line of text in white over black.
  bool WriteInfoText(const std::wstring& txt) {
    console_->SetColor(kWhiteFG);
    return console_->Write(txt);
  }

  // Write a result block. It consist of two lines. The first line
  // has [PASS] or [FAIL] with |name| and the second line has
  // the text in |extra|.
  bool WriteResult(bool success, const std::wstring& name,
                   const std::wstring& extra) {
    if (success) {
      console_->SetColor(kGreenFG);
      console_->Write(L"[PASS] ");
    } else {
      console_->SetColor(kRedFG);
      console_->Write(L"[FAIL] ");
    }
    WriteInfoText(name + L"\n");
    std::wstring second_line(L"   ");
    second_line.append(extra);
    return WriteInfoText(second_line + L"\n\n");
  }

 private:
  // constants for the colors we use.
  static const uint16 kRedFG = FOREGROUND_RED|FOREGROUND_INTENSITY;
  static const uint16 kGreenFG = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
  static const uint16 kWhiteFG = kRedFG | kGreenFG | FOREGROUND_BLUE;

  SimpleConsole* console_;

  DISALLOW_COPY_AND_ASSIGN(TestWriter);
};

std::wstring PrintableUSCurrentTime() {
  base::Time::Exploded exploded = {0};
  base::Time::Now().UTCExplode(&exploded);
  return StringPrintf(L"%d:%d:%d.%d:%d:%d",
      exploded.year, exploded.month, exploded.day_of_month,
      exploded.hour, exploded.minute, exploded.second);
}

// This class is a basic test controller. In this design the view (TestWriter)
// and the model (DiagnosticsModel) do not talk to each other directly but they
// are mediated by the controller. This has a name: 'passive view'.
// More info at http://martinfowler.com/eaaDev/PassiveScreen.html
class TestController : public DiagnosticsModel::Observer {
 public:
  explicit TestController(TestWriter* writer) : writer_(writer) {
  }

  // Run all the diagnostics of |model| and invoke the view as the model
  // callbacks arrive.
  void Run(DiagnosticsModel* model) {
    std::wstring title(L"Chrome Diagnostics Mode (");
    writer_->WriteInfoText(title.append(PrintableUSCurrentTime()) + L")\n");
    if (!model) {
      writer_->WriteResult(false, L"Diagnostics start", L"model is null");
      return;
    }
    bool icu_result = icu_util::Initialize();
    if (!icu_result) {
      writer_->WriteResult(false, L"Diagnostics start", L"ICU failure");
      return;
    }
    int count = model->GetTestAvailableCount();
    writer_->WriteInfoText(StringPrintf(L"%d available test(s)\n\n", count));
    model->RunAll(this);
  }

  // Next four are overriden from DiagnosticsModel::Observer
  virtual void OnProgress(int id, int percent, DiagnosticsModel* model) {
  }

  virtual void OnSkipped(int id, DiagnosticsModel* model) {
    // TODO(cpu): display skipped tests.
  }

  virtual void OnFinished(int id, DiagnosticsModel* model) {
    // As each test completes we output the results.
    ShowResult(model->GetTest(id));
  }

  virtual void OnDoneAll(DiagnosticsModel* model) {
    writer_->WriteInfoText(L"DONE\n\n");
  }

 private:
  void ShowResult(DiagnosticsModel::TestInfo& test_info) {
    bool success = (DiagnosticsModel::TEST_OK == test_info.GetResult());
    writer_->WriteResult(success, test_info.GetTitle(),
                         test_info.GetAdditionalInfo());
  }

  DiagnosticsModel* model_;
  TestWriter* writer_;

  DISALLOW_COPY_AND_ASSIGN(TestController);
};
}  // namespace

// This entry point is called from ChromeMain() when very few things
// have been initialized. To wit:
// -(win)   Breakpad
// -(macOS) base::EnableTerminationOnHeapCorruption()
// -(macOS) base::EnableTerminationOnOutOfMemory()
// -(all)   RegisterInvalidParamHandler()
// -(all)   base::AtExitManager::AtExitManager()
// -(macOS) base::ScopedNSAutoreleasePool
// -(posix) Singleton<base::GlobalDescriptors>::Set(kPrimaryIPCChannel)
// -(linux) Singleton<base::GlobalDescriptors>::Set(kCrashDumpSignal)
// -(posix) setlocale(LC_ALL,..)
// -(all)   CommandLine::Init();

int DiagnosticsMain(const CommandLine& command_line) {
  // If we can't initialize the console exit right away.
  SimpleConsole console;
  if (!console.Init())
    return 1;

  // We need to have the path providers registered. They both
  // return void so there is no early error signal that we can use.
  app::RegisterPathProvider();
  chrome::RegisterPathProvider();

  TestWriter writer(&console);
  DiagnosticsModel* model = MakeDiagnosticsModel(command_line);
  TestController controller(&writer);

  // Run all the diagnostic tests.
  controller.Run(model);
  delete model;

  // Block here so the user can see the results.
  writer.WriteInfoText(L"Press [enter] to continue\n");
  std::wstring txt;
  console.Read(&txt);
  return 0;
}

#else  // defined(OS_WIN)

int DiagnosticsMain(const CommandLine& command_line) {
  return 0;
}

#endif
<commit_msg>Posix: implement diagnostics mode console output.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/diagnostics/diagnostics_main.h"

#if defined(OS_POSIX)
#include <stdio.h>
#include <unistd.h>
#endif

#include "app/app_paths.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/diagnostics/diagnostics_model.h"
#include "chrome/common/chrome_paths.h"

#if defined(OS_WIN)
#include "base/win_util.h"
#endif

namespace {
// This is a minimalistic interface to wrap the platform console.  This will be
// eventually replaced by a view that can be subclassed for each platform and
// that the approved look and feel.
class SimpleConsole {
 public:
  enum Color {
    DEFAULT,
    RED,
    GREEN,
  };

  virtual ~SimpleConsole() { }

  // Init must be called before using any other method. If it returns
  // false there would be no console output.
  virtual bool Init() = 0;

  // Writes a string to the console with the current color.
  virtual bool Write(const std::wstring& text) = 0;

  // Reads a string from the console. Internally it may be limited to 256
  // characters.
  virtual bool Read(std::wstring* txt) = 0;

  // Sets the foreground and background color.
  virtual bool SetColor(Color color) = 0;

  // Create an appropriate SimpleConsole instance.  May return NULL if there is
  // no implementation for the current platform.
  static SimpleConsole* Create();
};

#if defined(OS_WIN)
// Wrapper for the windows console operating in high-level IO mode.
class WinConsole : public SimpleConsole {
 public:
  // The ctor allocates a console always. This avoids having to ask
  // the user to start chrome from a command prompt.
  WinConsole()
      : std_out_(INVALID_HANDLE_VALUE),
        std_in_(INVALID_HANDLE_VALUE)  {
  }

  virtual ~WinConsole() {
    ::FreeConsole();
  }

  virtual bool Init() {
    ::AllocConsole();
    return SetIOHandles();
  }

  virtual bool Write(const std::wstring& txt) {
    DWORD sz = txt.size();
    return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
  }

  // Reads a string from the console. Internally it is limited to 256
  // characters.
  virtual bool Read(std::wstring* txt) {
    wchar_t buf[256];
    DWORD read = sizeof(buf) - sizeof(buf[0]);
    if (!::ReadConsoleW(std_in_, buf, read, &read, NULL))
      return false;
    // Note that |read| is in bytes.
    txt->assign(buf, read/2);
    return true;
  }

  // Sets the foreground and background color.
  virtual bool SetColor(Color color) {
    uint16 color_combo =
        FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY;
    switch (color) {
      case RED:
        color_combo = FOREGROUND_RED|FOREGROUND_INTENSITY;
        break;
      case GREEN:
        color_combo = FOREGROUND_GREEN|FOREGROUND_INTENSITY;
        break;
      case DEFAULT:
        break;
      default:
        NOTREACHED();
    }
    return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
  }

 private:
  bool SetIOHandles() {
    std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
    std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
    return ((std_out_ != INVALID_HANDLE_VALUE) &&
            (std_in_ != INVALID_HANDLE_VALUE));
  }

  // The input and output handles to the screen. They seem to be
  // implemented as pipes but they have non-documented protocol.
  HANDLE std_out_;
  HANDLE std_in_;

  DISALLOW_COPY_AND_ASSIGN(WinConsole);
};

SimpleConsole* SimpleConsole::Create() {
  return new WinConsole();
}

#elif defined(OS_POSIX)

class PosixConsole : public SimpleConsole {
 public:
  PosixConsole() { }

  virtual bool Init() {
    // Technically, we should also check the terminal capabilities before using
    // color, but in practice this is unlikely to be an issue.
    use_color_ = isatty(STDOUT_FILENO);
    return true;
  }

  virtual bool Write(const std::wstring& text) {
    printf("%s", base::SysWideToNativeMB(text).c_str());
    return true;
  }

  virtual bool Read(std::wstring* txt) {
    // TODO(mattm): implement this.
    return false;
  }

  virtual bool SetColor(Color color) {
    if (!use_color_)
      return false;

    const char* code = "\033[m";
    switch (color) {
      case RED:
        code = "\033[1;31m";
        break;
      case GREEN:
        code = "\033[1;32m";
        break;
      case DEFAULT:
        break;
      default:
        NOTREACHED();
    }
    printf("%s", code);
    return true;
  }

 private:
  bool use_color_;

  DISALLOW_COPY_AND_ASSIGN(PosixConsole);
};

SimpleConsole* SimpleConsole::Create() {
  return new PosixConsole();
}

#else  // !defined(OS_WIN) && !defined(OS_POSIX)

SimpleConsole* SimpleConsole::Create() {
  return NULL;
}
#endif

// This class wraps a SimpleConsole for the specific use case of
// writing the results of the diagnostic tests.
// TODO(cpu) figure out the localization strategy.
class TestWriter {
 public:
  // The |console| must be valid and properly initialized. This
  // class does not own it.
  explicit TestWriter(SimpleConsole* console) : console_(console) {
  }

  // Write an informational line of text in white over black.
  bool WriteInfoText(const std::wstring& txt) {
    console_->SetColor(SimpleConsole::DEFAULT);
    return console_->Write(txt);
  }

  // Write a result block. It consist of two lines. The first line
  // has [PASS] or [FAIL] with |name| and the second line has
  // the text in |extra|.
  bool WriteResult(bool success, const std::wstring& name,
                   const std::wstring& extra) {
    if (success) {
      console_->SetColor(SimpleConsole::GREEN);
      console_->Write(L"[PASS] ");
    } else {
      console_->SetColor(SimpleConsole::RED);
      console_->Write(L"[FAIL] ");
    }
    WriteInfoText(name + L"\n");
    std::wstring second_line(L"   ");
    second_line.append(extra);
    return WriteInfoText(second_line + L"\n\n");
  }

 private:

  SimpleConsole* console_;

  DISALLOW_COPY_AND_ASSIGN(TestWriter);
};

std::wstring PrintableUSCurrentTime() {
  base::Time::Exploded exploded = {0};
  base::Time::Now().UTCExplode(&exploded);
  return StringPrintf(L"%d:%d:%d.%d:%d:%d",
      exploded.year, exploded.month, exploded.day_of_month,
      exploded.hour, exploded.minute, exploded.second);
}

// This class is a basic test controller. In this design the view (TestWriter)
// and the model (DiagnosticsModel) do not talk to each other directly but they
// are mediated by the controller. This has a name: 'passive view'.
// More info at http://martinfowler.com/eaaDev/PassiveScreen.html
class TestController : public DiagnosticsModel::Observer {
 public:
  explicit TestController(TestWriter* writer) : writer_(writer) {
  }

  // Run all the diagnostics of |model| and invoke the view as the model
  // callbacks arrive.
  void Run(DiagnosticsModel* model) {
    std::wstring title(L"Chrome Diagnostics Mode (");
    writer_->WriteInfoText(title.append(PrintableUSCurrentTime()) + L")\n");
    if (!model) {
      writer_->WriteResult(false, L"Diagnostics start", L"model is null");
      return;
    }
    bool icu_result = icu_util::Initialize();
    if (!icu_result) {
      writer_->WriteResult(false, L"Diagnostics start", L"ICU failure");
      return;
    }
    int count = model->GetTestAvailableCount();
    writer_->WriteInfoText(StringPrintf(L"%d available test(s)\n\n", count));
    model->RunAll(this);
  }

  // Next four are overriden from DiagnosticsModel::Observer
  virtual void OnProgress(int id, int percent, DiagnosticsModel* model) {
  }

  virtual void OnSkipped(int id, DiagnosticsModel* model) {
    // TODO(cpu): display skipped tests.
  }

  virtual void OnFinished(int id, DiagnosticsModel* model) {
    // As each test completes we output the results.
    ShowResult(model->GetTest(id));
  }

  virtual void OnDoneAll(DiagnosticsModel* model) {
    writer_->WriteInfoText(L"DONE\n\n");
  }

 private:
  void ShowResult(DiagnosticsModel::TestInfo& test_info) {
    bool success = (DiagnosticsModel::TEST_OK == test_info.GetResult());
    writer_->WriteResult(success, UTF16ToWide(test_info.GetTitle()),
                         UTF16ToWide(test_info.GetAdditionalInfo()));
  }

  DiagnosticsModel* model_;
  TestWriter* writer_;

  DISALLOW_COPY_AND_ASSIGN(TestController);
};
}  // namespace

// This entry point is called from ChromeMain() when very few things
// have been initialized. To wit:
// -(win)   Breakpad
// -(macOS) base::EnableTerminationOnHeapCorruption()
// -(macOS) base::EnableTerminationOnOutOfMemory()
// -(all)   RegisterInvalidParamHandler()
// -(all)   base::AtExitManager::AtExitManager()
// -(macOS) base::ScopedNSAutoreleasePool
// -(posix) Singleton<base::GlobalDescriptors>::Set(kPrimaryIPCChannel)
// -(linux) Singleton<base::GlobalDescriptors>::Set(kCrashDumpSignal)
// -(posix) setlocale(LC_ALL,..)
// -(all)   CommandLine::Init();

int DiagnosticsMain(const CommandLine& command_line) {
  // If we can't initialize the console exit right away.
  SimpleConsole* console = SimpleConsole::Create();
  if (!console || !console->Init())
    return 1;

  // We need to have the path providers registered. They both
  // return void so there is no early error signal that we can use.
  app::RegisterPathProvider();
  chrome::RegisterPathProvider();

  TestWriter writer(console);
  DiagnosticsModel* model = MakeDiagnosticsModel(command_line);
  TestController controller(&writer);

  // Run all the diagnostic tests.
  controller.Run(model);
  delete model;

  // The "press enter to continue" prompt isn't very unixy, so only do that on
  // Windows.
#if defined(OS_WIN)
  // Block here so the user can see the results.
  writer.WriteInfoText(L"Press [enter] to continue\n");
  std::wstring txt;
  console->Read(&txt);
#endif
  delete console;
  return 0;
}
<|endoftext|>


<commit_before>#ifndef MESSAGES_HPP_
#define MESSAGES_HPP_

#include <cstdint>

namespace protocol {
namespace message {

struct heartbeat_message_t {
  enum { ID = 0x00 };

  std::uint8_t seq;
} __attribute__((packed));

struct log_message_t {
  enum { ID = 0x01 };

  char data[255];
} __attribute__((packed));

struct attitude_message_t {
  enum { ID = 0x02 };

  float roll;
  float pitch;
  float yaw;
} __attribute__((packed));

std::uint16_t length(int id) {
  // TODO(kyle): sizeof(empty struct) is 1 in C++...
  switch(id) {
    case heartbeat_message_t::ID:
      return sizeof(heartbeat_message_t);
    case log_message_t::ID:
      return sizeof(log_message_t);
    case attitude_message_t::ID:
      return sizeof(attitude_message_t);
  }

  return 0; // TODO(kyle): Return something more meaningful?
}

}
}

#endif // MESSAGES_HPP_

<commit_msg>Add control mode message.<commit_after>#ifndef MESSAGES_HPP_
#define MESSAGES_HPP_

#include <cstdint>

namespace protocol {
namespace message {

struct heartbeat_message_t {
  enum { ID = 0x00 };

  std::uint8_t seq;
} __attribute__((packed));

struct log_message_t {
  enum { ID = 0x01 };

  char data[255];
} __attribute__((packed));

struct attitude_message_t {
  enum { ID = 0x02 };

  float roll;
  float pitch;
  float yaw;
} __attribute__((packed));

struct set_control_mode_message_t {
  enum { ID = 0x03 };

  enum class ControlMode {
    MANUAL,
    OFFBOARD
  };

  ControlMode mode;
} __attribute__((packed));

std::uint16_t length(int id) {
  // TODO(kyle): sizeof(empty struct) is 1 in C++...
  switch(id) {
    case heartbeat_message_t::ID:
      return sizeof(heartbeat_message_t);
    case log_message_t::ID:
      return sizeof(log_message_t);
    case attitude_message_t::ID:
      return sizeof(attitude_message_t);
    case set_control_mode_message_t::ID:
      return sizeof(set_control_mode_message_t);
  }

  return 0; // TODO(kyle): Return something more meaningful?
}

}
}

#endif // MESSAGES_HPP_

<|endoftext|>