<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.

// Provides wifi scan API binding for suitable for typical linux distributions.
// Currently, only the NetworkManager API is used, accessed via D-Bus (in turn
// accessed via the GLib wrapper).

#include "chrome/browser/geolocation/wifi_data_provider_linux.h"

#include <dbus/dbus-glib.h>
#include <glib.h>

#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"

namespace {
// The time periods between successive polls of the wifi data.
const int kDefaultPollingIntervalMilliseconds = 10 * 1000;  // 10s
const int kNoChangePollingIntervalMilliseconds = 2 * 60 * 1000;  // 2 mins
const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000;  // 10 mins

const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager";
const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager";
const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager";

// From http://projects.gnome.org/NetworkManager/developers/spec.html
enum { NM_DEVICE_TYPE_WIFI = 2 };

// Utility wrappers to make various GLib & DBus structs into scoped objects.
class ScopedGPtrArrayFree {
 public:
  void operator()(GPtrArray* x) const {
    if (x)
      g_ptr_array_free(x, TRUE);
  }
};
// Use ScopedGPtrArrayPtr as if it were scoped_ptr<GPtrArray>
typedef scoped_ptr_malloc<GPtrArray, ScopedGPtrArrayFree> ScopedGPtrArrayPtr;

class ScopedGObjectFree {
 public:
  void operator()(void* x) const {
    if (x)
      g_object_unref(x);
  }
};
// Use ScopedDBusGProxyPtr as if it were scoped_ptr<DBusGProxy>
typedef scoped_ptr_malloc<DBusGProxy, ScopedGObjectFree> ScopedDBusGProxyPtr;

// Use ScopedGValue::v as an instance of GValue with automatic cleanup.
class ScopedGValue {
 public:
  ScopedGValue()
      : v(empty_gvalue()) {
  }
  ~ScopedGValue() {
    g_value_unset(&v);
  }
  static GValue empty_gvalue() {
    GValue value = {0};
    return value;
  }

  GValue v;
};

// Wifi API binding to NetworkManager, to allow reuse of the polling behavior
// defined in WifiDataProviderCommon.
// TODO(joth): NetworkManager also allows for notification based handling,
// however this will require reworking of the threading code to run a GLib
// event loop (GMainLoop).
class NetworkManagerWlanApi : public WifiDataProviderCommon::WlanApiInterface {
 public:
  NetworkManagerWlanApi();
  ~NetworkManagerWlanApi();

  // Must be called before any other interface method. Will return false if the
  // NetworkManager session cannot be created (e.g. not present on this distro),
  // in which case no other method may be called.
  bool Init();

  // WifiDataProviderCommon::WlanApiInterface
  bool GetAccessPointData(WifiData::AccessPointDataSet* data);

 private:
  // Checks if the last dbus call returned an error.  If it did, logs the error
  // message, frees it and returns true.
  // This must be called after every dbus call that accepts |&error_|
  bool CheckError();

  // Enumerates the list of available network adapter devices known to
  // NetworkManager. Ownership of the array (and contained objects) is returned
  // to the caller.
  GPtrArray* GetAdapterDeviceList();

  // Given the NetworkManager path to a wireless adapater, dumps the wifi scan
  // results and appends them to |data|. Returns false if a fatal error is
  // encountered such that the data set could not be populated.
  bool GetAccessPointsForAdapter(const gchar* adapter_path,
                                 WifiData::AccessPointDataSet* data);

  // Internal method used by |GetAccessPointsForAdapter|, given a wifi access
  // point proxy retrieves the named property into |value_out|. Returns false if
  // the property could not be read, or is not of type |expected_gvalue_type|.
  bool GetAccessPointProperty(DBusGProxy* proxy, const char* property_name,
                              int expected_gvalue_type, GValue* value_out);

  // Error from the last dbus call.  NULL when there's no error.  Freed and
  // cleared by CheckError().
  GError* error_;
  // Connection to the dbus system bus.
  DBusGConnection* connection_;
  // Proxy to the network maanger dbus service.
  ScopedDBusGProxyPtr proxy_;

  DISALLOW_COPY_AND_ASSIGN(NetworkManagerWlanApi);
};

// Convert a wifi frequency to the corresponding channel. Adapted from
// geolocaiton/wifilib.cc in googleclient (internal to google).
int frquency_in_khz_to_channel(int frequency_khz) {
  if (frequency_khz >= 2412000 && frequency_khz <= 2472000)  // Channels 1-13.
    return (frequency_khz - 2407000) / 5000;
  if (frequency_khz == 2484000)
    return 14;
  if (frequency_khz > 5000000 && frequency_khz < 6000000)  // .11a bands.
    return (frequency_khz - 5000000) / 5000;
  // Ignore everything else.
  return AccessPointData().channel;  // invalid channel
}

NetworkManagerWlanApi::NetworkManagerWlanApi()
    : error_(NULL), connection_(NULL) {
}

NetworkManagerWlanApi::~NetworkManagerWlanApi() {
  proxy_.reset();
  if (connection_) {
    dbus_g_connection_unref(connection_);
  }
  DCHECK(!error_) << "Missing a call to CheckError() to clear |error_|";
}

bool NetworkManagerWlanApi::Init() {
  // Chrome DLL init code handles initializing the thread system, so rather than
  // get caught up with that nonsense here, lets just assert our requirement.
  CHECK(g_thread_supported());

  // We should likely do this higher up too, the docs say it must only be done
  // once but there's no way to know if it already was or not.
  dbus_g_thread_init();

  // Get a connection to the session bus.
  connection_ = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error_);
  if (CheckError())
    return false;
  DCHECK(connection_);

  proxy_.reset(dbus_g_proxy_new_for_name(connection_,
                                         kNetworkManagerServiceName,
                                         kNetworkManagerPath,
                                         kNetworkManagerInterface));
  DCHECK(proxy_.get());

  // Validate the proxy object by checking we can enumerate devices.
  ScopedGPtrArrayPtr device_list(GetAdapterDeviceList());
  return !!device_list.get();
}

bool NetworkManagerWlanApi::GetAccessPointData(
    WifiData::AccessPointDataSet* data) {
  ScopedGPtrArrayPtr device_list(GetAdapterDeviceList());
  if (device_list == NULL) {
    DLOG(WARNING) << "Could not enumerate access points";
    return false;
  }
  int success_count = 0;
  int fail_count = 0;

  // Iterate the devices, getting APs for each wireless adapter found
  for (guint i = 0; i < device_list->len; i++) {
    const gchar* device_path =
        reinterpret_cast<const gchar*>(g_ptr_array_index(device_list, i));

    ScopedDBusGProxyPtr device_properties_proxy(dbus_g_proxy_new_from_proxy(
        proxy_.get(), DBUS_INTERFACE_PROPERTIES, device_path));
    ScopedGValue device_type_g_value;
    dbus_g_proxy_call(device_properties_proxy.get(), "Get",  &error_,
                      G_TYPE_STRING, "org.freedesktop.NetworkManager.Device",
                      G_TYPE_STRING, "DeviceType",
                      G_TYPE_INVALID,
                      G_TYPE_VALUE,   &device_type_g_value.v,
                      G_TYPE_INVALID);
    if (CheckError())
      continue;

    const guint device_type = g_value_get_uint(&device_type_g_value.v);

    if (device_type == NM_DEVICE_TYPE_WIFI) {  // Found a wlan adapter
      if (GetAccessPointsForAdapter(device_path, data))
        ++success_count;
      else
        ++fail_count;
    }
  }
  // At least one successfull scan overrides any other adapter reporting error.
  return success_count || fail_count == 0;
}

bool NetworkManagerWlanApi::CheckError() {
  if (error_) {
    LOG(ERROR) << "Failed to complete NetworkManager call: " << error_->message;
    g_error_free(error_);
    error_ = NULL;
    return true;
  }
  return false;
}

GPtrArray* NetworkManagerWlanApi::GetAdapterDeviceList() {
  GPtrArray* device_list = NULL;
  dbus_g_proxy_call(proxy_.get(), "GetDevices", &error_,
                    G_TYPE_INVALID,
                    dbus_g_type_get_collection("GPtrArray",
                                               DBUS_TYPE_G_OBJECT_PATH),
                    &device_list,
                    G_TYPE_INVALID);
  if (CheckError())
    return NULL;
  return device_list;
}

bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
    const gchar* adapter_path, WifiData::AccessPointDataSet* data) {
  DCHECK(proxy_.get());

  // Create a proxy object for this wifi adapter, and ask it to do a scan
  // (or at least, dump its scan results).
  ScopedDBusGProxyPtr wifi_adapter_proxy(dbus_g_proxy_new_from_proxy(
      proxy_.get(), "org.freedesktop.NetworkManager.Device.Wireless",
      adapter_path));

  GPtrArray* ap_list_raw = NULL;
  // Enumerate the access points for this adapter.
  dbus_g_proxy_call(wifi_adapter_proxy.get(), "GetAccessPoints",  &error_,
                    G_TYPE_INVALID,
                    dbus_g_type_get_collection("GPtrArray",
                                               DBUS_TYPE_G_OBJECT_PATH),
                    &ap_list_raw,
                    G_TYPE_INVALID);
  ScopedGPtrArrayPtr ap_list(ap_list_raw);  // Takes ownership.
  ap_list_raw = NULL;

  if (CheckError())
    return false;

  DLOG(INFO) << "Wireless adapter " << adapter_path << " found "
             << ap_list->len << " access points.";

  for (guint i = 0; i < ap_list->len; i++) {
    const gchar* ap_path =
        reinterpret_cast<const gchar*>(g_ptr_array_index(ap_list, i));
    ScopedDBusGProxyPtr access_point_proxy(dbus_g_proxy_new_from_proxy(
        proxy_.get(), DBUS_INTERFACE_PROPERTIES, ap_path));

    AccessPointData access_point_data;
    {  // Read SSID.
      ScopedGValue ssid_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "Ssid",
                                  G_TYPE_BOXED, &ssid_g_value.v))
        continue;
      const GArray* ssid =
          reinterpret_cast<const GArray*>(g_value_get_boxed(&ssid_g_value.v));
      UTF8ToUTF16(ssid->data, ssid->len, &access_point_data.ssid);
    }

    { // Read the mac address
      ScopedGValue mac_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "HwAddress",
                                  G_TYPE_STRING, &mac_g_value.v))
        continue;
      std::string mac = g_value_get_string(&mac_g_value.v);
      ReplaceSubstringsAfterOffset(&mac, 0U, ":", "");
      std::vector<uint8> mac_bytes;
      if (!HexStringToBytes(mac, &mac_bytes) || mac_bytes.size() != 6) {
        DLOG(WARNING) << "Can't parse mac address (found " << mac_bytes.size()
                      << " bytes) so using raw string: " << mac;
        access_point_data.mac_address = UTF8ToUTF16(mac);
      } else {
        access_point_data.mac_address = MacAddressAsString16(&mac_bytes[0]);
      }
    }

    {  // Read signal strength.
      ScopedGValue signal_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "Strength",
                                  G_TYPE_UCHAR, &signal_g_value.v))
        continue;
      // Convert strength as a percentage into dBs.
      access_point_data.radio_signal_strength =
          -100 + g_value_get_uchar(&signal_g_value.v) / 2;
    }

    { // Read the channel
      ScopedGValue freq_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "Frequency",
                                  G_TYPE_UINT, &freq_g_value.v))
        continue;
      // NetworkManager returns frequency in MHz.
      access_point_data.channel =
          frquency_in_khz_to_channel(g_value_get_uint(&freq_g_value.v) * 1000);
    }
    data->insert(access_point_data);
  }
  return true;
}

bool NetworkManagerWlanApi::GetAccessPointProperty(DBusGProxy* proxy,
                                                   const char* property_name,
                                                   int expected_gvalue_type,
                                                   GValue* value_out) {
  dbus_g_proxy_call(proxy, "Get", &error_,
                    G_TYPE_STRING, "org.freedesktop.NetworkManager.AccessPoint",
                    G_TYPE_STRING, property_name,
                    G_TYPE_INVALID,
                    G_TYPE_VALUE, value_out,
                    G_TYPE_INVALID);
  if (CheckError())
    return false;
  if (!G_VALUE_HOLDS(value_out, expected_gvalue_type)) {
    DLOG(WARNING) << "Property " << property_name << " unexptected type "
                  << G_VALUE_TYPE(value_out);
    return false;
  }
  return true;
}

}  // namespace

// static
template<>
WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
  return new WifiDataProviderLinux();
}

WifiDataProviderLinux::WifiDataProviderLinux() {
}

WifiDataProviderLinux::~WifiDataProviderLinux() {
}

WifiDataProviderCommon::WlanApiInterface*
WifiDataProviderLinux::NewWlanApi() {
  scoped_ptr<NetworkManagerWlanApi> wlan_api(new NetworkManagerWlanApi);
  if (wlan_api->Init())
    return wlan_api.release();
  return NULL;
}

PollingPolicyInterface* WifiDataProviderLinux::NewPollingPolicy() {
  return new GenericPollingPolicy<kDefaultPollingIntervalMilliseconds,
                                  kNoChangePollingIntervalMilliseconds,
                                  kTwoNoChangePollingIntervalMilliseconds>;
}

<commit_msg>Work-around for DBus crash due to timers firing on the wrong thread.<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.

// Provides wifi scan API binding for suitable for typical linux distributions.
// Currently, only the NetworkManager API is used, accessed via D-Bus (in turn
// accessed via the GLib wrapper).

#include "chrome/browser/geolocation/wifi_data_provider_linux.h"

#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus.h>
#include <glib.h>

#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"

namespace {
// The time periods between successive polls of the wifi data.
const int kDefaultPollingIntervalMilliseconds = 10 * 1000;  // 10s
const int kNoChangePollingIntervalMilliseconds = 2 * 60 * 1000;  // 2 mins
const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000;  // 10 mins

const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager";
const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager";
const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager";

// From http://projects.gnome.org/NetworkManager/developers/spec.html
enum { NM_DEVICE_TYPE_WIFI = 2 };

// Utility wrappers to make various GLib & DBus structs into scoped objects.
class ScopedGPtrArrayFree {
 public:
  void operator()(GPtrArray* x) const {
    if (x)
      g_ptr_array_free(x, TRUE);
  }
};
// Use ScopedGPtrArrayPtr as if it were scoped_ptr<GPtrArray>
typedef scoped_ptr_malloc<GPtrArray, ScopedGPtrArrayFree> ScopedGPtrArrayPtr;

class ScopedGObjectFree {
 public:
  void operator()(void* x) const {
    if (x)
      g_object_unref(x);
  }
};
// Use ScopedDBusGProxyPtr as if it were scoped_ptr<DBusGProxy>
typedef scoped_ptr_malloc<DBusGProxy, ScopedGObjectFree> ScopedDBusGProxyPtr;

// Use ScopedGValue::v as an instance of GValue with automatic cleanup.
class ScopedGValue {
 public:
  ScopedGValue()
      : v(empty_gvalue()) {
  }
  ~ScopedGValue() {
    g_value_unset(&v);
  }
  static GValue empty_gvalue() {
    GValue value = {0};
    return value;
  }

  GValue v;
};

// Wifi API binding to NetworkManager, to allow reuse of the polling behavior
// defined in WifiDataProviderCommon.
// TODO(joth): NetworkManager also allows for notification based handling,
// however this will require reworking of the threading code to run a GLib
// event loop (GMainLoop).
class NetworkManagerWlanApi : public WifiDataProviderCommon::WlanApiInterface {
 public:
  NetworkManagerWlanApi();
  ~NetworkManagerWlanApi();

  // Must be called before any other interface method. Will return false if the
  // NetworkManager session cannot be created (e.g. not present on this distro),
  // in which case no other method may be called.
  bool Init();

  // WifiDataProviderCommon::WlanApiInterface
  bool GetAccessPointData(WifiData::AccessPointDataSet* data);

 private:
  // Checks if the last dbus call returned an error.  If it did, logs the error
  // message, frees it and returns true.
  // This must be called after every dbus call that accepts |&error_|
  bool CheckError();

  // Enumerates the list of available network adapter devices known to
  // NetworkManager. Ownership of the array (and contained objects) is returned
  // to the caller.
  GPtrArray* GetAdapterDeviceList();

  // Given the NetworkManager path to a wireless adapater, dumps the wifi scan
  // results and appends them to |data|. Returns false if a fatal error is
  // encountered such that the data set could not be populated.
  bool GetAccessPointsForAdapter(const gchar* adapter_path,
                                 WifiData::AccessPointDataSet* data);

  // Internal method used by |GetAccessPointsForAdapter|, given a wifi access
  // point proxy retrieves the named property into |value_out|. Returns false if
  // the property could not be read, or is not of type |expected_gvalue_type|.
  bool GetAccessPointProperty(DBusGProxy* proxy, const char* property_name,
                              int expected_gvalue_type, GValue* value_out);

  // Error from the last dbus call.  NULL when there's no error.  Freed and
  // cleared by CheckError().
  GError* error_;
  // Connection to the dbus system bus.
  DBusGConnection* connection_;
  // Proxy to the network maanger dbus service.
  ScopedDBusGProxyPtr proxy_;

  DISALLOW_COPY_AND_ASSIGN(NetworkManagerWlanApi);
};

// Convert a wifi frequency to the corresponding channel. Adapted from
// geolocaiton/wifilib.cc in googleclient (internal to google).
int frquency_in_khz_to_channel(int frequency_khz) {
  if (frequency_khz >= 2412000 && frequency_khz <= 2472000)  // Channels 1-13.
    return (frequency_khz - 2407000) / 5000;
  if (frequency_khz == 2484000)
    return 14;
  if (frequency_khz > 5000000 && frequency_khz < 6000000)  // .11a bands.
    return (frequency_khz - 5000000) / 5000;
  // Ignore everything else.
  return AccessPointData().channel;  // invalid channel
}

NetworkManagerWlanApi::NetworkManagerWlanApi()
    : error_(NULL), connection_(NULL) {
}

NetworkManagerWlanApi::~NetworkManagerWlanApi() {
  proxy_.reset();
  if (connection_) {
    dbus_g_connection_unref(connection_);
  }
  DCHECK(!error_) << "Missing a call to CheckError() to clear |error_|";
}

bool NetworkManagerWlanApi::Init() {
  // Chrome DLL init code handles initializing the thread system, so rather than
  // get caught up with that nonsense here, lets just assert our requirement.
  CHECK(g_thread_supported());

  // We should likely do this higher up too, the docs say it must only be done
  // once but there's no way to know if it already was or not.
  dbus_g_thread_init();

  // Get a connection to the session bus.
  connection_ = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error_);
  if (CheckError())
    return false;
  DCHECK(connection_);

  // dbus-glib queues timers that get fired on the default loop, unfortunately
  // it isn't thread safe in it's handling of these timers. We can't easily
  // tell it which loop to queue them on instead, but as we only make
  // blocking sync calls we don't need timers anyway, so disable them.
  // See http://crbug.com/40803 TODO(joth): This is not an ideal solution, as
  // we're reconfiguring the process global system bus connection, so could
  // impact other users of DBus.
  dbus_bool_t ok = dbus_connection_set_timeout_functions(
      dbus_g_connection_get_connection(connection_),
      NULL, NULL, NULL, NULL, NULL);
  DCHECK(ok);

  proxy_.reset(dbus_g_proxy_new_for_name(connection_,
                                         kNetworkManagerServiceName,
                                         kNetworkManagerPath,
                                         kNetworkManagerInterface));
  DCHECK(proxy_.get());

  // Validate the proxy object by checking we can enumerate devices.
  ScopedGPtrArrayPtr device_list(GetAdapterDeviceList());
  return !!device_list.get();
}

bool NetworkManagerWlanApi::GetAccessPointData(
    WifiData::AccessPointDataSet* data) {
  ScopedGPtrArrayPtr device_list(GetAdapterDeviceList());
  if (device_list == NULL) {
    DLOG(WARNING) << "Could not enumerate access points";
    return false;
  }
  int success_count = 0;
  int fail_count = 0;

  // Iterate the devices, getting APs for each wireless adapter found
  for (guint i = 0; i < device_list->len; i++) {
    const gchar* device_path =
        reinterpret_cast<const gchar*>(g_ptr_array_index(device_list, i));

    ScopedDBusGProxyPtr device_properties_proxy(dbus_g_proxy_new_from_proxy(
        proxy_.get(), DBUS_INTERFACE_PROPERTIES, device_path));
    ScopedGValue device_type_g_value;
    dbus_g_proxy_call(device_properties_proxy.get(), "Get",  &error_,
                      G_TYPE_STRING, "org.freedesktop.NetworkManager.Device",
                      G_TYPE_STRING, "DeviceType",
                      G_TYPE_INVALID,
                      G_TYPE_VALUE,   &device_type_g_value.v,
                      G_TYPE_INVALID);
    if (CheckError())
      continue;

    const guint device_type = g_value_get_uint(&device_type_g_value.v);

    if (device_type == NM_DEVICE_TYPE_WIFI) {  // Found a wlan adapter
      if (GetAccessPointsForAdapter(device_path, data))
        ++success_count;
      else
        ++fail_count;
    }
  }
  // At least one successfull scan overrides any other adapter reporting error.
  return success_count || fail_count == 0;
}

bool NetworkManagerWlanApi::CheckError() {
  if (error_) {
    LOG(ERROR) << "Failed to complete NetworkManager call: " << error_->message;
    g_error_free(error_);
    error_ = NULL;
    return true;
  }
  return false;
}

GPtrArray* NetworkManagerWlanApi::GetAdapterDeviceList() {
  GPtrArray* device_list = NULL;
  dbus_g_proxy_call(proxy_.get(), "GetDevices", &error_,
                    G_TYPE_INVALID,
                    dbus_g_type_get_collection("GPtrArray",
                                               DBUS_TYPE_G_OBJECT_PATH),
                    &device_list,
                    G_TYPE_INVALID);
  if (CheckError())
    return NULL;
  return device_list;
}

bool NetworkManagerWlanApi::GetAccessPointsForAdapter(
    const gchar* adapter_path, WifiData::AccessPointDataSet* data) {
  DCHECK(proxy_.get());

  // Create a proxy object for this wifi adapter, and ask it to do a scan
  // (or at least, dump its scan results).
  ScopedDBusGProxyPtr wifi_adapter_proxy(dbus_g_proxy_new_from_proxy(
      proxy_.get(), "org.freedesktop.NetworkManager.Device.Wireless",
      adapter_path));

  GPtrArray* ap_list_raw = NULL;
  // Enumerate the access points for this adapter.
  dbus_g_proxy_call(wifi_adapter_proxy.get(), "GetAccessPoints",  &error_,
                    G_TYPE_INVALID,
                    dbus_g_type_get_collection("GPtrArray",
                                               DBUS_TYPE_G_OBJECT_PATH),
                    &ap_list_raw,
                    G_TYPE_INVALID);
  ScopedGPtrArrayPtr ap_list(ap_list_raw);  // Takes ownership.
  ap_list_raw = NULL;

  if (CheckError())
    return false;

  DLOG(INFO) << "Wireless adapter " << adapter_path << " found "
             << ap_list->len << " access points.";

  for (guint i = 0; i < ap_list->len; i++) {
    const gchar* ap_path =
        reinterpret_cast<const gchar*>(g_ptr_array_index(ap_list, i));
    ScopedDBusGProxyPtr access_point_proxy(dbus_g_proxy_new_from_proxy(
        proxy_.get(), DBUS_INTERFACE_PROPERTIES, ap_path));

    AccessPointData access_point_data;
    {  // Read SSID.
      ScopedGValue ssid_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "Ssid",
                                  G_TYPE_BOXED, &ssid_g_value.v))
        continue;
      const GArray* ssid =
          reinterpret_cast<const GArray*>(g_value_get_boxed(&ssid_g_value.v));
      UTF8ToUTF16(ssid->data, ssid->len, &access_point_data.ssid);
    }

    { // Read the mac address
      ScopedGValue mac_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "HwAddress",
                                  G_TYPE_STRING, &mac_g_value.v))
        continue;
      std::string mac = g_value_get_string(&mac_g_value.v);
      ReplaceSubstringsAfterOffset(&mac, 0U, ":", "");
      std::vector<uint8> mac_bytes;
      if (!HexStringToBytes(mac, &mac_bytes) || mac_bytes.size() != 6) {
        DLOG(WARNING) << "Can't parse mac address (found " << mac_bytes.size()
                      << " bytes) so using raw string: " << mac;
        access_point_data.mac_address = UTF8ToUTF16(mac);
      } else {
        access_point_data.mac_address = MacAddressAsString16(&mac_bytes[0]);
      }
    }

    {  // Read signal strength.
      ScopedGValue signal_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "Strength",
                                  G_TYPE_UCHAR, &signal_g_value.v))
        continue;
      // Convert strength as a percentage into dBs.
      access_point_data.radio_signal_strength =
          -100 + g_value_get_uchar(&signal_g_value.v) / 2;
    }

    { // Read the channel
      ScopedGValue freq_g_value;
      if (!GetAccessPointProperty(access_point_proxy.get(), "Frequency",
                                  G_TYPE_UINT, &freq_g_value.v))
        continue;
      // NetworkManager returns frequency in MHz.
      access_point_data.channel =
          frquency_in_khz_to_channel(g_value_get_uint(&freq_g_value.v) * 1000);
    }
    data->insert(access_point_data);
  }
  return true;
}

bool NetworkManagerWlanApi::GetAccessPointProperty(DBusGProxy* proxy,
                                                   const char* property_name,
                                                   int expected_gvalue_type,
                                                   GValue* value_out) {
  dbus_g_proxy_call(proxy, "Get", &error_,
                    G_TYPE_STRING, "org.freedesktop.NetworkManager.AccessPoint",
                    G_TYPE_STRING, property_name,
                    G_TYPE_INVALID,
                    G_TYPE_VALUE, value_out,
                    G_TYPE_INVALID);
  if (CheckError())
    return false;
  if (!G_VALUE_HOLDS(value_out, expected_gvalue_type)) {
    DLOG(WARNING) << "Property " << property_name << " unexptected type "
                  << G_VALUE_TYPE(value_out);
    return false;
  }
  return true;
}

}  // namespace

// static
template<>
WifiDataProviderImplBase* WifiDataProvider::DefaultFactoryFunction() {
  return new WifiDataProviderLinux();
}

WifiDataProviderLinux::WifiDataProviderLinux() {
}

WifiDataProviderLinux::~WifiDataProviderLinux() {
}

WifiDataProviderCommon::WlanApiInterface*
WifiDataProviderLinux::NewWlanApi() {
  scoped_ptr<NetworkManagerWlanApi> wlan_api(new NetworkManagerWlanApi);
  if (wlan_api->Init())
    return wlan_api.release();
  return NULL;
}

PollingPolicyInterface* WifiDataProviderLinux::NewPollingPolicy() {
  return new GenericPollingPolicy<kDefaultPollingIntervalMilliseconds,
                                  kNoChangePollingIntervalMilliseconds,
                                  kTwoNoChangePollingIntervalMilliseconds>;
}

<|endoftext|>


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

#include "chrome/browser/policy/cloud_policy_manager.h"

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "chrome/browser/policy/configuration_policy_provider_test.h"
#include "chrome/browser/policy/mock_cloud_policy_client.h"
#include "chrome/browser/policy/mock_cloud_policy_store.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_builder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Mock;
using testing::_;

namespace em = enterprise_management;

namespace policy {
namespace {

class TestHarness : public PolicyProviderTestHarness {
 public:
  explicit TestHarness(PolicyLevel level);
  virtual ~TestHarness();

  virtual void SetUp() OVERRIDE;

  virtual ConfigurationPolicyProvider* CreateProvider(
      const PolicyDefinitionList* policy_definition_list) OVERRIDE;

  virtual void InstallEmptyPolicy() OVERRIDE;
  virtual void InstallStringPolicy(const std::string& policy_name,
                                   const std::string& policy_value) OVERRIDE;
  virtual void InstallIntegerPolicy(const std::string& policy_name,
                                    int policy_value) OVERRIDE;
  virtual void InstallBooleanPolicy(const std::string& policy_name,
                                    bool policy_value) OVERRIDE;
  virtual void InstallStringListPolicy(
      const std::string& policy_name,
      const base::ListValue* policy_value) OVERRIDE;
  virtual void InstallDictionaryPolicy(
      const std::string& policy_name,
      const base::DictionaryValue* policy_value) OVERRIDE;

  // Creates harnesses for mandatory and recommended levels, respectively.
  static PolicyProviderTestHarness* CreateMandatory();
  static PolicyProviderTestHarness* CreateRecommended();

 private:
  MockCloudPolicyStore* store_;

  DISALLOW_COPY_AND_ASSIGN(TestHarness);
};

TestHarness::TestHarness(PolicyLevel level)
    : PolicyProviderTestHarness(level, POLICY_SCOPE_USER) {}

TestHarness::~TestHarness() {}

void TestHarness::SetUp() {}

ConfigurationPolicyProvider* TestHarness::CreateProvider(
    const PolicyDefinitionList* policy_definition_list) {
  // Create and initialize the store.
  store_ = new MockCloudPolicyStore();
  store_->NotifyStoreLoaded();
  EXPECT_CALL(*store_, Load());
  return new CloudPolicyManager(scoped_ptr<CloudPolicyStore>(store_));
  Mock::VerifyAndClearExpectations(store_);
}

void TestHarness::InstallEmptyPolicy() {}

void TestHarness::InstallStringPolicy(const std::string& policy_name,
                                      const std::string& policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          base::Value::CreateStringValue(policy_value));
}

void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
                                       int policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          base::Value::CreateIntegerValue(policy_value));
}

void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
                                       bool policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          base::Value::CreateBooleanValue(policy_value));
}

void TestHarness::InstallStringListPolicy(const std::string& policy_name,
                                          const base::ListValue* policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          policy_value->DeepCopy());
}

void TestHarness::InstallDictionaryPolicy(
    const std::string& policy_name,
    const base::DictionaryValue* policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          policy_value->DeepCopy());
}

// static
PolicyProviderTestHarness* TestHarness::CreateMandatory() {
  return new TestHarness(POLICY_LEVEL_MANDATORY);
}

// static
PolicyProviderTestHarness* TestHarness::CreateRecommended() {
  return new TestHarness(POLICY_LEVEL_RECOMMENDED);
}

// Instantiate abstract test case for basic policy reading tests.
INSTANTIATE_TEST_CASE_P(
    UserCloudPolicyManagerProviderTest,
    ConfigurationPolicyProviderTest,
    testing::Values(TestHarness::CreateMandatory,
                    TestHarness::CreateRecommended));

class TestCloudPolicyManager : public CloudPolicyManager {
 public:
  explicit TestCloudPolicyManager(scoped_ptr<CloudPolicyStore> store)
      : CloudPolicyManager(store.Pass()) {}
  virtual ~TestCloudPolicyManager() {}

  // Publish the protected members for testing.
  using CloudPolicyManager::InitializeService;
  using CloudPolicyManager::ShutdownService;
  using CloudPolicyManager::StartRefreshScheduler;
  using CloudPolicyManager::CheckAndPublishPolicy;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestCloudPolicyManager);
};

MATCHER_P(ProtoMatches, proto, "") {
  return arg.SerializePartialAsString() == proto.SerializePartialAsString();
}

class CloudPolicyManagerTest : public testing::Test {
 protected:
  CloudPolicyManagerTest() {}

  virtual void SetUp() OVERRIDE {
    // Set up a policy map for testing.
    policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                    base::Value::CreateStringValue("value"));
    expected_bundle_.Get(POLICY_DOMAIN_CHROME, std::string()).CopyFrom(
        policy_map_);

    policy_.payload().mutable_homepagelocation()->set_homepagelocation(
        "http://www.example.com");
    policy_.Build();

    store_ = new MockCloudPolicyStore();
    EXPECT_CALL(*store_, Load());
    manager_.reset(
        new TestCloudPolicyManager(scoped_ptr<CloudPolicyStore>(store_)));
    manager_->Init();
    Mock::VerifyAndClearExpectations(store_);
    manager_->AddObserver(&observer_);
  }

  virtual void TearDown() OVERRIDE {
    manager_->RemoveObserver(&observer_);
    manager_->Shutdown();
  }

  // Required by the refresh scheduler that's created by the manager.
  MessageLoop loop_;

  // Testing policy.
  UserPolicyBuilder policy_;
  PolicyMap policy_map_;
  PolicyBundle expected_bundle_;

  // Policy infrastructure.
  MockConfigurationPolicyObserver observer_;
  MockCloudPolicyStore* store_;
  scoped_ptr<TestCloudPolicyManager> manager_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CloudPolicyManagerTest);
};

TEST_F(CloudPolicyManagerTest, InitAndShutdown) {
  PolicyBundle empty_bundle;
  EXPECT_TRUE(empty_bundle.Equals(manager_->policies()));
  EXPECT_FALSE(manager_->IsInitializationComplete());

  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  manager_->CheckAndPublishPolicy();
  Mock::VerifyAndClearExpectations(&observer_);

  store_->policy_map_.CopyFrom(policy_map_);
  store_->policy_.reset(new em::PolicyData(policy_.policy_data()));
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
  EXPECT_TRUE(manager_->IsInitializationComplete());

  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  EXPECT_CALL(*client, SetupRegistration(_, _));
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));
  Mock::VerifyAndClearExpectations(client);
  EXPECT_TRUE(manager_->cloud_policy_client());
  EXPECT_TRUE(manager_->cloud_policy_service());

  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  manager_->CheckAndPublishPolicy();
  Mock::VerifyAndClearExpectations(&observer_);

  manager_->ShutdownService();
  EXPECT_FALSE(manager_->cloud_policy_client());
  EXPECT_FALSE(manager_->cloud_policy_service());
}

TEST_F(CloudPolicyManagerTest, RegistrationAndFetch) {
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(manager_->IsInitializationComplete());

  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));

  client->SetDMToken(policy_.policy_data().request_token());
  client->NotifyRegistrationStateChanged();

  client->SetPolicy(policy_.policy());
  EXPECT_CALL(*store_, Store(ProtoMatches(policy_.policy())));
  client->NotifyPolicyFetched();
  Mock::VerifyAndClearExpectations(store_);

  store_->policy_map_.CopyFrom(policy_map_);
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
}

TEST_F(CloudPolicyManagerTest, Update) {
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(manager_->IsInitializationComplete());
  PolicyBundle empty_bundle;
  EXPECT_TRUE(empty_bundle.Equals(manager_->policies()));

  store_->policy_map_.CopyFrom(policy_map_);
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
  EXPECT_TRUE(manager_->IsInitializationComplete());
}

TEST_F(CloudPolicyManagerTest, RefreshNotRegistered) {
  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));

  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);

  // A refresh on a non-registered store should not block.
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  manager_->RefreshPolicies();
  Mock::VerifyAndClearExpectations(&observer_);
}

TEST_F(CloudPolicyManagerTest, RefreshSuccessful) {
  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));

  // Simulate a store load.
  store_->policy_.reset(new em::PolicyData(policy_.policy_data()));
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  EXPECT_CALL(*client, SetupRegistration(_, _));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(client);
  Mock::VerifyAndClearExpectations(&observer_);

  // Acknowledge registration.
  client->SetDMToken(policy_.policy_data().request_token());

  // Start a refresh.
  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  EXPECT_CALL(*client, FetchPolicy());
  manager_->RefreshPolicies();
  Mock::VerifyAndClearExpectations(client);
  Mock::VerifyAndClearExpectations(&observer_);
  store_->policy_map_.CopyFrom(policy_map_);

  // A stray reload should be suppressed until the refresh completes.
  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);

  // Respond to the policy fetch, which should trigger a write to |store_|.
  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  EXPECT_CALL(*store_, Store(_));
  client->SetPolicy(policy_.policy());
  client->NotifyPolicyFetched();
  Mock::VerifyAndClearExpectations(&observer_);
  Mock::VerifyAndClearExpectations(store_);

  // The load notification from |store_| should trigger the policy update.
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
  Mock::VerifyAndClearExpectations(&observer_);
}

}  // namespace
}  // namespace policy
<commit_msg>Fix bad CloudPolicyManager test harness setup.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/policy/cloud_policy_manager.h"

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "chrome/browser/policy/configuration_policy_provider_test.h"
#include "chrome/browser/policy/mock_cloud_policy_client.h"
#include "chrome/browser/policy/mock_cloud_policy_store.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_builder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Mock;
using testing::_;

namespace em = enterprise_management;

namespace policy {
namespace {

class TestHarness : public PolicyProviderTestHarness {
 public:
  explicit TestHarness(PolicyLevel level);
  virtual ~TestHarness();

  virtual void SetUp() OVERRIDE;

  virtual ConfigurationPolicyProvider* CreateProvider(
      const PolicyDefinitionList* policy_definition_list) OVERRIDE;

  virtual void InstallEmptyPolicy() OVERRIDE;
  virtual void InstallStringPolicy(const std::string& policy_name,
                                   const std::string& policy_value) OVERRIDE;
  virtual void InstallIntegerPolicy(const std::string& policy_name,
                                    int policy_value) OVERRIDE;
  virtual void InstallBooleanPolicy(const std::string& policy_name,
                                    bool policy_value) OVERRIDE;
  virtual void InstallStringListPolicy(
      const std::string& policy_name,
      const base::ListValue* policy_value) OVERRIDE;
  virtual void InstallDictionaryPolicy(
      const std::string& policy_name,
      const base::DictionaryValue* policy_value) OVERRIDE;

  // Creates harnesses for mandatory and recommended levels, respectively.
  static PolicyProviderTestHarness* CreateMandatory();
  static PolicyProviderTestHarness* CreateRecommended();

 private:
  MockCloudPolicyStore* store_;

  DISALLOW_COPY_AND_ASSIGN(TestHarness);
};

TestHarness::TestHarness(PolicyLevel level)
    : PolicyProviderTestHarness(level, POLICY_SCOPE_USER) {}

TestHarness::~TestHarness() {}

void TestHarness::SetUp() {}

ConfigurationPolicyProvider* TestHarness::CreateProvider(
    const PolicyDefinitionList* policy_definition_list) {
  // Create and initialize the store.
  store_ = new MockCloudPolicyStore();
  store_->NotifyStoreLoaded();
  EXPECT_CALL(*store_, Load());
  ConfigurationPolicyProvider* provider =
      new CloudPolicyManager(scoped_ptr<CloudPolicyStore>(store_));
  Mock::VerifyAndClearExpectations(store_);
  return provider;
}

void TestHarness::InstallEmptyPolicy() {}

void TestHarness::InstallStringPolicy(const std::string& policy_name,
                                      const std::string& policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          base::Value::CreateStringValue(policy_value));
}

void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
                                       int policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          base::Value::CreateIntegerValue(policy_value));
}

void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
                                       bool policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          base::Value::CreateBooleanValue(policy_value));
}

void TestHarness::InstallStringListPolicy(const std::string& policy_name,
                                          const base::ListValue* policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          policy_value->DeepCopy());
}

void TestHarness::InstallDictionaryPolicy(
    const std::string& policy_name,
    const base::DictionaryValue* policy_value) {
  store_->policy_map_.Set(policy_name, policy_level(), policy_scope(),
                          policy_value->DeepCopy());
}

// static
PolicyProviderTestHarness* TestHarness::CreateMandatory() {
  return new TestHarness(POLICY_LEVEL_MANDATORY);
}

// static
PolicyProviderTestHarness* TestHarness::CreateRecommended() {
  return new TestHarness(POLICY_LEVEL_RECOMMENDED);
}

// Instantiate abstract test case for basic policy reading tests.
INSTANTIATE_TEST_CASE_P(
    UserCloudPolicyManagerProviderTest,
    ConfigurationPolicyProviderTest,
    testing::Values(TestHarness::CreateMandatory,
                    TestHarness::CreateRecommended));

class TestCloudPolicyManager : public CloudPolicyManager {
 public:
  explicit TestCloudPolicyManager(scoped_ptr<CloudPolicyStore> store)
      : CloudPolicyManager(store.Pass()) {}
  virtual ~TestCloudPolicyManager() {}

  // Publish the protected members for testing.
  using CloudPolicyManager::InitializeService;
  using CloudPolicyManager::ShutdownService;
  using CloudPolicyManager::StartRefreshScheduler;
  using CloudPolicyManager::CheckAndPublishPolicy;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestCloudPolicyManager);
};

MATCHER_P(ProtoMatches, proto, "") {
  return arg.SerializePartialAsString() == proto.SerializePartialAsString();
}

class CloudPolicyManagerTest : public testing::Test {
 protected:
  CloudPolicyManagerTest() {}

  virtual void SetUp() OVERRIDE {
    // Set up a policy map for testing.
    policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                    base::Value::CreateStringValue("value"));
    expected_bundle_.Get(POLICY_DOMAIN_CHROME, std::string()).CopyFrom(
        policy_map_);

    policy_.payload().mutable_homepagelocation()->set_homepagelocation(
        "http://www.example.com");
    policy_.Build();

    store_ = new MockCloudPolicyStore();
    EXPECT_CALL(*store_, Load());
    manager_.reset(
        new TestCloudPolicyManager(scoped_ptr<CloudPolicyStore>(store_)));
    manager_->Init();
    Mock::VerifyAndClearExpectations(store_);
    manager_->AddObserver(&observer_);
  }

  virtual void TearDown() OVERRIDE {
    manager_->RemoveObserver(&observer_);
    manager_->Shutdown();
  }

  // Required by the refresh scheduler that's created by the manager.
  MessageLoop loop_;

  // Testing policy.
  UserPolicyBuilder policy_;
  PolicyMap policy_map_;
  PolicyBundle expected_bundle_;

  // Policy infrastructure.
  MockConfigurationPolicyObserver observer_;
  MockCloudPolicyStore* store_;
  scoped_ptr<TestCloudPolicyManager> manager_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CloudPolicyManagerTest);
};

TEST_F(CloudPolicyManagerTest, InitAndShutdown) {
  PolicyBundle empty_bundle;
  EXPECT_TRUE(empty_bundle.Equals(manager_->policies()));
  EXPECT_FALSE(manager_->IsInitializationComplete());

  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  manager_->CheckAndPublishPolicy();
  Mock::VerifyAndClearExpectations(&observer_);

  store_->policy_map_.CopyFrom(policy_map_);
  store_->policy_.reset(new em::PolicyData(policy_.policy_data()));
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
  EXPECT_TRUE(manager_->IsInitializationComplete());

  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  EXPECT_CALL(*client, SetupRegistration(_, _));
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));
  Mock::VerifyAndClearExpectations(client);
  EXPECT_TRUE(manager_->cloud_policy_client());
  EXPECT_TRUE(manager_->cloud_policy_service());

  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  manager_->CheckAndPublishPolicy();
  Mock::VerifyAndClearExpectations(&observer_);

  manager_->ShutdownService();
  EXPECT_FALSE(manager_->cloud_policy_client());
  EXPECT_FALSE(manager_->cloud_policy_service());
}

TEST_F(CloudPolicyManagerTest, RegistrationAndFetch) {
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(manager_->IsInitializationComplete());

  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));

  client->SetDMToken(policy_.policy_data().request_token());
  client->NotifyRegistrationStateChanged();

  client->SetPolicy(policy_.policy());
  EXPECT_CALL(*store_, Store(ProtoMatches(policy_.policy())));
  client->NotifyPolicyFetched();
  Mock::VerifyAndClearExpectations(store_);

  store_->policy_map_.CopyFrom(policy_map_);
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
}

TEST_F(CloudPolicyManagerTest, Update) {
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(manager_->IsInitializationComplete());
  PolicyBundle empty_bundle;
  EXPECT_TRUE(empty_bundle.Equals(manager_->policies()));

  store_->policy_map_.CopyFrom(policy_map_);
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
  EXPECT_TRUE(manager_->IsInitializationComplete());
}

TEST_F(CloudPolicyManagerTest, RefreshNotRegistered) {
  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));

  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);

  // A refresh on a non-registered store should not block.
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  manager_->RefreshPolicies();
  Mock::VerifyAndClearExpectations(&observer_);
}

TEST_F(CloudPolicyManagerTest, RefreshSuccessful) {
  MockCloudPolicyClient* client = new MockCloudPolicyClient();
  manager_->InitializeService(scoped_ptr<CloudPolicyClient>(client));

  // Simulate a store load.
  store_->policy_.reset(new em::PolicyData(policy_.policy_data()));
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  EXPECT_CALL(*client, SetupRegistration(_, _));
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(client);
  Mock::VerifyAndClearExpectations(&observer_);

  // Acknowledge registration.
  client->SetDMToken(policy_.policy_data().request_token());

  // Start a refresh.
  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  EXPECT_CALL(*client, FetchPolicy());
  manager_->RefreshPolicies();
  Mock::VerifyAndClearExpectations(client);
  Mock::VerifyAndClearExpectations(&observer_);
  store_->policy_map_.CopyFrom(policy_map_);

  // A stray reload should be suppressed until the refresh completes.
  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  store_->NotifyStoreLoaded();
  Mock::VerifyAndClearExpectations(&observer_);

  // Respond to the policy fetch, which should trigger a write to |store_|.
  EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
  EXPECT_CALL(*store_, Store(_));
  client->SetPolicy(policy_.policy());
  client->NotifyPolicyFetched();
  Mock::VerifyAndClearExpectations(&observer_);
  Mock::VerifyAndClearExpectations(store_);

  // The load notification from |store_| should trigger the policy update.
  EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
  store_->NotifyStoreLoaded();
  EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
  Mock::VerifyAndClearExpectations(&observer_);
}

}  // namespace
}  // namespace policy
<|endoftext|>


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

#include "base/bind.h"
#include "chrome/browser/profiles/profile_impl.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/ui_test_utils.h"

namespace {

// An observer that returns back to test code after a new profile is
// initialized.
void OnUnblockOnProfileCreation(Profile* profile,
                                Profile::CreateStatus status) {
  if (status == Profile::CREATE_STATUS_INITIALIZED)
    MessageLoop::current()->Quit();
}

} // namespace

// This file contains tests for the ProfileManager that require a heavyweight
// InProcessBrowserTest.  These include tests involving profile deletion.

class ProfileManagerBrowserTest : public InProcessBrowserTest {
};

// TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
// platforms.
#if defined(OS_MACOSX)
// Delete single profile and make sure a new one is created.
IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();

  // We should start out with 1 profile.
  ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);

  // Delete singleton profile.
  FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
  EXPECT_FALSE(singleton_profile_path.empty());
  profile_manager->ScheduleProfileForDeletion(singleton_profile_path);

  // Spin things till profile is actually deleted.
  ui_test_utils::RunAllPendingInMessageLoop();

  // Make sure a new profile was created automatically.
  EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
  FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
  EXPECT_NE(new_profile_path, singleton_profile_path);

  // Make sure that last used profile preference is set correctly.
  Profile* last_used = ProfileManager::GetLastUsedProfile();
  EXPECT_EQ(new_profile_path, last_used->GetPath());
}

// Delete all profiles in a multi profile setup and make sure a new one is
// created.

#if defined(OS_MACOSX)
// Crashes/CHECKs. See crbug.com/104851
#define MAYBE_DeleteAllProfiles DISABLED_DeleteAllProfiles
#else
#define MAYBE_DeleteAllProfiles DeleteAllProfiles
#endif

IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, MAYBE_DeleteAllProfiles) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();

  // Create an additional profile.
  FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
  profile_manager->CreateProfileAsync(new_path,
                                      base::Bind(&OnUnblockOnProfileCreation));

  // Spin to allow profile creation to take place, loop is terminated
  // by OnUnblockOnProfileCreation when the profile is created.
  ui_test_utils::RunMessageLoop();

  ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);

  // Delete all profiles.
  FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
  FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
  EXPECT_FALSE(profile_path1.empty());
  EXPECT_FALSE(profile_path2.empty());
  profile_manager->ScheduleProfileForDeletion(profile_path1);
  profile_manager->ScheduleProfileForDeletion(profile_path2);

  // Spin things so deletion can take place.
  ui_test_utils::RunAllPendingInMessageLoop();

  // Make sure a new profile was created automatically.
  EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
  FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
  EXPECT_NE(new_profile_path, profile_path1);
  EXPECT_NE(new_profile_path, profile_path2);

  // Make sure that last used profile preference is set correctly.
  Profile* last_used = ProfileManager::GetLastUsedProfile();
  EXPECT_EQ(new_profile_path, last_used->GetPath());
}
#endif  // OS_MACOSX

#if defined(OS_MACOSX)
#define MAYBE_ProfileReadmeCreated ProfileReadmeCreated
#else
#define MAYBE_ProfileReadmeCreated DISABLED_ProfileReadmeCreated
#endif

// Ensure that README file is created for a new profile.
// TODO(ivankr): this test probably should belong to profile_browsertest.cc.
IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, MAYBE_ProfileReadmeCreated) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // No delay before README creation.
  ProfileImpl::create_readme_delay_ms = 0;

  // Create an additional profile.
  FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
  profile_manager->CreateProfileAsync(new_path,
                                      base::Bind(&OnUnblockOnProfileCreation));

  // Spin to allow profile creation to take place, loop is terminated
  // by OnUnblockOnProfileCreation when the profile is created.
  ui_test_utils::RunMessageLoop();

  // Verify that README exists.
  EXPECT_TRUE(file_util::PathExists(new_path.Append(chrome::kReadmeFilename)));
}
<commit_msg>Revert 126404 - Disabled ProfileManagerBrowserTest.ProfileReadmeCreated on non-Macs.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "chrome/browser/profiles/profile_impl.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/ui_test_utils.h"

namespace {

// An observer that returns back to test code after a new profile is
// initialized.
void OnUnblockOnProfileCreation(Profile* profile,
                                Profile::CreateStatus status) {
  if (status == Profile::CREATE_STATUS_INITIALIZED)
    MessageLoop::current()->Quit();
}

} // namespace

// This file contains tests for the ProfileManager that require a heavyweight
// InProcessBrowserTest.  These include tests involving profile deletion.

class ProfileManagerBrowserTest : public InProcessBrowserTest {
};

// TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
// platforms.
#if defined(OS_MACOSX)
// Delete single profile and make sure a new one is created.
IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();

  // We should start out with 1 profile.
  ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);

  // Delete singleton profile.
  FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
  EXPECT_FALSE(singleton_profile_path.empty());
  profile_manager->ScheduleProfileForDeletion(singleton_profile_path);

  // Spin things till profile is actually deleted.
  ui_test_utils::RunAllPendingInMessageLoop();

  // Make sure a new profile was created automatically.
  EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
  FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
  EXPECT_NE(new_profile_path, singleton_profile_path);

  // Make sure that last used profile preference is set correctly.
  Profile* last_used = ProfileManager::GetLastUsedProfile();
  EXPECT_EQ(new_profile_path, last_used->GetPath());
}

// Delete all profiles in a multi profile setup and make sure a new one is
// created.

#if defined(OS_MACOSX)
// Crashes/CHECKs. See crbug.com/104851
#define MAYBE_DeleteAllProfiles DISABLED_DeleteAllProfiles
#else
#define MAYBE_DeleteAllProfiles DeleteAllProfiles
#endif

IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, MAYBE_DeleteAllProfiles) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();

  // Create an additional profile.
  FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
  profile_manager->CreateProfileAsync(new_path,
                                      base::Bind(&OnUnblockOnProfileCreation));

  // Spin to allow profile creation to take place, loop is terminated
  // by OnUnblockOnProfileCreation when the profile is created.
  ui_test_utils::RunMessageLoop();

  ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);

  // Delete all profiles.
  FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
  FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
  EXPECT_FALSE(profile_path1.empty());
  EXPECT_FALSE(profile_path2.empty());
  profile_manager->ScheduleProfileForDeletion(profile_path1);
  profile_manager->ScheduleProfileForDeletion(profile_path2);

  // Spin things so deletion can take place.
  ui_test_utils::RunAllPendingInMessageLoop();

  // Make sure a new profile was created automatically.
  EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
  FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
  EXPECT_NE(new_profile_path, profile_path1);
  EXPECT_NE(new_profile_path, profile_path2);

  // Make sure that last used profile preference is set correctly.
  Profile* last_used = ProfileManager::GetLastUsedProfile();
  EXPECT_EQ(new_profile_path, last_used->GetPath());
}
#endif  // OS_MACOSX

// Ensure that README file is created for a new profile.
// TODO(ivankr): this test probably should belong to profile_browsertest.cc.
IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, ProfileReadmeCreated) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // No delay before README creation.
  ProfileImpl::create_readme_delay_ms = 0;

  // Create an additional profile.
  FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
  profile_manager->CreateProfileAsync(new_path,
                                      base::Bind(&OnUnblockOnProfileCreation));

  // Spin to allow profile creation to take place, loop is terminated
  // by OnUnblockOnProfileCreation when the profile is created.
  ui_test_utils::RunMessageLoop();

  // Verify that README exists.
  EXPECT_TRUE(file_util::PathExists(new_path.Append(chrome::kReadmeFilename)));
}
<|endoftext|>


<commit_before>/* dtkComposerScenePort.cpp ---
 *
 * Author: Julien Wintz
 * Copyright (C) 2008-2011 - Julien Wintz, Inria.
 * Created: Fri Feb  3 13:59:41 2012 (+0100)
 * Version: $Id$
 * Last-Updated: Fri May  4 09:42:27 2012 (+0200)
 *           By: Julien Wintz
 *     Update #: 131
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "dtkComposerSceneNode.h"
#include "dtkComposerSceneNodeControl.h"
#include "dtkComposerScenePort.h"

class dtkComposerScenePortPrivate
{
public:
    dtkComposerScenePort::Type type;

public:
    dtkComposerSceneNode *node;

public:
    int loop;

public:
    QGraphicsEllipseItem *ellipse;
    QGraphicsTextItem *label;
};

dtkComposerScenePort::dtkComposerScenePort(Type type, dtkComposerSceneNode *parent) : QGraphicsItem(parent), d(new dtkComposerScenePortPrivate)
{
    d->type = type;
    d->node = parent;
    d->loop = 0;

    d->ellipse = new QGraphicsEllipseItem(this);
    d->ellipse->setPen(QPen(Qt::darkGray, 1));
    d->ellipse->setBrush(Qt::lightGray);
    d->ellipse->setRect(0, 0, 10, 10);

    d->label = new QGraphicsTextItem(this);
#if defined(Q_WS_MAC)
    d->label->setFont(QFont("Lucida Grande", 11));
#else
    d->label->setFont(QFont("Lucida Grande", 9));
#endif
    d->label->setDefaultTextColor(Qt::white);

    this->setFlags(QGraphicsItem::ItemIsSelectable);
    this->setZValue(1);
}

dtkComposerScenePort::dtkComposerScenePort(Type type, const QString& label, dtkComposerSceneNode *parent) : QGraphicsItem(parent), d(new dtkComposerScenePortPrivate)
{
    d->type = type;
    d->node = parent;
    d->loop = 0;

    d->ellipse = new QGraphicsEllipseItem(this);
    d->ellipse->setPen(QPen(Qt::darkGray, 1));
    d->ellipse->setBrush(Qt::lightGray);
    d->ellipse->setRect(0, 0, 10, 10);

    d->label = new QGraphicsTextItem(this);
#if defined(Q_WS_MAC)
    d->label->setFont(QFont("Lucida Grande", 11));
#else
    d->label->setFont(QFont("Lucida Grande", 9));
#endif
    d->label->setDefaultTextColor(Qt::white);

    this->setLabel(label);
    this->setFlags(QGraphicsItem::ItemIsSelectable);
    this->setZValue(1);
}

dtkComposerScenePort::~dtkComposerScenePort(void)
{
    delete d;

    d = NULL;
}

dtkComposerScenePort::Type dtkComposerScenePort::type(void)
{
    return d->type;
}

dtkComposerSceneNode *dtkComposerScenePort::node(void)
{
    return d->node;
}

dtkComposerSceneNode *dtkComposerScenePort::owner(void)
{
    if (dynamic_cast<dtkComposerSceneNodeControl *>(d->node->parent()))
        return d->node->parent();

    return d->node;
}

int dtkComposerScenePort::loop(void)
{
    return d->loop;
}

QString dtkComposerScenePort::label(void)
{
    return d->label->toPlainText();
}

void dtkComposerScenePort::setLoop(int loop)
{
    d->loop = loop;
}

void dtkComposerScenePort::setLabel(const QString& label)
{
    d->label->setPlainText(label);

    QFontMetricsF fm(d->label->font());

    if(d->type == Input)
        d->label->setPos(d->ellipse->pos() + QPointF(d->ellipse->boundingRect().width(), 0) - QPointF(0, fm.height()/2.0));
    else
        d->label->setPos(d->ellipse->pos() - QPointF(7, 0) - QPointF(fm.width(label), fm.height()/2.0));
}

QRectF dtkComposerScenePort::boundingRect(void) const
{
    return QRectF(0, 0, 10, 10);
}

void dtkComposerScenePort::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}
<commit_msg>display loop ports in white<commit_after>/* dtkComposerScenePort.cpp ---
 *
 * Author: Julien Wintz
 * Copyright (C) 2008-2011 - Julien Wintz, Inria.
 * Created: Fri Feb  3 13:59:41 2012 (+0100)
 * Version: $Id$
 * Last-Updated: mer. juin  6 16:53:47 2012 (+0200)
 *           By: Nicolas Niclausse
 *     Update #: 140
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "dtkComposerSceneNode.h"
#include "dtkComposerSceneNodeControl.h"
#include "dtkComposerScenePort.h"

class dtkComposerScenePortPrivate
{
public:
    dtkComposerScenePort::Type type;

public:
    dtkComposerSceneNode *node;

public:
    int loop;

public:
    QGraphicsEllipseItem *ellipse;
    QGraphicsTextItem *label;
};

dtkComposerScenePort::dtkComposerScenePort(Type type, dtkComposerSceneNode *parent) : QGraphicsItem(parent), d(new dtkComposerScenePortPrivate)
{
    d->type = type;
    d->node = parent;
    d->loop = 0;

    d->ellipse = new QGraphicsEllipseItem(this);
    d->ellipse->setPen(QPen(Qt::darkGray, 1));
    d->ellipse->setBrush(Qt::lightGray);
    d->ellipse->setRect(0, 0, 10, 10);

    d->label = new QGraphicsTextItem(this);
#if defined(Q_WS_MAC)
    d->label->setFont(QFont("Lucida Grande", 11));
#else
    d->label->setFont(QFont("Lucida Grande", 9));
#endif
    d->label->setDefaultTextColor(Qt::white);

    this->setFlags(QGraphicsItem::ItemIsSelectable);
    this->setZValue(1);
}

dtkComposerScenePort::dtkComposerScenePort(Type type, const QString& label, dtkComposerSceneNode *parent) : QGraphicsItem(parent), d(new dtkComposerScenePortPrivate)
{
    d->type = type;
    d->node = parent;
    d->loop = 0;

    d->ellipse = new QGraphicsEllipseItem(this);
    d->ellipse->setPen(QPen(Qt::darkGray, 1));
    d->ellipse->setBrush(Qt::lightGray);
    d->ellipse->setRect(0, 0, 10, 10);

    d->label = new QGraphicsTextItem(this);
#if defined(Q_WS_MAC)
    d->label->setFont(QFont("Lucida Grande", 11));
#else
    d->label->setFont(QFont("Lucida Grande", 9));
#endif
    d->label->setDefaultTextColor(Qt::white);

    this->setLabel(label);
    this->setFlags(QGraphicsItem::ItemIsSelectable);
    this->setZValue(1);
}

dtkComposerScenePort::~dtkComposerScenePort(void)
{
    delete d;

    d = NULL;
}

dtkComposerScenePort::Type dtkComposerScenePort::type(void)
{
    return d->type;
}

dtkComposerSceneNode *dtkComposerScenePort::node(void)
{
    return d->node;
}

dtkComposerSceneNode *dtkComposerScenePort::owner(void)
{
    if (dynamic_cast<dtkComposerSceneNodeControl *>(d->node->parent()))
        return d->node->parent();

    return d->node;
}

int dtkComposerScenePort::loop(void)
{
    return d->loop;
}

QString dtkComposerScenePort::label(void)
{
    return d->label->toPlainText();
}

void dtkComposerScenePort::setLoop(int loop)
{
    d->loop = loop;
    if (loop > 0)
        d->ellipse->setBrush(Qt::white);
}

void dtkComposerScenePort::setLabel(const QString& label)
{
    d->label->setPlainText(label);

    QFontMetricsF fm(d->label->font());

    if(d->type == Input)
        d->label->setPos(d->ellipse->pos() + QPointF(d->ellipse->boundingRect().width(), 0) - QPointF(0, fm.height()/2.0));
    else
        d->label->setPos(d->ellipse->pos() - QPointF(7, 0) - QPointF(fm.width(label), fm.height()/2.0));
}

QRectF dtkComposerScenePort::boundingRect(void) const
{
    return QRectF(0, 0, 10, 10);
}

void dtkComposerScenePort::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}
<|endoftext|>


<commit_before>/*
    Copyright 2011 Brain Research Institute, Melbourne, Australia

    Written by Robert E. Smith, 2012.

    This file is part of MRtrix.

    MRtrix 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 3 of the License, or
    (at your option) any later version.

    MRtrix 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 MRtrix.  If not, see <http://www.gnu.org/licenses/>.

 */

#include "dwi/tractography/properties.h"
#include "dwi/tractography/seeding/seeding.h"

namespace MR
{
  namespace DWI
  {
    namespace Tractography
    {
      namespace Seeding
      {

      using namespace App;

      const OptionGroup SeedOption = OptionGroup ("Tractography seeding options")

      + Option ("seed_sphere", "spherical seed as four comma-separated values (XYZ position and radius").allow_multiple()
        + Argument ("spec").type_sequence_float()

      + Option ("seed_mask", "seed mask for random placement of seed points").allow_multiple()
        + Argument ("image").type_image_in()

      + Option ("seed_random_per_voxel", "seed a fixed number of streamlines per voxel in the mask; random placement of seeds in each voxel").allow_multiple()
        + Argument ("image").type_image_in()
        + Argument ("num_per_voxel").type_integer (1, 1, std::numeric_limits<int>::max())

      + Option ("seed_grid_per_voxel", "seed a fixed number of streamlines per voxel in the mask; place seeds on a 3D mesh grid").allow_multiple()
        + Argument ("image").type_image_in()
        + Argument ("grid_size").type_integer (1, 1, std::numeric_limits<int>::max())

      + Option ("seed_rejection", "seed from an image using rejection sampling (higher values = more probable to seed from)").allow_multiple()
        + Argument ("image").type_image_in()

      + Option ("seed_gmwmi", "seed from the grey matter - white matter interface (only valid if using ACT framework)").allow_multiple()
        + Argument ("seed_image").type_image_in()

      + Option ("seed_dynamic", "determine seed points dynamically using the SIFT model (must NOT provide any other seed)") // Don't allow multiple
        + Argument ("fod_image").type_image_in();

      void load_tracking_seeds (Properties& properties)
      {

        List& list (properties.seeds);

        App::Options opt = get_options ("seed_sphere");
        for (size_t i = 0; i < opt.size(); ++i) {
          Sphere* seed = new Sphere (opt[i][0], list.get_rng());
          list.add (seed);
        }

        opt = get_options ("seed_mask");
        for (size_t i = 0; i < opt.size(); ++i) {
          Default* seed = new Default (opt[i][0], list.get_rng());
          list.add (seed);
        }

        opt = get_options ("seed_random_per_voxel");
        for (size_t i = 0; i < opt.size(); ++i) {
          Random_per_voxel* seed = new Random_per_voxel (opt[i][0], list.get_rng(), opt[i][1]);
          list.add (seed);
        }

        opt = get_options ("seed_grid_per_voxel");
        for (size_t i = 0; i < opt.size(); ++i) {
          Grid_per_voxel* seed = new Grid_per_voxel (opt[i][0], list.get_rng(), opt[i][1]);
          list.add (seed);
        }

        opt = get_options ("seed_rejection");
        for (size_t i = 0; i < opt.size(); ++i) {
          Rejection* seed = new Rejection (opt[i][0], list.get_rng());
          list.add (seed);
        }

        opt = get_options ("seed_gmwmi");
        if (opt.size()) {
          App::Options opt_act = get_options ("act");
          if (!opt_act.size())
            throw Exception ("Cannot perform GM-WM Interface seeding without ACT segmented tissue image");
          for (size_t i = 0; i < opt.size(); ++i) {
            GMWMI* seed = new GMWMI (opt[i][0], list.get_rng(), str(opt_act[0][0]));
            list.add (seed);
          }
        }

        // Can't instantiate the dynamic seeder here; internal FMLS segmenter has to use the same Directions::Set as TrackMapperDixel
        opt = get_options ("seed_dynamic");
        if (opt.size()) {
          if (list.num_seeds())
            throw Exception ("If performing dynamic streamline seeding, cannot specify any other type of seed!");
          properties["seed_dynamic"] = str(opt[0][0]);
        } else if (!list.num_seeds()) {
          throw Exception ("Must provide at least one source of streamline seeds!");
        }

      }

      }
    }
  }
}

<commit_msg>For tckgen, renamed -seed_mask option to -seed_image, to hopefully reduce confusion with -mask option<commit_after>/*
    Copyright 2011 Brain Research Institute, Melbourne, Australia

    Written by Robert E. Smith, 2012.

    This file is part of MRtrix.

    MRtrix 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 3 of the License, or
    (at your option) any later version.

    MRtrix 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 MRtrix.  If not, see <http://www.gnu.org/licenses/>.

 */

#include "dwi/tractography/properties.h"
#include "dwi/tractography/seeding/seeding.h"

namespace MR
{
  namespace DWI
  {
    namespace Tractography
    {
      namespace Seeding
      {

      using namespace App;

      const OptionGroup SeedOption = OptionGroup ("Tractography seeding options")

      + Option ("seed_sphere", "spherical seed as four comma-separated values (XYZ position and radius").allow_multiple()
        + Argument ("spec").type_sequence_float()

      + Option ("seed_image", "seed streamlines entirely at random within a mask image "
                              "(this is the same behaviour as the streamline seeding in MRtrix 0.2)").allow_multiple()
        + Argument ("image").type_image_in()

      + Option ("seed_random_per_voxel", "seed a fixed number of streamlines per voxel in a mask image; random placement of seeds in each voxel").allow_multiple()
        + Argument ("image").type_image_in()
        + Argument ("num_per_voxel").type_integer (1, 1, std::numeric_limits<int>::max())

      + Option ("seed_grid_per_voxel", "seed a fixed number of streamlines per voxel in a mask image; place seeds on a 3D mesh grid").allow_multiple()
        + Argument ("image").type_image_in()
        + Argument ("grid_size").type_integer (1, 1, std::numeric_limits<int>::max())

      + Option ("seed_rejection", "seed from an image using rejection sampling (higher values = more probable to seed from)").allow_multiple()
        + Argument ("image").type_image_in()

      + Option ("seed_gmwmi", "seed from the grey matter - white matter interface (only valid if using ACT framework)").allow_multiple()
        + Argument ("seed_image").type_image_in()

      + Option ("seed_dynamic", "determine seed points dynamically using the SIFT model (must NOT provide any other seeding mechanism)") // Don't allow multiple
        + Argument ("fod_image").type_image_in();

      void load_tracking_seeds (Properties& properties)
      {

        List& list (properties.seeds);

        App::Options opt = get_options ("seed_sphere");
        for (size_t i = 0; i < opt.size(); ++i) {
          Sphere* seed = new Sphere (opt[i][0], list.get_rng());
          list.add (seed);
        }

        opt = get_options ("seed_image");
        for (size_t i = 0; i < opt.size(); ++i) {
          Default* seed = new Default (opt[i][0], list.get_rng());
          list.add (seed);
        }

        opt = get_options ("seed_random_per_voxel");
        for (size_t i = 0; i < opt.size(); ++i) {
          Random_per_voxel* seed = new Random_per_voxel (opt[i][0], list.get_rng(), opt[i][1]);
          list.add (seed);
        }

        opt = get_options ("seed_grid_per_voxel");
        for (size_t i = 0; i < opt.size(); ++i) {
          Grid_per_voxel* seed = new Grid_per_voxel (opt[i][0], list.get_rng(), opt[i][1]);
          list.add (seed);
        }

        opt = get_options ("seed_rejection");
        for (size_t i = 0; i < opt.size(); ++i) {
          Rejection* seed = new Rejection (opt[i][0], list.get_rng());
          list.add (seed);
        }

        opt = get_options ("seed_gmwmi");
        if (opt.size()) {
          App::Options opt_act = get_options ("act");
          if (!opt_act.size())
            throw Exception ("Cannot perform GM-WM Interface seeding without ACT segmented tissue image");
          for (size_t i = 0; i < opt.size(); ++i) {
            GMWMI* seed = new GMWMI (opt[i][0], list.get_rng(), str(opt_act[0][0]));
            list.add (seed);
          }
        }

        // Can't instantiate the dynamic seeder here; internal FMLS segmenter has to use the same Directions::Set as TrackMapperDixel
        opt = get_options ("seed_dynamic");
        if (opt.size()) {
          if (list.num_seeds())
            throw Exception ("If performing dynamic streamline seeding, cannot specify any other type of seed!");
          properties["seed_dynamic"] = str(opt[0][0]);
        } else if (!list.num_seeds()) {
          throw Exception ("Must provide at least one source of streamline seeds!");
        }

      }

      }
    }
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include <boost/uuid/uuid_io.hpp>

#include <cmn/agent_cmn.h>
#include <route/route.h>

#include <oper/route_common.h>
#include <oper/vrf.h>
#include <oper/tunnel_nh.h>
#include <oper/mpls.h>
#include <oper/vxlan.h>
#include <oper/mirror_table.h>
#include <oper/multicast.h>
#include <controller/controller_export.h>
#include <controller/controller_peer.h>
#include <controller/controller_init.h>
#include <oper/agent_sandesh.h>

using namespace std;
using namespace boost::asio;

static void MulticastTableEnqueue(Agent *agent, DBRequest *req) {
    AgentRouteTable *table = agent->fabric_inet4_multicast_table();
    if (table) {
        table->Enqueue(req);
    }
}

static void MulticastTableProcess(Agent *agent, const string &vrf_name,
                                  DBRequest &req) {
    AgentRouteTable *table =
        agent->vrf_table()->GetInet4MulticastRouteTable(vrf_name);
    if (table) {
        table->Process(req);
    }
}

DBTableBase *Inet4MulticastAgentRouteTable::CreateTable(DB *db,
                                                      const std::string &name) {
    AgentRouteTable *table = new Inet4MulticastAgentRouteTable(db, name);
    table->Init();
    //table->InitRouteTable(db, table, name, Agent::INET4_MULTICAST);
    return table;
}

void
Inet4MulticastAgentRouteTable::AddMulticastRoute(const string &vrf_name,
                                                 const string &vn_name,
                                                 const Ip4Address &src_addr,
                                                 const Ip4Address &grp_addr,
                                                 ComponentNHKeyList
                                                 &component_nh_key_list) {
    DBRequest nh_req;
    NextHopKey *nh_key;
    CompositeNHData *nh_data;

    nh_key = new CompositeNHKey(Composite::L3COMP, true, component_nh_key_list,
                                vrf_name);
    nh_req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    nh_req.key.reset(nh_key);
    nh_data = new CompositeNHData();
    nh_req.data.reset(nh_data);

    DBRequest req;
    req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vrf_name,
                                                                grp_addr,
                                                                src_addr);
    MulticastRoute *data = new MulticastRoute(vn_name,
                                              MplsTable::kInvalidLabel,
                                              VxLanTable::kInvalidvxlan_id,
                                              TunnelType::AllType(),
                                              nh_req, Composite::L3COMP);
    req.key.reset(rt_key);
    req.data.reset(data);
    MulticastTableEnqueue(Agent::GetInstance(), &req);
}

void
Inet4MulticastAgentRouteTable::AddVHostRecvRoute(const string &vm_vrf,
                                                 const string &interface_name,
                                                 const Ip4Address &addr,
                                                 bool policy)
{
    DBRequest req;

    req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vm_vrf, addr);
    req.key.reset(rt_key);
    InetInterfaceKey intf_key(Agent::GetInstance()->
                                     vhost_interface_name());
    ReceiveRoute *data =
        new ReceiveRoute(intf_key, MplsTable::kInvalidLabel,
                         TunnelType::AllType(), policy,
                         Agent::GetInstance()->fabric_vn_name());
    //data->SetMulticast(true);
    req.data.reset(data);
    MulticastTableEnqueue(Agent::GetInstance(), &req);
}

void
Inet4MulticastAgentRouteTable::DeleteMulticastRoute(const string &vrf_name,
                                                    const Ip4Address &src_addr,
                                                    const Ip4Address &grp_addr)
{
    DBRequest req;

    req.oper = DBRequest::DB_ENTRY_DELETE;
    Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vrf_name,
                                                                grp_addr,
                                                                src_addr);

    req.key.reset(rt_key);
    req.data.reset(NULL);
    MulticastTableEnqueue(Agent::GetInstance(), &req);
}

void Inet4MulticastAgentRouteTable::Delete(const string &vrf_name,
                                           const Ip4Address &src_addr,
                                           const Ip4Address &grp_addr) {
    DBRequest req(DBRequest::DB_ENTRY_DELETE);
    req.key.reset(new Inet4MulticastRouteKey(vrf_name, grp_addr, src_addr));
    req.data.reset(NULL);
    MulticastTableProcess(Agent::GetInstance(), vrf_name, req);
}

AgentRoute *
Inet4MulticastRouteKey::AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
{
    Inet4MulticastRouteEntry * entry = new Inet4MulticastRouteEntry(vrf, dip_,
                                                                    sip_);
    return static_cast<AgentRoute *>(entry);
}

AgentRouteKey *Inet4MulticastRouteKey::Clone() const {
    return (new Inet4MulticastRouteKey(vrf_name_, dip_, sip_));
}

string Inet4MulticastRouteKey::ToString() const {
    ostringstream str;
    str << "Group:";
    str << dip_.to_string();
    str << " Src:";
    str << sip_.to_string();
    return str.str();
}

string Inet4MulticastRouteEntry::ToString() const {
    ostringstream str;
    str << "Group:";
    str << dst_addr_.to_string();
    str << " Src:";
    str << src_addr_.to_string();
    return str.str();
}

int Inet4MulticastRouteEntry::CompareTo(const Route &rhs) const {
    const Inet4MulticastRouteEntry &a =
        static_cast<const Inet4MulticastRouteEntry &>(rhs);

    if (src_addr_ < a.src_addr_)
        return -1;

    if (src_addr_ > a.src_addr_)
        return 1;

    if (dst_addr_ < a.dst_addr_)
        return -1;

    if (dst_addr_ > a.dst_addr_)
        return 1;

    return 0;
}

DBEntryBase::KeyPtr Inet4MulticastRouteEntry::GetDBRequestKey() const {
    Inet4MulticastRouteKey *key =
        new Inet4MulticastRouteKey(vrf()->GetName(), dst_addr_,
                                   src_addr_);
    return DBEntryBase::KeyPtr(key);
}

void Inet4MulticastRouteEntry::SetKey(const DBRequestKey *key) {
    const Inet4MulticastRouteKey *k =
        static_cast<const Inet4MulticastRouteKey *>(key);
    SetVrf(Agent::GetInstance()->vrf_table()->FindVrfFromName(k->vrf_name()));
    Ip4Address grp(k->dest_ip_addr());
    Ip4Address src(k->src_ip_addr());
    set_dest_ip_addr(grp);
    set_src_ip_addr(src);
}

bool Inet4MulticastRouteEntry::DBEntrySandesh(Sandesh *sresp, bool stale) const {
    Inet4McRouteResp *resp = static_cast<Inet4McRouteResp *>(sresp);

    RouteMcSandeshData data;
    data.set_src(src_ip_addr().to_string());
    data.set_grp(dest_ip_addr().to_string());
    MulticastGroupObject *mc_obj = MulticastHandler::GetInstance()->
        FindGroupObject(vrf()->GetName(), dest_ip_addr());
    Agent *agent = (static_cast<AgentRouteTable *>(get_table()))->agent();
    if (!stale || (mc_obj->peer_identifier() != agent->controller()->
                   multicast_sequence_number())) {
        GetActiveNextHop()->SetNHSandeshData(data.nh);
    }

    std::vector<RouteMcSandeshData> &list =
        const_cast<std::vector<RouteMcSandeshData>&>(resp->get_route_list());
    list.push_back(data);
    return true;
}

void Inet4McRouteReq::HandleRequest() const {
    VrfEntry *vrf =
        Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
    if (!vrf) {
        ErrorResp *resp = new ErrorResp();
        resp->set_context(context());
        resp->Response();
        return;
    }

    AgentSandeshPtr sand(new AgentInet4McRtSandesh(vrf, context(), "",
                                                   get_stale()));
    sand->DoSandesh(sand);
}

AgentSandeshPtr Inet4MulticastAgentRouteTable::GetAgentSandesh
(const AgentSandeshArguments *args, const std::string &context) {
    return AgentSandeshPtr(new AgentInet4McRtSandesh(vrf_entry(), context, "",
                                                     false));
}
<commit_msg>NULL check.<commit_after>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include <boost/uuid/uuid_io.hpp>

#include <cmn/agent_cmn.h>
#include <route/route.h>

#include <oper/route_common.h>
#include <oper/vrf.h>
#include <oper/tunnel_nh.h>
#include <oper/mpls.h>
#include <oper/vxlan.h>
#include <oper/mirror_table.h>
#include <oper/multicast.h>
#include <controller/controller_export.h>
#include <controller/controller_peer.h>
#include <controller/controller_init.h>
#include <oper/agent_sandesh.h>

using namespace std;
using namespace boost::asio;

static void MulticastTableEnqueue(Agent *agent, DBRequest *req) {
    AgentRouteTable *table = agent->fabric_inet4_multicast_table();
    if (table) {
        table->Enqueue(req);
    }
}

static void MulticastTableProcess(Agent *agent, const string &vrf_name,
                                  DBRequest &req) {
    AgentRouteTable *table =
        agent->vrf_table()->GetInet4MulticastRouteTable(vrf_name);
    if (table) {
        table->Process(req);
    }
}

DBTableBase *Inet4MulticastAgentRouteTable::CreateTable(DB *db,
                                                      const std::string &name) {
    AgentRouteTable *table = new Inet4MulticastAgentRouteTable(db, name);
    table->Init();
    //table->InitRouteTable(db, table, name, Agent::INET4_MULTICAST);
    return table;
}

void
Inet4MulticastAgentRouteTable::AddMulticastRoute(const string &vrf_name,
                                                 const string &vn_name,
                                                 const Ip4Address &src_addr,
                                                 const Ip4Address &grp_addr,
                                                 ComponentNHKeyList
                                                 &component_nh_key_list) {
    DBRequest nh_req;
    NextHopKey *nh_key;
    CompositeNHData *nh_data;

    nh_key = new CompositeNHKey(Composite::L3COMP, true, component_nh_key_list,
                                vrf_name);
    nh_req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    nh_req.key.reset(nh_key);
    nh_data = new CompositeNHData();
    nh_req.data.reset(nh_data);

    DBRequest req;
    req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vrf_name,
                                                                grp_addr,
                                                                src_addr);
    MulticastRoute *data = new MulticastRoute(vn_name,
                                              MplsTable::kInvalidLabel,
                                              VxLanTable::kInvalidvxlan_id,
                                              TunnelType::AllType(),
                                              nh_req, Composite::L3COMP);
    req.key.reset(rt_key);
    req.data.reset(data);
    MulticastTableEnqueue(Agent::GetInstance(), &req);
}

void
Inet4MulticastAgentRouteTable::AddVHostRecvRoute(const string &vm_vrf,
                                                 const string &interface_name,
                                                 const Ip4Address &addr,
                                                 bool policy)
{
    DBRequest req;

    req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vm_vrf, addr);
    req.key.reset(rt_key);
    InetInterfaceKey intf_key(Agent::GetInstance()->
                                     vhost_interface_name());
    ReceiveRoute *data =
        new ReceiveRoute(intf_key, MplsTable::kInvalidLabel,
                         TunnelType::AllType(), policy,
                         Agent::GetInstance()->fabric_vn_name());
    //data->SetMulticast(true);
    req.data.reset(data);
    MulticastTableEnqueue(Agent::GetInstance(), &req);
}

void
Inet4MulticastAgentRouteTable::DeleteMulticastRoute(const string &vrf_name,
                                                    const Ip4Address &src_addr,
                                                    const Ip4Address &grp_addr)
{
    DBRequest req;

    req.oper = DBRequest::DB_ENTRY_DELETE;
    Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vrf_name,
                                                                grp_addr,
                                                                src_addr);

    req.key.reset(rt_key);
    req.data.reset(NULL);
    MulticastTableEnqueue(Agent::GetInstance(), &req);
}

void Inet4MulticastAgentRouteTable::Delete(const string &vrf_name,
                                           const Ip4Address &src_addr,
                                           const Ip4Address &grp_addr) {
    DBRequest req(DBRequest::DB_ENTRY_DELETE);
    req.key.reset(new Inet4MulticastRouteKey(vrf_name, grp_addr, src_addr));
    req.data.reset(NULL);
    MulticastTableProcess(Agent::GetInstance(), vrf_name, req);
}

AgentRoute *
Inet4MulticastRouteKey::AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
{
    Inet4MulticastRouteEntry * entry = new Inet4MulticastRouteEntry(vrf, dip_,
                                                                    sip_);
    return static_cast<AgentRoute *>(entry);
}

AgentRouteKey *Inet4MulticastRouteKey::Clone() const {
    return (new Inet4MulticastRouteKey(vrf_name_, dip_, sip_));
}

string Inet4MulticastRouteKey::ToString() const {
    ostringstream str;
    str << "Group:";
    str << dip_.to_string();
    str << " Src:";
    str << sip_.to_string();
    return str.str();
}

string Inet4MulticastRouteEntry::ToString() const {
    ostringstream str;
    str << "Group:";
    str << dst_addr_.to_string();
    str << " Src:";
    str << src_addr_.to_string();
    return str.str();
}

int Inet4MulticastRouteEntry::CompareTo(const Route &rhs) const {
    const Inet4MulticastRouteEntry &a =
        static_cast<const Inet4MulticastRouteEntry &>(rhs);

    if (src_addr_ < a.src_addr_)
        return -1;

    if (src_addr_ > a.src_addr_)
        return 1;

    if (dst_addr_ < a.dst_addr_)
        return -1;

    if (dst_addr_ > a.dst_addr_)
        return 1;

    return 0;
}

DBEntryBase::KeyPtr Inet4MulticastRouteEntry::GetDBRequestKey() const {
    Inet4MulticastRouteKey *key =
        new Inet4MulticastRouteKey(vrf()->GetName(), dst_addr_,
                                   src_addr_);
    return DBEntryBase::KeyPtr(key);
}

void Inet4MulticastRouteEntry::SetKey(const DBRequestKey *key) {
    const Inet4MulticastRouteKey *k =
        static_cast<const Inet4MulticastRouteKey *>(key);
    SetVrf(Agent::GetInstance()->vrf_table()->FindVrfFromName(k->vrf_name()));
    Ip4Address grp(k->dest_ip_addr());
    Ip4Address src(k->src_ip_addr());
    set_dest_ip_addr(grp);
    set_src_ip_addr(src);
}

bool Inet4MulticastRouteEntry::DBEntrySandesh(Sandesh *sresp, bool stale) const {
    Inet4McRouteResp *resp = static_cast<Inet4McRouteResp *>(sresp);

    RouteMcSandeshData data;
    data.set_src(src_ip_addr().to_string());
    data.set_grp(dest_ip_addr().to_string());
    MulticastGroupObject *mc_obj = MulticastHandler::GetInstance()->
        FindGroupObject(vrf()->GetName(), dest_ip_addr());
    Agent *agent = (static_cast<AgentRouteTable *>(get_table()))->agent();
    if (!stale || (mc_obj && (mc_obj->peer_identifier() != agent->controller()->
                   multicast_sequence_number()))) {
        GetActiveNextHop()->SetNHSandeshData(data.nh);
    }

    std::vector<RouteMcSandeshData> &list =
        const_cast<std::vector<RouteMcSandeshData>&>(resp->get_route_list());
    list.push_back(data);
    return true;
}

void Inet4McRouteReq::HandleRequest() const {
    VrfEntry *vrf =
        Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
    if (!vrf) {
        ErrorResp *resp = new ErrorResp();
        resp->set_context(context());
        resp->Response();
        return;
    }

    AgentSandeshPtr sand(new AgentInet4McRtSandesh(vrf, context(), "",
                                                   get_stale()));
    sand->DoSandesh(sand);
}

AgentSandeshPtr Inet4MulticastAgentRouteTable::GetAgentSandesh
(const AgentSandeshArguments *args, const std::string &context) {
    return AgentSandeshPtr(new AgentInet4McRtSandesh(vrf_entry(), context, "",
                                                     false));
}
<|endoftext|>


<commit_before>#include <cmath>
#include <string>

#include <ros/ros.h>
#include <geometry_msgs/Point.h>
#include <rviz_visual_tools/rviz_visual_tools.h>
#include <tf2_eigen/tf2_eigen.h>
#include <tf2_ros/transform_listener.h>

#include <Eigen/Geometry>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "body_angle_visualizer");
  ros::NodeHandle n {};
  ros::Publisher pub {n.advertise<geometry_msgs::Point>("body_direction", 1)};
  ros::Rate r {5};
  tf2_ros::Buffer tfBuffer {};
  tf2_ros::TransformListener tfListener {tfBuffer};
  rviz_visual_tools::RvizVisualTools rvt {"openni_depth_frame", "rviz_visual_markers"};

  ros::NodeHandle pn {"~"};
  int target_number {0};
  pn.getParam("target_number", target_number);
  std::string root_name {"openni_depth_frame"};
  pn.getParam("root", root_name);

  const auto head_name {"head_" + std::to_string(target_number)};
  const auto torso_name {"torso_" + std::to_string(target_number)};

  while (ros::ok()) {
    try {
      const auto head_pos {tf2::transformToEigen(tfBuffer.lookupTransform(root_name, head_name, ros::Time{0}))};
      const auto torso_pos {tf2::transformToEigen(tfBuffer.lookupTransform(root_name, torso_name, ros::Time{0}))};
      const auto stand_vec {head_pos.translation() - torso_pos.translation()};
      const auto stand_quaternion {Eigen::Quaterniond::FromTwoVectors(Eigen::Vector3d::UnitX(), stand_vec)};

      pub.publish(tf2::toMsg(stand_vec));

      rvt.deleteAllMarkers();
      rvt.publishArrow(Eigen::Affine3d{stand_quaternion});

      Eigen::Affine3d text_pos {};
      text_pos.translation() = stand_vec;
      rvt.publishText(text_pos, std::to_string(stand_vec.normalized()(1)), rviz_visual_tools::WHITE, rviz_visual_tools::XLARGE);

      rvt.trigger();
    } catch (tf2::TransformException &e) {
      ROS_WARN("%s", e.what());
    }

    r.sleep();
  }
}
<commit_msg>Change default number<commit_after>#include <cmath>
#include <string>

#include <ros/ros.h>
#include <geometry_msgs/Point.h>
#include <rviz_visual_tools/rviz_visual_tools.h>
#include <tf2_eigen/tf2_eigen.h>
#include <tf2_ros/transform_listener.h>

#include <Eigen/Geometry>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "body_angle_visualizer");
  ros::NodeHandle n {};
  ros::Publisher pub {n.advertise<geometry_msgs::Point>("body_direction", 1)};
  ros::Rate r {5};
  tf2_ros::Buffer tfBuffer {};
  tf2_ros::TransformListener tfListener {tfBuffer};
  rviz_visual_tools::RvizVisualTools rvt {"openni_depth_frame", "rviz_visual_markers"};

  ros::NodeHandle pn {"~"};
  int target_number {1};
  pn.getParam("target_number", target_number);
  std::string root_name {"openni_depth_frame"};
  pn.getParam("root", root_name);

  const auto head_name {"head_" + std::to_string(target_number)};
  const auto torso_name {"torso_" + std::to_string(target_number)};

  while (ros::ok()) {
    try {
      const auto head_pos {tf2::transformToEigen(tfBuffer.lookupTransform(root_name, head_name, ros::Time{0}))};
      const auto torso_pos {tf2::transformToEigen(tfBuffer.lookupTransform(root_name, torso_name, ros::Time{0}))};
      const auto stand_vec {head_pos.translation() - torso_pos.translation()};
      const auto stand_quaternion {Eigen::Quaterniond::FromTwoVectors(Eigen::Vector3d::UnitX(), stand_vec)};

      pub.publish(tf2::toMsg(stand_vec));

      rvt.deleteAllMarkers();
      rvt.publishArrow(Eigen::Affine3d{stand_quaternion});

      Eigen::Affine3d text_pos {};
      text_pos.translation() = stand_vec;
      rvt.publishText(text_pos, std::to_string(stand_vec.normalized()(1)), rviz_visual_tools::WHITE, rviz_visual_tools::XLARGE);

      rvt.trigger();
    } catch (tf2::TransformException &e) {
      ROS_WARN("%s", e.what());
    }

    r.sleep();
  }
}
<|endoftext|>