<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2018 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file FlightTaskAuto.hpp
 *
 * Map from global triplet to local quadruple.
 */

#pragma once

#include "FlightTask.hpp"
#include <uORB/topics/position_setpoint_triplet.h>
#include <uORB/topics/position_setpoint.h>
#include <uORB/topics/home_position.h>
#include <lib/ecl/geo/geo.h>

/**
 * This enum has to agree with position_setpoint_s type definition
 * The only reason for not using the struct position_setpoint is because
 * of the size
 */
enum class WaypointType : int {
	position = 0,
	velocity,
	loiter,
	takeoff,
	land,
	idle,
	offboard, // only part of this structure due to legacy reason. It is not used within the Auto flighttasks
	follow_target
};

enum class State {
	offtrack, /**< Vehicle is more than cruise speed away from track */
	target_behind, /**< Vehicle is in front of target. */
	previous_infront, /**< Vehilce is behind previous waypoint.*/
	none /**< Vehicle is in normal tracking mode from triplet previous to triplet target */
};

class FlightTaskAuto : public FlightTask
{
public:
	FlightTaskAuto() = default;

	virtual ~FlightTaskAuto() = default;
	bool initializeSubscriptions(SubscriptionArray &subscription_array) override;
	bool activate() override;
	bool updateInitialize() override;

protected:
	void _setDefaultConstraints() override;
	float _getMaxCruiseSpeed() {return MPC_XY_CRUISE.get();} /**< getter for default cruise speed */
	matrix::Vector2f _getTargetVelocityXY(); /**< only used for follow-me and only here because of legacy reason.*/
	void _updateInternalWaypoints(); /**< Depending on state of vehicle, the internal waypoints might differ from target (for instance if offtrack). */

	matrix::Vector3f _prev_prev_wp{}; /**< Pre-previous waypoint (local frame). This will be used for smoothing trajectories -> not used yet. */
	matrix::Vector3f _prev_wp{}; /**< Previous waypoint  (local frame). If no previous triplet is available, the prev_wp is set to current position. */
	matrix::Vector3f _target{}; /**< Target waypoint  (local frame).*/
	matrix::Vector3f _next_wp{}; /**< The next waypoint after target (local frame). If no next setpoint is available, next is set to target. */
	float _mc_cruise_speed{0.0f}; /**< Requested cruise speed. If not valid, default cruise speed is used. */
	WaypointType _type{WaypointType::idle}; /**< Type of current target triplet. */
	uORB::Subscription<home_position_s> *_sub_home_position{nullptr};

	State _current_state{State::none};

	float _speed_at_target = 0.0f; /**< Desired velocity at target. */

	DEFINE_PARAMETERS_CUSTOM_PARENT(FlightTask,
					(ParamFloat<px4::params::MPC_XY_CRUISE>) MPC_XY_CRUISE,
					(ParamFloat<px4::params::MPC_CRUISE_90>) MPC_CRUISE_90, // speed at corner when angle is 90 degrees move to line
					(ParamFloat<px4::params::NAV_ACC_RAD>) NAV_ACC_RAD // acceptance radius at which waypoints are updated move to line
				       ); /**< Default mc cruise speed.*/

private:
	matrix::Vector2f _lock_position_xy{NAN, NAN}; /**< if no valid triplet is received, lock positition to current position */

	uORB::Subscription<position_setpoint_triplet_s> *_sub_triplet_setpoint{nullptr};

	matrix::Vector3f
	_triplet_target; /**< current triplet from navigator which may differ from the intenal one (_target) depending on the vehicle state. */
	matrix::Vector3f
	_triplet_prev_wp; /**< previous triplet from navigator which may differ from the intenal one (_prev_wp) depending on the vehicle state.*/
	matrix::Vector3f
	_triplet_next_wp; /**< next triplet from navigator which may differ from the intenal one (_next_wp) depending on the vehicle state.*/
	matrix::Vector2f _closest_pt; /**< closest point to the vehicle position on the line previous - target */

	map_projection_reference_s _reference_position{}; /**< Structure used to project lat/lon setpoint into local frame. */
	float _reference_altitude = NAN;  /**< Altitude relative to ground. */
	hrt_abstime _time_stamp_reference = 0; /**< time stamp when last reference update occured. */

	bool _evaluateTriplets(); /**< Checks and sets triplets. */
	bool _isFinite(const position_setpoint_s sp); /**< Checks if all waypoint triplets are finite. */
	bool _evaluateGlobalReference(); /**< Check is global reference is available. */
	float _getVelocityFromAngle(const float angle); /**< Computes the speed at target depending on angle. */
	State _getCurrentState(); /**< Computes the current vehicle state based on the vehicle position and navigator triplets. */
};
<commit_msg>FlightTaskAuto/Line: make params protected and add NAC_ACC_RAD and MPC_YAW_MODE<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2018 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file FlightTaskAuto.hpp
 *
 * Map from global triplet to local quadruple.
 */

#pragma once

#include "FlightTask.hpp"
#include <uORB/topics/position_setpoint_triplet.h>
#include <uORB/topics/position_setpoint.h>
#include <uORB/topics/home_position.h>
#include <lib/ecl/geo/geo.h>

/**
 * This enum has to agree with position_setpoint_s type definition
 * The only reason for not using the struct position_setpoint is because
 * of the size
 */
enum class WaypointType : int {
	position = 0,
	velocity,
	loiter,
	takeoff,
	land,
	idle,
	offboard, // only part of this structure due to legacy reason. It is not used within the Auto flighttasks
	follow_target
};

enum class State {
	offtrack, /**< Vehicle is more than cruise speed away from track */
	target_behind, /**< Vehicle is in front of target. */
	previous_infront, /**< Vehilce is behind previous waypoint.*/
	none /**< Vehicle is in normal tracking mode from triplet previous to triplet target */
};

class FlightTaskAuto : public FlightTask
{
public:
	FlightTaskAuto() = default;

	virtual ~FlightTaskAuto() = default;
	bool initializeSubscriptions(SubscriptionArray &subscription_array) override;
	bool activate() override;
	bool updateInitialize() override;

protected:
	void _setDefaultConstraints() override;
	float _getMaxCruiseSpeed() {return MPC_XY_CRUISE.get();} /**< getter for default cruise speed */
	matrix::Vector2f _getTargetVelocityXY(); /**< only used for follow-me and only here because of legacy reason.*/
	void _updateInternalWaypoints(); /**< Depending on state of vehicle, the internal waypoints might differ from target (for instance if offtrack). */

	matrix::Vector3f _prev_prev_wp{}; /**< Pre-previous waypoint (local frame). This will be used for smoothing trajectories -> not used yet. */
	matrix::Vector3f _prev_wp{}; /**< Previous waypoint  (local frame). If no previous triplet is available, the prev_wp is set to current position. */
	matrix::Vector3f _target{}; /**< Target waypoint  (local frame).*/
	matrix::Vector3f _next_wp{}; /**< The next waypoint after target (local frame). If no next setpoint is available, next is set to target. */
	float _mc_cruise_speed{0.0f}; /**< Requested cruise speed. If not valid, default cruise speed is used. */
	WaypointType _type{WaypointType::idle}; /**< Type of current target triplet. */
	uORB::Subscription<home_position_s> *_sub_home_position{nullptr};

	State _current_state{State::none};

	float _speed_at_target = 0.0f; /**< Desired velocity at target. */

	DEFINE_PARAMETERS_CUSTOM_PARENT(FlightTask,
					(ParamFloat<px4::params::MPC_XY_CRUISE>) MPC_XY_CRUISE,
					(ParamFloat<px4::params::MPC_CRUISE_90>) MPC_CRUISE_90, // speed at corner when angle is 90 degrees move to line
					(ParamFloat<px4::params::NAV_ACC_RAD>) NAV_ACC_RAD, // acceptance radius at which waypoints are updated move to line
				    (ParamInt<px4::params::MPC_YAW_MODE>) MPC_YAW_MODE // defines how heading is executed
 					);

private:
	matrix::Vector2f _lock_position_xy{NAN, NAN}; /**< if no valid triplet is received, lock positition to current position */

	uORB::Subscription<position_setpoint_triplet_s> *_sub_triplet_setpoint{nullptr};

	matrix::Vector3f
	_triplet_target; /**< current triplet from navigator which may differ from the intenal one (_target) depending on the vehicle state. */
	matrix::Vector3f
	_triplet_prev_wp; /**< previous triplet from navigator which may differ from the intenal one (_prev_wp) depending on the vehicle state.*/
	matrix::Vector3f
	_triplet_next_wp; /**< next triplet from navigator which may differ from the intenal one (_next_wp) depending on the vehicle state.*/
	matrix::Vector2f _closest_pt; /**< closest point to the vehicle position on the line previous - target */

	map_projection_reference_s _reference_position{}; /**< Structure used to project lat/lon setpoint into local frame. */
	float _reference_altitude = NAN;  /**< Altitude relative to ground. */
	hrt_abstime _time_stamp_reference = 0; /**< time stamp when last reference update occured. */

	bool _evaluateTriplets(); /**< Checks and sets triplets. */
	bool _isFinite(const position_setpoint_s sp); /**< Checks if all waypoint triplets are finite. */
	bool _evaluateGlobalReference(); /**< Check is global reference is available. */
	float _getVelocityFromAngle(const float angle); /**< Computes the speed at target depending on angle. */
	State _getCurrentState(); /**< Computes the current vehicle state based on the vehicle position and navigator triplets. */
	void _set_heading_from_mode(); /**< @see  MPC_YAW_MODE */
};
<|endoftext|>


<commit_before>// Copyright (c) 2009 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#include "libmv/correspondence/feature_matching.h"

#include "libmv/correspondence/ArrayMatcher.h"
#include "libmv/correspondence/ArrayMatcher_BruteForce.h"
#include "libmv/correspondence/ArrayMatcher_Kdtree_Flann.h"
#include "libmv/correspondence/ArrayMatcher_Kdtree.h"

// Compute candidate matches between 2 sets of features.  Two features A and B
// are a candidate match if A is the nearest neighbor of B and B is the nearest
// neighbor of A.
void FindCandidateMatches(const FeatureSet &left,
                          const FeatureSet &right,
                          Matches *matches,
                          eLibmvMatchMethod eMatchMethod) {
  if (left.features.size() == 0 ||
      right.features.size() == 0 )  {
    return;
  }
  int descriptorSize = left.features[0].descriptor.coords.size();

  correspondence::ArrayMatcher<float> * pArrayMatcherA = NULL;
  correspondence::ArrayMatcher<float> * pArrayMatcherB = NULL;
  switch (eMatchMethod)
  {
  case eMATCH_KDTREE:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree<float>;
      pArrayMatcherB = new correspondence::ArrayMatcher_Kdtree<float>;
    }
    break;
    case eMATCH_KDTREE_FLANN:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
      pArrayMatcherB = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
    }
    break;
    case eMATCH_LINEAR:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_BruteForce<float>;
      pArrayMatcherB = new correspondence::ArrayMatcher_BruteForce<float>;
    }
    break;
  };

  if (pArrayMatcherA != NULL && pArrayMatcherB != NULL) {

    // Paste the necessary data in contiguous arrays.
    float * arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left);
    float * arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right);

    libmv::vector<int> indices, indicesReverse;
    libmv::vector<float> distances, distancesReverse;

    bool breturn = false;
    if (pArrayMatcherA->build(arrayA,left.features.size(),descriptorSize) &&
        pArrayMatcherB->build(arrayB,right.features.size(),descriptorSize) )  {

      const int NN = 1;
      breturn =
        pArrayMatcherB->searchNeighbours(arrayA,left.features.size(),
          &indices, &distances, NN) &&
        pArrayMatcherA->searchNeighbours(arrayB,right.features.size(),
          &indicesReverse, &distancesReverse, NN);
    }
    delete pArrayMatcherA;
    delete pArrayMatcherB;

    delete [] arrayA;
    delete [] arrayB;

    // From putative matches get symmetric matches.
    if (breturn)  {
      //TODO(pmoulon) clear previous matches.
      int max_track_number = 0;
      for (size_t i = 0; i < indices.size(); ++i) {
        // Add the matche only if we have a symetric result.
        if (i == indicesReverse[indices[i]])  {
          matches->Insert(0, max_track_number, &left.features[i]);
          matches->Insert(1, max_track_number, &right.features[indices[i]]);
          ++max_track_number;
        }
      }
    }
    else  {
      LOG(INFO) << "[FindCandidateMatches] Cannot compute symmetric matches.";
    }
  }
  else  {
    LOG(INFO) << "[FindCandidateMatches] Unknow input match method.";
  }
}

float * FeatureSet::FeatureSetDescriptorsToContiguousArray
  ( const FeatureSet & featureSet ) {

  if (featureSet.features.size() == 0)  {
    return NULL;
  }
  int descriptorSize = featureSet.features[0].descriptor.coords.size();
  // Allocate and paste the necessary data.
  float * array = new float[featureSet.features.size()*descriptorSize];

  //-- Paste data in the contiguous array :
  for (int i = 0; i < (int)featureSet.features.size(); ++i) {
    for (int j = 0;j < descriptorSize; ++j)
      array[descriptorSize*i + j] = (float)featureSet.features[i][j];
  }
  return array;
}

// Compute candidate matches between 2 sets of features with a ratio.
void FindCandidateMatches_Ratio(const FeatureSet &left,
                          const FeatureSet &right,
                          Matches *matches,
                          eLibmvMatchMethod eMatchMethod,
                          float fRatio) {

  if (left.features.size() == 0 ||
      right.features.size() == 0 )  {
    return;
  }
  int descriptorSize = left.features[0].descriptor.coords.size();

  correspondence::ArrayMatcher<float> * pArrayMatcherA = NULL;
  switch (eMatchMethod)
  {
  case eMATCH_KDTREE:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree<float>;
    }
    break;
    case eMATCH_KDTREE_FLANN:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
    }
    break;
    case eMATCH_LINEAR:
    {
      // Build the arrays matcher in order to compute matches pair.
      LOG(INFO) << "Not yet implemented.";
      return;
    }
    break;
  };

  const int NN = 2;
  if (pArrayMatcherA != NULL) {

    // Paste the necessary data in contiguous arrays.
    float * arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left);
    float * arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right);

    libmv::vector<int> indices;
    libmv::vector<float> distances;

    bool breturn = false;
    if (pArrayMatcherA->build(arrayB,right.features.size(),descriptorSize))  {
      breturn =
        pArrayMatcherA->searchNeighbours(arrayA,left.features.size(),
          &indices, &distances, NN);
    }
    delete pArrayMatcherA;
    delete [] arrayA;
    delete [] arrayB;

    // From putative matches get matches that fit the "Ratio" heuristic.
    if (breturn)  {
      //TODO(pmoulon) clear previous matches.
      int max_track_number = 0;

      for (size_t i = 0; i < left.features.size(); ++i) {
        // Test distance ratio :
        float distance0 = distances[i*NN];
        float distance1 = distances[i*NN+NN-1];

        if (distance0 < fRatio * distance1) {
          matches->Insert(0, max_track_number, &left.features[i]);
          matches->Insert(1, max_track_number, &right.features[indices[i*NN]]);
          ++max_track_number;
        }
      }
    }
    else  {
      LOG(INFO) << "[FindCandidateMatches_Ratio] Cannot compute matches.";
    }
  }
  else  {
    LOG(INFO) << "[FindCandidateMatches_Ratio] Unknow input match method.";
  }
}

// Compute correspondences that match between 2 sets of features with a ratio.
void FindCorrespondences(const FeatureSet &left,
                         const FeatureSet &right,
                         std::map<size_t, size_t> *correspondences,
                         eLibmvMatchMethod eMatchMethod,
                         float fRatio) {
  if (left.features.size() == 0 ||
      right.features.size() == 0 )  {
    return;
  }
  int descriptorSize = left.features[0].descriptor.coords.size();

  correspondence::ArrayMatcher<float> * pArrayMatcherA = NULL;
  switch (eMatchMethod)
  {
  case eMATCH_KDTREE:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree<float>;
    }
    break;
    case eMATCH_KDTREE_FLANN:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
    }
    break;
    case eMATCH_LINEAR:
    {
      // Build the arrays matcher in order to compute matches pair.
      LOG(INFO) << "Not yet implemented.";
      return;
    }
    break;
  };

  const int NN = 2;
  if (pArrayMatcherA != NULL) {

    // Paste the necessary data in contiguous arrays.
    float * arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left);
    float * arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right);

    libmv::vector<int> indices;
    libmv::vector<float> distances;

    bool breturn = false;
    if (pArrayMatcherA->build(arrayB,right.features.size(),descriptorSize))  {
      breturn =
        pArrayMatcherA->searchNeighbours(arrayA,left.features.size(),
          &indices, &distances, NN);
    }
    delete pArrayMatcherA;
    delete [] arrayA;
    delete [] arrayB;

    // From putative matches get matches that fit the "Ratio" heuristic.
    if (breturn)  {
      for (size_t i = 0; i < left.features.size(); ++i) {
        // Test distance ratio :
        float distance0 = distances[i*NN];
        float distance1 = distances[i*NN+NN-1];

        if (distance0 < fRatio * distance1) {
          (*correspondences)[i] = indices[i*NN];
        }
      }
    }
    else  {
      LOG(INFO) << "[FindCandidateMatches_Ratio] Cannot compute matches.";
    }
  }
  else  {
    LOG(INFO) << "[FindCandidateMatches_Ratio] Unknow input match method.";
  }
}<commit_msg>Fixed a small logging typo<commit_after>// Copyright (c) 2009 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#include "libmv/correspondence/feature_matching.h"

#include "libmv/correspondence/ArrayMatcher.h"
#include "libmv/correspondence/ArrayMatcher_BruteForce.h"
#include "libmv/correspondence/ArrayMatcher_Kdtree_Flann.h"
#include "libmv/correspondence/ArrayMatcher_Kdtree.h"

// Compute candidate matches between 2 sets of features.  Two features A and B
// are a candidate match if A is the nearest neighbor of B and B is the nearest
// neighbor of A.
void FindCandidateMatches(const FeatureSet &left,
                          const FeatureSet &right,
                          Matches *matches,
                          eLibmvMatchMethod eMatchMethod) {
  if (left.features.size() == 0 ||
      right.features.size() == 0 )  {
    return;
  }
  int descriptorSize = left.features[0].descriptor.coords.size();

  correspondence::ArrayMatcher<float> * pArrayMatcherA = NULL;
  correspondence::ArrayMatcher<float> * pArrayMatcherB = NULL;
  switch (eMatchMethod)
  {
  case eMATCH_KDTREE:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree<float>;
      pArrayMatcherB = new correspondence::ArrayMatcher_Kdtree<float>;
    }
    break;
    case eMATCH_KDTREE_FLANN:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
      pArrayMatcherB = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
    }
    break;
    case eMATCH_LINEAR:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_BruteForce<float>;
      pArrayMatcherB = new correspondence::ArrayMatcher_BruteForce<float>;
    }
    break;
  };

  if (pArrayMatcherA != NULL && pArrayMatcherB != NULL) {

    // Paste the necessary data in contiguous arrays.
    float * arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left);
    float * arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right);

    libmv::vector<int> indices, indicesReverse;
    libmv::vector<float> distances, distancesReverse;

    bool breturn = false;
    if (pArrayMatcherA->build(arrayA,left.features.size(),descriptorSize) &&
        pArrayMatcherB->build(arrayB,right.features.size(),descriptorSize) )  {

      const int NN = 1;
      breturn =
        pArrayMatcherB->searchNeighbours(arrayA,left.features.size(),
          &indices, &distances, NN) &&
        pArrayMatcherA->searchNeighbours(arrayB,right.features.size(),
          &indicesReverse, &distancesReverse, NN);
    }
    delete pArrayMatcherA;
    delete pArrayMatcherB;

    delete [] arrayA;
    delete [] arrayB;

    // From putative matches get symmetric matches.
    if (breturn)  {
      //TODO(pmoulon) clear previous matches.
      int max_track_number = 0;
      for (size_t i = 0; i < indices.size(); ++i) {
        // Add the matche only if we have a symetric result.
        if (i == indicesReverse[indices[i]])  {
          matches->Insert(0, max_track_number, &left.features[i]);
          matches->Insert(1, max_track_number, &right.features[indices[i]]);
          ++max_track_number;
        }
      }
    }
    else  {
      LOG(INFO) << "[FindCandidateMatches] Cannot compute symmetric matches.";
    }
  }
  else  {
    LOG(INFO) << "[FindCandidateMatches] Unknown input match method.";
  }
}

float * FeatureSet::FeatureSetDescriptorsToContiguousArray
  ( const FeatureSet & featureSet ) {

  if (featureSet.features.size() == 0)  {
    return NULL;
  }
  int descriptorSize = featureSet.features[0].descriptor.coords.size();
  // Allocate and paste the necessary data.
  float * array = new float[featureSet.features.size()*descriptorSize];

  //-- Paste data in the contiguous array :
  for (int i = 0; i < (int)featureSet.features.size(); ++i) {
    for (int j = 0;j < descriptorSize; ++j)
      array[descriptorSize*i + j] = (float)featureSet.features[i][j];
  }
  return array;
}

// Compute candidate matches between 2 sets of features with a ratio.
void FindCandidateMatches_Ratio(const FeatureSet &left,
                          const FeatureSet &right,
                          Matches *matches,
                          eLibmvMatchMethod eMatchMethod,
                          float fRatio) {

  if (left.features.size() == 0 ||
      right.features.size() == 0 )  {
    return;
  }
  int descriptorSize = left.features[0].descriptor.coords.size();

  correspondence::ArrayMatcher<float> * pArrayMatcherA = NULL;
  switch (eMatchMethod)
  {
  case eMATCH_KDTREE:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree<float>;
    }
    break;
    case eMATCH_KDTREE_FLANN:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
    }
    break;
    case eMATCH_LINEAR:
    {
      // Build the arrays matcher in order to compute matches pair.
      LOG(INFO) << "Not yet implemented.";
      return;
    }
    break;
  };

  const int NN = 2;
  if (pArrayMatcherA != NULL) {

    // Paste the necessary data in contiguous arrays.
    float * arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left);
    float * arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right);

    libmv::vector<int> indices;
    libmv::vector<float> distances;

    bool breturn = false;
    if (pArrayMatcherA->build(arrayB,right.features.size(),descriptorSize))  {
      breturn =
        pArrayMatcherA->searchNeighbours(arrayA,left.features.size(),
          &indices, &distances, NN);
    }
    delete pArrayMatcherA;
    delete [] arrayA;
    delete [] arrayB;

    // From putative matches get matches that fit the "Ratio" heuristic.
    if (breturn)  {
      //TODO(pmoulon) clear previous matches.
      int max_track_number = 0;

      for (size_t i = 0; i < left.features.size(); ++i) {
        // Test distance ratio :
        float distance0 = distances[i*NN];
        float distance1 = distances[i*NN+NN-1];

        if (distance0 < fRatio * distance1) {
          matches->Insert(0, max_track_number, &left.features[i]);
          matches->Insert(1, max_track_number, &right.features[indices[i*NN]]);
          ++max_track_number;
        }
      }
    }
    else  {
      LOG(INFO) << "[FindCandidateMatches_Ratio] Cannot compute matches.";
    }
  }
  else  {
    LOG(INFO) << "[FindCandidateMatches_Ratio] Unknow input match method.";
  }
}

// Compute correspondences that match between 2 sets of features with a ratio.
void FindCorrespondences(const FeatureSet &left,
                         const FeatureSet &right,
                         std::map<size_t, size_t> *correspondences,
                         eLibmvMatchMethod eMatchMethod,
                         float fRatio) {
  if (left.features.size() == 0 ||
      right.features.size() == 0 )  {
    return;
  }
  int descriptorSize = left.features[0].descriptor.coords.size();

  correspondence::ArrayMatcher<float> * pArrayMatcherA = NULL;
  switch (eMatchMethod)
  {
  case eMATCH_KDTREE:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree<float>;
    }
    break;
    case eMATCH_KDTREE_FLANN:
    {
      // Build the arrays matcher in order to compute matches pair.
      pArrayMatcherA = new correspondence::ArrayMatcher_Kdtree_Flann<float>;
    }
    break;
    case eMATCH_LINEAR:
    {
      // Build the arrays matcher in order to compute matches pair.
      LOG(INFO) << "Not yet implemented.";
      return;
    }
    break;
  };

  const int NN = 2;
  if (pArrayMatcherA != NULL) {

    // Paste the necessary data in contiguous arrays.
    float * arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left);
    float * arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right);

    libmv::vector<int> indices;
    libmv::vector<float> distances;

    bool breturn = false;
    if (pArrayMatcherA->build(arrayB,right.features.size(),descriptorSize))  {
      breturn =
        pArrayMatcherA->searchNeighbours(arrayA,left.features.size(),
          &indices, &distances, NN);
    }
    delete pArrayMatcherA;
    delete [] arrayA;
    delete [] arrayB;

    // From putative matches get matches that fit the "Ratio" heuristic.
    if (breturn)  {
      for (size_t i = 0; i < left.features.size(); ++i) {
        // Test distance ratio :
        float distance0 = distances[i*NN];
        float distance1 = distances[i*NN+NN-1];

        if (distance0 < fRatio * distance1) {
          (*correspondences)[i] = indices[i*NN];
        }
      }
    }
    else  {
      LOG(INFO) << "[FindCandidateMatches_Ratio] Cannot compute matches.";
    }
  }
  else  {
    LOG(INFO) << "[FindCandidateMatches_Ratio] Unknow input match method.";
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

#ifndef GUARD_transaction_ctrl_hpp
#define GUARD_transaction_ctrl_hpp

#include "account.hpp"
#include "decimal_text_ctrl.hpp"
#include "transaction_type_ctrl.hpp"
#include <jewel/on_windows.hpp>
#include <wx/button.h>
#include <wx/event.h>
#include <wx/panel.h>
#include <wx/gbsizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>

namespace phatbooks
{

// Begin forward declarations

class PhatbooksDatabaseConnection;

namespace gui
{

class AccountCtrl;
class DateCtrl;
class EntryCtrl;
class TopPanel;

// End forward declarations

/**
 * Dialog in which user creates a new transaction (i.e. Journal).
 *
 * @todo Ensure Journal balances.
 *
 * @todo Provide option to save as Draft, Recurring or etc. etc..
 *
 * @todo When the update the TopPanel after posting or cancelling Journal
 * from TransactionCtrl, there is flicker. This is because we are redrawing
 * the entire TopPanel from scratch. We could probably get rid of the flicker
 * by only redrawing the parts we need.
 *
 * @todo Ensure this can handle situation where insufficient default
 * Accounts are available.
 *
 * @todo Handle case where Journal doesn't balance - or else structure
 * things so that this is impossible.
 */
class TransactionCtrl: public wxPanel
{
public:

	/**
	 * All Accounts in p_accounts should be associated with the same
	 * PhatbooksDatabaseConnection.
	 *
	 * @param p_parent parent panel
	 *
	 * @param p_balance_sheet_accounts a sequence of Accounts
	 * all of which must be balance sheet Accounts (i.e. of
	 * account_super_type::balance_sheet). May be empty providing
	 * p_pl_accounts has at least 2 elements.
	 *
	 * @param p_pl_accounts a sequence of Accounts all of which
	 * must be P&L Accounts (i.e. of account_super_type::pl). May be empty
	 * providing p_balance_sheet_accounts has at least 2 elements.
	 *
	 * @param p_database_connection database connection. Must be the same
	 * one that the Accounts in p_balance_sheet_accounts and
	 * p_pl_accounts are associated with.
	 */
	TransactionCtrl
	(	TopPanel* p_parent,
		std::vector<Account> const& p_balance_sheet_accounts,
		std::vector<Account> const& p_pl_accounts,
		PhatbooksDatabaseConnection& p_database_connection
	);

	/**
	 * Refresh the selections available in the AccountCtrls in the
	 * TransactionCtrl, and the selection in the TransactionTypeCtrl,
	 * to match p_transaction_type.
	 */
	void refresh_for_transaction_type
	(	transaction_type::TransactionType p_transaction_type
	);

	void notify_decimal_ctrl_focus_kill();

private:
	void on_ok_button_click(wxCommandEvent& event);
	void on_recurring_transaction_button_click(wxCommandEvent& event);
	void on_cancel_button_click(wxCommandEvent& event);

	void reset_entry_ctrl_amounts();

	void post_journal();
	bool is_balanced() const;
	jewel::Decimal primary_amount() const;

	int m_max_entry_row_id;

	wxGridBagSizer* m_top_sizer;

	TransactionTypeCtrl* m_transaction_type_ctrl;

	EntryCtrl* m_source_entry_ctrl;
	EntryCtrl* m_destination_entry_ctrl;

	DecimalTextCtrl* m_primary_amount_ctrl;
	DateCtrl* m_date_ctrl;

	wxButton* m_cancel_button;
	wxButton* m_recurring_transaction_button;
	wxButton* m_ok_button;

	static unsigned int const s_date_ctrl_id =
		wxID_HIGHEST + 1;
	static unsigned int const s_primary_amount_ctrl_id =
		s_date_ctrl_id + 1;
	static unsigned int const s_recurring_transaction_button_id =
		s_primary_amount_ctrl_id + 1;
	static unsigned int const s_transaction_type_ctrl_id =
		s_recurring_transaction_button_id + 1;
	static unsigned int const s_min_entry_row_id =
		s_transaction_type_ctrl_id + 1;

	PhatbooksDatabaseConnection& m_database_connection;

	DECLARE_EVENT_TABLE()

};  // class TransactionCtrl

}  // namespace gui
}  // namespace phatbooks

#endif  // GUARD_transaction_ctrl_hpp
<commit_msg>TODO re. split transactions not being posted properly.<commit_after>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

#ifndef GUARD_transaction_ctrl_hpp
#define GUARD_transaction_ctrl_hpp

#include "account.hpp"
#include "decimal_text_ctrl.hpp"
#include "transaction_type_ctrl.hpp"
#include <jewel/on_windows.hpp>
#include <wx/button.h>
#include <wx/event.h>
#include <wx/panel.h>
#include <wx/gbsizer.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>

namespace phatbooks
{

// Begin forward declarations

class PhatbooksDatabaseConnection;

namespace gui
{

class AccountCtrl;
class DateCtrl;
class EntryCtrl;
class TopPanel;

// End forward declarations

/**
 * Dialog in which user creates a new transaction (i.e. Journal).
 *
 * @todo Ensure Journal balances.
 *
 * @todo Provide option to save as Draft, Recurring or etc. etc..
 *
 * @todo When the update the TopPanel after posting or cancelling Journal
 * from TransactionCtrl, there is flicker. This is because we are redrawing
 * the entire TopPanel from scratch. We could probably get rid of the flicker
 * by only redrawing the parts we need.
 *
 * @todo Ensure this can handle situation where insufficient default
 * Accounts are available.
 *
 * @todo Handle case where Journal doesn't balance - or else structure
 * things so that this is impossible.
 *
 * @todo HIGH PRIORITY. Split transactions are not being posted properly.
 * Entire amount is getting posted to the 0th Entry in the EntryCtrl.
 */
class TransactionCtrl: public wxPanel
{
public:

	/**
	 * All Accounts in p_accounts should be associated with the same
	 * PhatbooksDatabaseConnection.
	 *
	 * @param p_parent parent panel
	 *
	 * @param p_balance_sheet_accounts a sequence of Accounts
	 * all of which must be balance sheet Accounts (i.e. of
	 * account_super_type::balance_sheet). May be empty providing
	 * p_pl_accounts has at least 2 elements.
	 *
	 * @param p_pl_accounts a sequence of Accounts all of which
	 * must be P&L Accounts (i.e. of account_super_type::pl). May be empty
	 * providing p_balance_sheet_accounts has at least 2 elements.
	 *
	 * @param p_database_connection database connection. Must be the same
	 * one that the Accounts in p_balance_sheet_accounts and
	 * p_pl_accounts are associated with.
	 */
	TransactionCtrl
	(	TopPanel* p_parent,
		std::vector<Account> const& p_balance_sheet_accounts,
		std::vector<Account> const& p_pl_accounts,
		PhatbooksDatabaseConnection& p_database_connection
	);

	/**
	 * Refresh the selections available in the AccountCtrls in the
	 * TransactionCtrl, and the selection in the TransactionTypeCtrl,
	 * to match p_transaction_type.
	 */
	void refresh_for_transaction_type
	(	transaction_type::TransactionType p_transaction_type
	);

	void notify_decimal_ctrl_focus_kill();

private:
	void on_ok_button_click(wxCommandEvent& event);
	void on_recurring_transaction_button_click(wxCommandEvent& event);
	void on_cancel_button_click(wxCommandEvent& event);

	void reset_entry_ctrl_amounts();

	void post_journal();
	bool is_balanced() const;
	jewel::Decimal primary_amount() const;

	int m_max_entry_row_id;

	wxGridBagSizer* m_top_sizer;

	TransactionTypeCtrl* m_transaction_type_ctrl;

	EntryCtrl* m_source_entry_ctrl;
	EntryCtrl* m_destination_entry_ctrl;

	DecimalTextCtrl* m_primary_amount_ctrl;
	DateCtrl* m_date_ctrl;

	wxButton* m_cancel_button;
	wxButton* m_recurring_transaction_button;
	wxButton* m_ok_button;

	static unsigned int const s_date_ctrl_id =
		wxID_HIGHEST + 1;
	static unsigned int const s_primary_amount_ctrl_id =
		s_date_ctrl_id + 1;
	static unsigned int const s_recurring_transaction_button_id =
		s_primary_amount_ctrl_id + 1;
	static unsigned int const s_transaction_type_ctrl_id =
		s_recurring_transaction_button_id + 1;
	static unsigned int const s_min_entry_row_id =
		s_transaction_type_ctrl_id + 1;

	PhatbooksDatabaseConnection& m_database_connection;

	DECLARE_EVENT_TABLE()

};  // class TransactionCtrl

}  // namespace gui
}  // namespace phatbooks

#endif  // GUARD_transaction_ctrl_hpp
<|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/geolocation/chrome_geolocation_permission_context.h"

#include <functional>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/view_type_utils.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"

using WebKit::WebSecurityOrigin;
using content::BrowserThread;
using content::WebContents;

// GeolocationPermissionContext -----------------------------------------------

ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext(
    Profile* profile)
    : profile_(profile),
      ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_(
         new GeolocationInfoBarQueueController(
             base::Bind(
                 &ChromeGeolocationPermissionContext::NotifyPermissionSet,
                 this),
             profile))) {
}

void ChromeGeolocationPermissionContext::RegisterUserPrefs(
    PrefService *user_prefs) {
#if defined(OS_ANDROID)
  user_prefs->RegisterBooleanPref(prefs::kGeolocationEnabled, true,
                                  PrefService::UNSYNCABLE_PREF);
#endif
}

ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() {
}

void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
    int render_process_id, int render_view_id, int bridge_id,
    const GURL& requesting_frame, base::Callback<void(bool)> callback) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(
            &ChromeGeolocationPermissionContext::RequestGeolocationPermission,
            this, render_process_id, render_view_id, bridge_id,
            requesting_frame, callback));
    return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

#if defined(OS_ANDROID)
  // Check to see if the feature in its entirety has been disabled.
  // This must happen before other services (e.g. tabs, extensions)
  // get an opportunity to allow the geolocation request.
  if (!profile_->GetPrefs()->GetBoolean(prefs::kGeolocationEnabled)) {
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
    return;
  }
#endif

  ExtensionService* extension_service = profile_->GetExtensionService();
  if (extension_service) {
    const extensions::Extension* extension =
        extension_service->extensions()->GetExtensionOrAppByURL(
            ExtensionURLInfo(
                WebSecurityOrigin::createFromString(
                    UTF8ToUTF16(requesting_frame.spec())),
                requesting_frame));
    if (extension &&
        extension->HasAPIPermission(extensions::APIPermission::kGeolocation)) {
      // Make sure the extension is in the calling process.
      if (extension_service->process_map()->Contains(
              extension->id(), render_process_id)) {
        NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                            requesting_frame, callback, true);
        return;
      }
    }
  }

  WebContents* web_contents =
      tab_util::GetWebContentsByID(render_process_id, render_view_id);
  if (chrome::GetViewType(web_contents) != chrome::VIEW_TYPE_TAB_CONTENTS) {
    // The tab may have gone away, or the request may not be from a tab at all.
    // TODO(mpcomplete): the request could be from a background page or
    // extension popup (tab_contents will have a different ViewType). But why do
    // we care? Shouldn't we still put an infobar up in the current tab?
    LOG(WARNING) << "Attempt to use geolocation tabless renderer: "
                 << render_process_id << "," << render_view_id << ","
                 << bridge_id << " (can't prompt user without a visible tab)";
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
    return;
  }

  GURL embedder = web_contents->GetURL();
  if (!requesting_frame.is_valid() || !embedder.is_valid()) {
    LOG(WARNING) << "Attempt to use geolocation from an invalid URL: "
                 << requesting_frame << "," << embedder
                 << " (geolocation is not supported in popups)";
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
    return;
  }

  ContentSetting content_setting =
     profile_->GetHostContentSettingsMap()->GetContentSetting(
          requesting_frame,
          embedder,
          CONTENT_SETTINGS_TYPE_GEOLOCATION,
          std::string());
  if (content_setting == CONTENT_SETTING_BLOCK) {
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
  } else if (content_setting == CONTENT_SETTING_ALLOW) {
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, true);
  } else {  // setting == ask. Prompt the user.
    geolocation_infobar_queue_controller_->CreateInfoBarRequest(
        render_process_id, render_view_id, bridge_id, requesting_frame,
        embedder, callback);
  }
}

void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest(
    int render_process_id,
    int render_view_id,
    int bridge_id,
    const GURL& requesting_frame) {
  CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id);
}

void ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest(
    int render_process_id,
    int render_view_id,
    int bridge_id) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(
            &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest,
            this, render_process_id, render_view_id, bridge_id));
     return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  geolocation_infobar_queue_controller_->CancelInfoBarRequest(
      render_process_id,
      render_view_id,
      bridge_id);
}

void ChromeGeolocationPermissionContext::NotifyPermissionSet(
    int render_process_id,
    int render_view_id,
    int bridge_id,
    const GURL& requesting_frame,
    base::Callback<void(bool)> callback,
    bool allowed) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // WebContents may have gone away (or not exists for extension).
  TabSpecificContentSettings* content_settings =
      TabSpecificContentSettings::Get(render_process_id, render_view_id);
  if (content_settings) {
    content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(),
                                                 allowed);
  }

  callback.Run(allowed);
}
<commit_msg>Don't retain reference to ChromeGeolocationPermissionContext<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/geolocation/chrome_geolocation_permission_context.h"

#include <functional>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/geolocation/geolocation_infobar_queue_controller.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/view_type_utils.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"

using WebKit::WebSecurityOrigin;
using content::BrowserThread;
using content::WebContents;

// GeolocationPermissionContext -----------------------------------------------

ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext(
    Profile* profile)
    : profile_(profile),
      ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_(
         new GeolocationInfoBarQueueController(
             base::Bind(
                 &ChromeGeolocationPermissionContext::NotifyPermissionSet,
                 base::Unretained(this)),
             profile))) {
}

void ChromeGeolocationPermissionContext::RegisterUserPrefs(
    PrefService *user_prefs) {
#if defined(OS_ANDROID)
  user_prefs->RegisterBooleanPref(prefs::kGeolocationEnabled, true,
                                  PrefService::UNSYNCABLE_PREF);
#endif
}

ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() {
}

void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
    int render_process_id, int render_view_id, int bridge_id,
    const GURL& requesting_frame, base::Callback<void(bool)> callback) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(
            &ChromeGeolocationPermissionContext::RequestGeolocationPermission,
            this, render_process_id, render_view_id, bridge_id,
            requesting_frame, callback));
    return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

#if defined(OS_ANDROID)
  // Check to see if the feature in its entirety has been disabled.
  // This must happen before other services (e.g. tabs, extensions)
  // get an opportunity to allow the geolocation request.
  if (!profile_->GetPrefs()->GetBoolean(prefs::kGeolocationEnabled)) {
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
    return;
  }
#endif

  ExtensionService* extension_service = profile_->GetExtensionService();
  if (extension_service) {
    const extensions::Extension* extension =
        extension_service->extensions()->GetExtensionOrAppByURL(
            ExtensionURLInfo(
                WebSecurityOrigin::createFromString(
                    UTF8ToUTF16(requesting_frame.spec())),
                requesting_frame));
    if (extension &&
        extension->HasAPIPermission(extensions::APIPermission::kGeolocation)) {
      // Make sure the extension is in the calling process.
      if (extension_service->process_map()->Contains(
              extension->id(), render_process_id)) {
        NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                            requesting_frame, callback, true);
        return;
      }
    }
  }

  WebContents* web_contents =
      tab_util::GetWebContentsByID(render_process_id, render_view_id);
  if (chrome::GetViewType(web_contents) != chrome::VIEW_TYPE_TAB_CONTENTS) {
    // The tab may have gone away, or the request may not be from a tab at all.
    // TODO(mpcomplete): the request could be from a background page or
    // extension popup (tab_contents will have a different ViewType). But why do
    // we care? Shouldn't we still put an infobar up in the current tab?
    LOG(WARNING) << "Attempt to use geolocation tabless renderer: "
                 << render_process_id << "," << render_view_id << ","
                 << bridge_id << " (can't prompt user without a visible tab)";
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
    return;
  }

  GURL embedder = web_contents->GetURL();
  if (!requesting_frame.is_valid() || !embedder.is_valid()) {
    LOG(WARNING) << "Attempt to use geolocation from an invalid URL: "
                 << requesting_frame << "," << embedder
                 << " (geolocation is not supported in popups)";
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
    return;
  }

  ContentSetting content_setting =
     profile_->GetHostContentSettingsMap()->GetContentSetting(
          requesting_frame,
          embedder,
          CONTENT_SETTINGS_TYPE_GEOLOCATION,
          std::string());
  if (content_setting == CONTENT_SETTING_BLOCK) {
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, false);
  } else if (content_setting == CONTENT_SETTING_ALLOW) {
    NotifyPermissionSet(render_process_id, render_view_id, bridge_id,
                        requesting_frame, callback, true);
  } else {  // setting == ask. Prompt the user.
    geolocation_infobar_queue_controller_->CreateInfoBarRequest(
        render_process_id, render_view_id, bridge_id, requesting_frame,
        embedder, callback);
  }
}

void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest(
    int render_process_id,
    int render_view_id,
    int bridge_id,
    const GURL& requesting_frame) {
  CancelPendingInfoBarRequest(render_process_id, render_view_id, bridge_id);
}

void ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest(
    int render_process_id,
    int render_view_id,
    int bridge_id) {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        base::Bind(
            &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest,
            this, render_process_id, render_view_id, bridge_id));
     return;
  }
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  geolocation_infobar_queue_controller_->CancelInfoBarRequest(
      render_process_id,
      render_view_id,
      bridge_id);
}

void ChromeGeolocationPermissionContext::NotifyPermissionSet(
    int render_process_id,
    int render_view_id,
    int bridge_id,
    const GURL& requesting_frame,
    base::Callback<void(bool)> callback,
    bool allowed) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  // WebContents may have gone away (or not exists for extension).
  TabSpecificContentSettings* content_settings =
      TabSpecificContentSettings::Get(render_process_id, render_view_id);
  if (content_settings) {
    content_settings->OnGeolocationPermissionSet(requesting_frame.GetOrigin(),
                                                 allowed);
  }

  callback.Run(allowed);
}
<|endoftext|>


<commit_before><commit_msg>Improved scons tests<commit_after><|endoftext|>


<commit_before><commit_msg>[BP] Use C++11 primitives for thread creation and synchronization<commit_after><|endoftext|>


<commit_before><commit_msg>Add comment regarding permissible values for XML_PLATFORM_NEW_BLOCK_ALIGNMENT.<commit_after><|endoftext|>


<commit_before><commit_msg>added a TODO<commit_after><|endoftext|>


<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "bstprofiler.hh"
#include <string.h>
/* --- thread view --- */
enum {
  TCOL_NAME,
  TCOL_TID,
  TCOL_PROC,
  TCOL_PRIO,
  TCOL_PERC,
  TCOL_UTIME,
  TCOL_STIME,
  N_TCOLS
};
/* --- variables --- */
static GtkWidget     *profiler_dialog = NULL;
static GxkRadget     *profiler = NULL;
static guint          timer_id = 0;
static guint          n_thread_infos = 0;
static BseThreadInfo *thread_infos = NULL;
/* --- funtions --- */
#if 0
static gchar
char_state_from_thread_state (BseThreadState thread_state)
{
  switch (thread_state)
    {
    default:
    case BSE_THREAD_STATE_UNKNOWN:      return SFI_THREAD_UNKNOWN;
    case BSE_THREAD_STATE_RUNNING:      return SFI_THREAD_RUNNING;
    case BSE_THREAD_STATE_SLEEPING:     return SFI_THREAD_SLEEPING;
    case BSE_THREAD_STATE_DISKWAIT:     return SFI_THREAD_DISKWAIT;
    case BSE_THREAD_STATE_TRACED:       return SFI_THREAD_TRACED;
    case BSE_THREAD_STATE_PAGING:       return SFI_THREAD_PAGING;
    case BSE_THREAD_STATE_ZOMBIE:       return SFI_THREAD_ZOMBIE;
    case BSE_THREAD_STATE_DEAD:         return SFI_THREAD_DEAD;
    }
}
#endif
static BseThreadState
thread_state_from_char_state (gchar thread_state)
{
  switch (thread_state)
    {
    default:
    case SFI_THREAD_UNKNOWN:    return BSE_THREAD_STATE_UNKNOWN;
    case SFI_THREAD_RUNNING:    return BSE_THREAD_STATE_RUNNING;
    case SFI_THREAD_SLEEPING:   return BSE_THREAD_STATE_SLEEPING;
    case SFI_THREAD_DISKWAIT:   return BSE_THREAD_STATE_DISKWAIT;
    case SFI_THREAD_TRACED:     return BSE_THREAD_STATE_TRACED;
    case SFI_THREAD_PAGING:     return BSE_THREAD_STATE_PAGING;
    case SFI_THREAD_ZOMBIE:     return BSE_THREAD_STATE_ZOMBIE;
    case SFI_THREAD_DEAD:       return BSE_THREAD_STATE_DEAD;
    }
}
static void
thread_info_cell_fill_value (GtkWidget *profiler,
                             guint      column,
                             guint      row,
                             GValue    *value)
{
  BseThreadInfo *info = thread_infos + row;
  switch (column)
    {
    case TCOL_NAME:
      sfi_value_take_string (value, g_strdup_printf ("%s", info->name));
      break;
    case TCOL_PROC:
      sfi_value_take_string (value, info->processor ? g_strdup_printf ("%d", info->processor) : g_strdup (""));
      break;
    case TCOL_TID:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%u", info->thread_id) : g_strdup (""));
      break;
    case TCOL_PRIO:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%d", info->priority) : g_strdup (""));
      break;
    case TCOL_PERC:
      sfi_value_take_string (value, g_strdup_printf ("%5.2f%%", (info->utime + info->stime) * 0.0001));
      break;
    case TCOL_UTIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->utime * 0.001));
      break;
    case TCOL_STIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->stime * 0.001));
      break;
    }
}
static void
update_infos (GSList         *slist,
              GxkListWrapper *lw)
{
  guint i, n = g_slist_length (slist) + 1;
  while (n_thread_infos > n)
    {
      BseThreadInfo *info = thread_infos + --n_thread_infos;
      g_free (info->name);
      gxk_list_wrapper_notify_delete (lw, n_thread_infos);
    }
  if (n > n_thread_infos)
    {
      thread_infos = g_renew (BseThreadInfo, thread_infos, n);
      guint delta = n - n_thread_infos;
      memset (thread_infos + n_thread_infos, 0, sizeof (thread_infos[0]) * delta);
      n_thread_infos = n;
      gxk_list_wrapper_notify_append (lw, delta);
    }
  BseThreadInfo *totals = thread_infos + n - 1;
  gboolean totals_changed = !totals->name;
  totals->utime = 0;
  totals->stime = 0;
  totals->priority = G_MAXINT;
  for (i = 0; i < n - 1; i++)
    {
      BseThreadInfo *oinfo = thread_infos + i;
      BseThreadInfo *ninfo = (BseThreadInfo*) slist->data;
      slist = slist->next;
      if (!oinfo->name || strcmp (oinfo->name, ninfo->name) ||
          oinfo->thread_id != ninfo->thread_id ||
          oinfo->state != ninfo->state ||
          oinfo->priority != ninfo->priority ||
          oinfo->processor != ninfo->processor ||
          oinfo->utime != ninfo->utime ||
          oinfo->stime != ninfo->stime)
        {
          g_free (oinfo->name);
          oinfo->name = g_strdup (ninfo->name);
          oinfo->thread_id = ninfo->thread_id;
          oinfo->state = ninfo->state;
          oinfo->priority = ninfo->priority;
          oinfo->processor = ninfo->processor;
          oinfo->utime = ninfo->utime;
          oinfo->stime = ninfo->stime;
          gxk_list_wrapper_notify_change (lw, i);
          totals_changed = TRUE;
        }
      totals->utime += oinfo->utime;
      totals->stime += oinfo->stime;
      totals->priority = MIN (oinfo->priority, totals->priority);
    }
  if (totals_changed)
    {
      g_free (totals->name);
      totals->name = g_strdup (_("Totals"));
      totals->state = BSE_THREAD_STATE_RUNNING;
      totals->processor = 0;
      gxk_list_wrapper_notify_change (lw, n - 1);
    }
}
static void
profiler_update (void)
{
  GxkListWrapper *lwrapper = (GxkListWrapper*) g_object_get_data ((GObject*) profiler_dialog, "list-wrapper");
  BseThreadTotals *tt = bse_collect_thread_totals ();
  sfi_thread_sleep (0); /* update accounting for self */
  BirnetThreadInfo *si = sfi_thread_info_collect (sfi_thread_self());
  BseThreadInfo bi = { 0, };
  GSList *slist = NULL;
  guint i;
  bi.name = si->name;
  bi.thread_id = si->thread_id;
  bi.state = thread_state_from_char_state (si->state);
  bi.priority = si->priority;
  bi.processor = si->processor;
  bi.utime = si->utime;
  bi.stime = si->stime;
  bi.cutime = si->cutime;
  bi.cstime = si->cstime;
  for (i = 0; i < tt->synthesis->n_thread_infos; i++)
    slist = g_slist_prepend (slist, tt->synthesis->thread_infos[i]);
  if (tt->sequencer)
    slist = g_slist_prepend (slist, tt->sequencer);
  if (tt->main)
    slist = g_slist_prepend (slist, tt->main);
  slist = g_slist_prepend (slist, &bi);
  update_infos (slist, lwrapper);
  g_slist_free (slist);
  sfi_thread_info_free (si);
}
static gboolean
profiler_timer (gpointer data)
{
  gboolean visible;
  GDK_THREADS_ENTER ();
  visible = profiler_dialog && GTK_WIDGET_VISIBLE (profiler_dialog);
  if (visible)
    profiler_update ();
  else
    timer_id = 0;
  GDK_THREADS_LEAVE ();
  return visible;
}
GtkWidget*
bst_profiler_window_get (void)
{
  if (!profiler)
    {
      profiler = gxk_radget_create ("beast", "profiler", NULL);
      profiler_dialog = (GtkWidget*) gxk_dialog_new (&profiler, NULL,
                                                     GXK_DIALOG_HIDE_ON_DELETE,
                                                     _("Profiler"),
                                                     (GtkWidget*) profiler);
      GxkListWrapper *lwrapper = gxk_list_wrapper_new (N_TCOLS,
                                                       G_TYPE_STRING,   /* TCOL_NAME */
                                                       G_TYPE_STRING,   /* TCOL_TID */
                                                       G_TYPE_STRING,   /* TCOL_PERC */
                                                       G_TYPE_STRING,   /* TCOL_UTIME */
                                                       G_TYPE_STRING,   /* TCOL_STIME */
                                                       G_TYPE_STRING,   /* TCOL_PRIO */
                                                       G_TYPE_STRING    /* TCOL_PROC */
                                                       );
      g_signal_connect_object (lwrapper, "fill-value",
                               G_CALLBACK (thread_info_cell_fill_value),
                               profiler, G_CONNECT_SWAPPED);
      GtkTreeModel *smodel = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (lwrapper));
      g_object_unref (lwrapper);
      GtkTreeView *tview = (GtkTreeView*) gxk_radget_find (profiler, "tree-view");
      gtk_tree_view_set_model (tview, smodel);
      GtkTreeSelection *tsel = gtk_tree_view_get_selection (tview);
      gtk_tree_selection_set_mode (tsel, GTK_SELECTION_NONE);
      g_object_unref (smodel);
      gxk_tree_view_add_text_column (tview, TCOL_NAME, "SAG", 0.0, _("Thread Name"), NULL, NULL, NULL, GConnectFlags (0));
      if (BST_DVL_HINTS)
        gxk_tree_view_add_text_column (tview, TCOL_TID, "SA", 0.5, _("TID"), _("Thread ID (on some systems the process ID)"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_PERC, "SAG", 1.0, _("CPU%"), _("Percentage of CPU usage"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_UTIME, "SAG", 1.0, _("UTime"), _("Average number of milliseconds per second of user CPU time used by thread"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_STIME, "SAG", 1.0, _("STime"), _("Average number of milliseconds per second of system CPU time used by thread"), NULL, NULL, GConnectFlags (0));
      /*
        gxk_tree_view_add_text_column (tview, TCOL_STATE, "F", 0.5, _("S"),
        _("Thread State:\n"
        "'?' - thread state is unknown\n"
        "'R' - thread is running\n"
        "'S' - thread is sleeping\n"
        "'D' - thread waits on disk\n"
        "'T' - thread is traced\n"
        "'W' - thread is swapping memory\n"
        "'Z' - thread died unexpectedly\n"
        "'X' - thread exited"),
        NULL, NULL, 0);
      */
      gxk_tree_view_add_text_column (tview, TCOL_PRIO, "AG", 0.5, _("Nice"), _("Thread priority from -20 (high) to +19 (low)"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_PROC, "A", 0.5, _("CPU#"), _("CPU the thread is currently running on"), NULL, NULL, GConnectFlags (0));
      g_object_set_data ((GObject*) profiler_dialog, "list-wrapper", lwrapper);
      profiler_update ();
    }
  if (!timer_id)
    timer_id = g_timeout_add (500, profiler_timer, NULL);
  return profiler_dialog;
}
<commit_msg>BST: port thread profiling to Rapicorn::TaskStatus<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "bstprofiler.hh"
#include <string.h>
/* --- thread view --- */
enum {
  TCOL_NAME,
  TCOL_TID,
  TCOL_PROC,
  TCOL_PRIO,
  TCOL_PERC,
  TCOL_UTIME,
  TCOL_STIME,
  N_TCOLS
};
/* --- variables --- */
static GtkWidget     *profiler_dialog = NULL;
static GxkRadget     *profiler = NULL;
static guint          timer_id = 0;
static guint          n_thread_infos = 0;
static BseThreadInfo *thread_infos = NULL;
/* --- funtions --- */
#if 0
static gchar
char_state_from_thread_state (BseThreadState thread_state)
{
  switch (thread_state)
    {
    default:
    case BSE_THREAD_STATE_UNKNOWN:      return SFI_THREAD_UNKNOWN;
    case BSE_THREAD_STATE_RUNNING:      return SFI_THREAD_RUNNING;
    case BSE_THREAD_STATE_SLEEPING:     return SFI_THREAD_SLEEPING;
    case BSE_THREAD_STATE_DISKWAIT:     return SFI_THREAD_DISKWAIT;
    case BSE_THREAD_STATE_TRACED:       return SFI_THREAD_TRACED;
    case BSE_THREAD_STATE_PAGING:       return SFI_THREAD_PAGING;
    case BSE_THREAD_STATE_ZOMBIE:       return SFI_THREAD_ZOMBIE;
    case BSE_THREAD_STATE_DEAD:         return SFI_THREAD_DEAD;
    }
}
#endif

static void
thread_info_cell_fill_value (GtkWidget *profiler,
                             guint      column,
                             guint      row,
                             GValue    *value)
{
  BseThreadInfo *info = thread_infos + row;
  switch (column)
    {
    case TCOL_NAME:
      sfi_value_take_string (value, g_strdup_printf ("%s", info->name));
      break;
    case TCOL_PROC:
      sfi_value_take_string (value, info->processor ? g_strdup_printf ("%d", info->processor) : g_strdup (""));
      break;
    case TCOL_TID:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%u", info->thread_id) : g_strdup (""));
      break;
    case TCOL_PRIO:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%d", info->priority) : g_strdup (""));
      break;
    case TCOL_PERC:
      sfi_value_take_string (value, g_strdup_printf ("%5.2f%%", (info->utime + info->stime) * 0.0001));
      break;
    case TCOL_UTIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->utime * 0.001));
      break;
    case TCOL_STIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->stime * 0.001));
      break;
    }
}

static void
update_infos (GSList         *slist,
              GxkListWrapper *lw)
{
  guint i, n = g_slist_length (slist) + 1;
  while (n_thread_infos > n)
    {
      BseThreadInfo *info = thread_infos + --n_thread_infos;
      g_free (info->name);
      gxk_list_wrapper_notify_delete (lw, n_thread_infos);
    }
  if (n > n_thread_infos)
    {
      thread_infos = g_renew (BseThreadInfo, thread_infos, n);
      guint delta = n - n_thread_infos;
      memset (thread_infos + n_thread_infos, 0, sizeof (thread_infos[0]) * delta);
      n_thread_infos = n;
      gxk_list_wrapper_notify_append (lw, delta);
    }
  BseThreadInfo *totals = thread_infos + n - 1;
  gboolean totals_changed = !totals->name;
  totals->utime = 0;
  totals->stime = 0;
  totals->priority = G_MAXINT;
  for (i = 0; i < n - 1; i++)
    {
      BseThreadInfo *oinfo = thread_infos + i;
      BseThreadInfo *ninfo = (BseThreadInfo*) slist->data;
      slist = slist->next;
      if (!oinfo->name || strcmp (oinfo->name, ninfo->name) ||
          oinfo->thread_id != ninfo->thread_id ||
          oinfo->state != ninfo->state ||
          oinfo->priority != ninfo->priority ||
          oinfo->processor != ninfo->processor ||
          oinfo->utime != ninfo->utime ||
          oinfo->stime != ninfo->stime)
        {
          g_free (oinfo->name);
          oinfo->name = g_strdup (ninfo->name);
          oinfo->thread_id = ninfo->thread_id;
          oinfo->state = ninfo->state;
          oinfo->priority = ninfo->priority;
          oinfo->processor = ninfo->processor;
          oinfo->utime = ninfo->utime;
          oinfo->stime = ninfo->stime;
          gxk_list_wrapper_notify_change (lw, i);
          totals_changed = TRUE;
        }
      totals->utime += oinfo->utime;
      totals->stime += oinfo->stime;
      totals->priority = MIN (oinfo->priority, totals->priority);
    }
  if (totals_changed)
    {
      g_free (totals->name);
      totals->name = g_strdup (_("Totals"));
      totals->state = BSE_THREAD_STATE_RUNNING;
      totals->processor = 0;
      gxk_list_wrapper_notify_change (lw, n - 1);
    }
}

static BseThreadState
convert_thread_state (Rapicorn::TaskStatus::State ts)
{
  switch (ts)
    {
    default:
    case Rapicorn::TaskStatus::UNKNOWN:     return BSE_THREAD_STATE_UNKNOWN;
    case Rapicorn::TaskStatus::RUNNING:     return BSE_THREAD_STATE_RUNNING;
    case Rapicorn::TaskStatus::SLEEPING:    return BSE_THREAD_STATE_SLEEPING;
    case Rapicorn::TaskStatus::DISKWAIT:    return BSE_THREAD_STATE_DISKWAIT;
    case Rapicorn::TaskStatus::STOPPED:     return BSE_THREAD_STATE_TRACED;     // T - BSD:stopped, Linux:traced
    case Rapicorn::TaskStatus::PAGING:      return BSE_THREAD_STATE_PAGING;
    case Rapicorn::TaskStatus::ZOMBIE:      return BSE_THREAD_STATE_ZOMBIE;
    case Rapicorn::TaskStatus::DEBUG:       return BSE_THREAD_STATE_DEAD;       // X - BSD:debug, Linux:dead
    }
}

static void
profiler_update (void)
{
  static Rapicorn::TaskStatus *gui_task_status = NULL;
  GxkListWrapper *lwrapper = (GxkListWrapper*) g_object_get_data ((GObject*) profiler_dialog, "list-wrapper");
  BseThreadTotals *tt = bse_collect_thread_totals ();
  if (!gui_task_status)
    {
      gui_task_status = new Rapicorn::TaskStatus (Rapicorn::ThisThread::process_pid(), Rapicorn::ThisThread::thread_pid());
      gui_task_status->name = "Beast GUI";
    }
  gui_task_status->update();
  BseThreadInfo bi = { 0, };
  bi.name = const_cast<char*> (gui_task_status->name.c_str());
  bi.thread_id = gui_task_status->task_id;
  bi.state = convert_thread_state (gui_task_status->state);
  bi.priority = gui_task_status->priority;
  bi.processor = gui_task_status->processor;
  bi.utime = gui_task_status->utime;
  bi.stime = gui_task_status->stime;
  bi.cutime = gui_task_status->cutime;
  bi.cstime = gui_task_status->cstime;
  GSList *slist = NULL;
  for (uint i = 0; i < tt->synthesis->n_thread_infos; i++)
    slist = g_slist_prepend (slist, tt->synthesis->thread_infos[i]);
  if (tt->sequencer)
    slist = g_slist_prepend (slist, tt->sequencer);
  if (tt->main)
    slist = g_slist_prepend (slist, tt->main);
  slist = g_slist_prepend (slist, &bi);
  update_infos (slist, lwrapper);
  g_slist_free (slist);
}

static gboolean
profiler_timer (gpointer data)
{
  gboolean visible;
  GDK_THREADS_ENTER ();
  visible = profiler_dialog && GTK_WIDGET_VISIBLE (profiler_dialog);
  if (visible)
    profiler_update ();
  else
    timer_id = 0;
  GDK_THREADS_LEAVE ();
  return visible;
}
GtkWidget*
bst_profiler_window_get (void)
{
  if (!profiler)
    {
      profiler = gxk_radget_create ("beast", "profiler", NULL);
      profiler_dialog = (GtkWidget*) gxk_dialog_new (&profiler, NULL,
                                                     GXK_DIALOG_HIDE_ON_DELETE,
                                                     _("Profiler"),
                                                     (GtkWidget*) profiler);
      GxkListWrapper *lwrapper = gxk_list_wrapper_new (N_TCOLS,
                                                       G_TYPE_STRING,   /* TCOL_NAME */
                                                       G_TYPE_STRING,   /* TCOL_TID */
                                                       G_TYPE_STRING,   /* TCOL_PERC */
                                                       G_TYPE_STRING,   /* TCOL_UTIME */
                                                       G_TYPE_STRING,   /* TCOL_STIME */
                                                       G_TYPE_STRING,   /* TCOL_PRIO */
                                                       G_TYPE_STRING    /* TCOL_PROC */
                                                       );
      g_signal_connect_object (lwrapper, "fill-value",
                               G_CALLBACK (thread_info_cell_fill_value),
                               profiler, G_CONNECT_SWAPPED);
      GtkTreeModel *smodel = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (lwrapper));
      g_object_unref (lwrapper);
      GtkTreeView *tview = (GtkTreeView*) gxk_radget_find (profiler, "tree-view");
      gtk_tree_view_set_model (tview, smodel);
      GtkTreeSelection *tsel = gtk_tree_view_get_selection (tview);
      gtk_tree_selection_set_mode (tsel, GTK_SELECTION_NONE);
      g_object_unref (smodel);
      gxk_tree_view_add_text_column (tview, TCOL_NAME, "SAG", 0.0, _("Thread Name"), NULL, NULL, NULL, GConnectFlags (0));
      if (BST_DVL_HINTS)
        gxk_tree_view_add_text_column (tview, TCOL_TID, "SA", 0.5, _("TID"), _("Thread ID (on some systems the process ID)"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_PERC, "SAG", 1.0, _("CPU%"), _("Percentage of CPU usage"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_UTIME, "SAG", 1.0, _("UTime"), _("Average number of milliseconds per second of user CPU time used by thread"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_STIME, "SAG", 1.0, _("STime"), _("Average number of milliseconds per second of system CPU time used by thread"), NULL, NULL, GConnectFlags (0));
      /*
        gxk_tree_view_add_text_column (tview, TCOL_STATE, "F", 0.5, _("S"),
        _("Thread State:\n"
        "'?' - thread state is unknown\n"
        "'R' - thread is running\n"
        "'S' - thread is sleeping\n"
        "'D' - thread waits on disk\n"
        "'T' - thread is traced\n"
        "'W' - thread is swapping memory\n"
        "'Z' - thread died unexpectedly\n"
        "'X' - thread exited"),
        NULL, NULL, 0);
      */
      gxk_tree_view_add_text_column (tview, TCOL_PRIO, "AG", 0.5, _("Nice"), _("Thread priority from -20 (high) to +19 (low)"), NULL, NULL, GConnectFlags (0));
      gxk_tree_view_add_text_column (tview, TCOL_PROC, "A", 0.5, _("CPU#"), _("CPU the thread is currently running on"), NULL, NULL, GConnectFlags (0));
      g_object_set_data ((GObject*) profiler_dialog, "list-wrapper", lwrapper);
      profiler_update ();
    }
  if (!timer_id)
    timer_id = g_timeout_add (500, profiler_timer, NULL);
  return profiler_dialog;
}
<|endoftext|>


<commit_before>// Check the value profiling instrinsics emitted by instrumentation.

// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -mllvm -enable-value-profiling -fexceptions -target %itanium_abi_triple | FileCheck %s

void (*foo) (void);

int main(int argc, const char *argv[]) {
// CHECK:  [[REG1:%[0-9]+]] = load void ()*, void ()** @foo
// CHECK-NEXT:  [[REG2:%[0-9]+]] = ptrtoint void ()* [[REG1]] to i64
// CHECK-NEXT:  call void @__llvm_profile_instrument_target(i64 [[REG2]], i8* bitcast ({{.*}}* @__profd_main to i8*), i32 0)
// CHECK-NEXT:  invoke void [[REG1]]()
  try {
    foo();
  } catch (int) {}
  return 0;
}

// CHECK: declare void @__llvm_profile_instrument_target(i64, i8*, i32)

<commit_msg>[profile] Fix another use of the driver.<commit_after>// Check the value profiling instrinsics emitted by instrumentation.

// RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument=clang -mllvm -enable-value-profiling -fexceptions -fcxx-exceptions -triple %itanium_abi_triple | FileCheck %s

void (*foo) (void);

int main(int argc, const char *argv[]) {
// CHECK:  [[REG1:%[0-9]+]] = load void ()*, void ()** @foo
// CHECK-NEXT:  [[REG2:%[0-9]+]] = ptrtoint void ()* [[REG1]] to i64
// CHECK-NEXT:  call void @__llvm_profile_instrument_target(i64 [[REG2]], i8* bitcast ({{.*}}* @__profd_main to i8*), i32 0)
// CHECK-NEXT:  invoke void [[REG1]]()
  try {
    foo();
  } catch (int) {}
  return 0;
}

// CHECK: declare void @__llvm_profile_instrument_target(i64, i8*, i32)

<|endoftext|>


<commit_before>#include "Halide.h"
#include <stdio.h>

// The check has to go in the Halide namespace, because get_source_location looks for the first thing outside of it
namespace Halide {
void check(const void *var, const std::string &type,
           const std::string &correct_name,
           const std::string &correct_file, int line) {
    std::string correct_loc = correct_file + ":" + std::to_string(line);
    std::string loc = Halide::Internal::Introspection::get_source_location();
    std::string name = Halide::Internal::Introspection::get_variable_name(var, type);

    if (name != correct_name) {
        printf("Mispredicted name: %s vs %s\n",
               name.c_str(), correct_name.c_str());
        exit(-1);
    }

    if (loc != correct_loc) {
        printf("Mispredicted source location: %s vs %s\n",
               loc.c_str(), correct_loc.c_str());
        exit(-1);
    }
}
}

using Halide::check;

int global_int = 7;

struct SomeStruct {
    int global_struct_a;
    int global_struct_b;
    static float static_float;
    static double static_member_double_array[17];
    static struct SubStruct {
        int a;
    } substruct;
} global_struct;

float SomeStruct::static_float = 3.0f;
double SomeStruct::static_member_double_array[17] = {0};
SomeStruct::SubStruct SomeStruct::substruct = {0};

float global_array[7];

namespace Foo {

int global_int_in_foo = 8;

namespace {
struct Bar {
    typedef int bint;
    bint bar_int;
    Bar(int x) : bar_int(x) {
        check(this, "Foo::{anonymous}::Bar", "b", __FILE__, __LINE__);
        check(&bar_int, "Foo::{anonymous}::Bar::bint", "b.bar_int", __FILE__, __LINE__);
    }
    ~Bar() {
        check(this, "Foo::{anonymous}::Bar", "b", __FILE__, __LINE__);
        check(&bar_int, "Foo::{anonymous}::Bar::bint", "b.bar_int", __FILE__, __LINE__);
    }
    int get() {
        return bar_int * 2;
    }
};

int g(int x) {
    Bar b(x*7);
    return b.get();
}

}

int f(int x) {
    static float static_float_in_f = 0.3f;
    int y = g(x) + g(x-1);
    check(&y, "int", "y", __FILE__, __LINE__);
    check(&static_float_in_f, "float", "static_float_in_f", __FILE__, __LINE__);
    return y - 1;
}

}

typedef float fancy_float;

struct HeapObject {
    float f;
    fancy_float f2;
    int i;
    struct  {
        char c;
        double d;
        int i_array[20];
    } inner;
    HeapObject *ptr;
    struct inner2 {
        int a[5];
    };
    inner2 inner2_array[10];
};

int main(int argc, char **argv) {
    bool result = HalideIntrospectionCanary::test();

    if (result) {
        printf("Halide C++ introspection claims to be working with this build config\n");
    } else {
        printf("Halide C++ introspection doesn't claim to work with this build config. Not continuing.\n");
        return 0;
    }

    printf("Continuing with further tests...\n");

    Foo::f(17);

    // Make sure it works all the way up to main
    int secret_int = 5;
    check(&secret_int, "int", "secret_int", __FILE__, __LINE__);

    // Make sure it rejects heap variables
    int *on_the_heap = new int;
    check(on_the_heap, "int", "", __FILE__, __LINE__);
    delete on_the_heap;

    // .. unless they're members of explicitly registered objects
    HeapObject *obj = new HeapObject;
    static HeapObject *dummy_heap_object_ptr = NULL;
    Halide::Internal::Introspection::register_heap_object(obj, sizeof(HeapObject), &dummy_heap_object_ptr);
    check(&(obj->f), "float", "f", __FILE__, __LINE__);
    check(&(obj->f2), "fancy_float", "f2", __FILE__, __LINE__);
    check(&(obj->f2), "float", "f2", __FILE__, __LINE__);
    check(&(obj->i), "int", "i", __FILE__, __LINE__);
    check(&(obj->inner.c), "char", "inner.c", __FILE__, __LINE__);
    check(&(obj->inner.d), "double", "inner.d", __FILE__, __LINE__);
    check(&(obj->ptr), "HeapObject *", "ptr", __FILE__, __LINE__);
    // TODO:
    check(&(obj->inner.i_array[10]), "int", "inner.i_array[10]", __FILE__, __LINE__);
    check(&(obj->inner2_array[4].a[2]), "int", "inner2_array[4].a[2]", __FILE__, __LINE__);
    check(&(obj->inner.i_array), "int [20]", "inner.i_array", __FILE__, __LINE__);
    Halide::Internal::Introspection::deregister_heap_object(obj, sizeof(HeapObject));
    delete obj;

    // Make sure it works for arrays.
    float an_array[17];
    check(&an_array[5], "float", "an_array[5]", __FILE__, __LINE__);

    // Check what happens with lexical blocks which may reuse stack positions
    {
        int block_a = 3;
        (void)block_a;
        check(&block_a, "int", "block_a", __FILE__, __LINE__);
    }

    {
        int block_b = 3;
        (void)block_b;
        check(&block_b, "int", "block_b", __FILE__, __LINE__);
    }

    {
        int block_c = 3;
        (void)block_c;
        check(&block_c, "int", "block_c", __FILE__, __LINE__);
    }

    // Check we can name globals
    check(&global_int, "int", "global_int", __FILE__, __LINE__);
    check(&Foo::global_int_in_foo, "int", "Foo::global_int_in_foo", __FILE__, __LINE__);

    // Check we can name members of globals
    check(&global_struct.global_struct_a, "int", "global_struct.global_struct_a", __FILE__, __LINE__);
    check(&global_struct.global_struct_b, "int", "global_struct.global_struct_b", __FILE__, __LINE__);

    check(&global_array[4], "float", "global_array[4]", __FILE__, __LINE__);

    check(&SomeStruct::static_float, "float", "SomeStruct::static_float", __FILE__, __LINE__);

    check(&SomeStruct::static_member_double_array[5], "double", "SomeStruct::static_member_double_array[5]", __FILE__, __LINE__);

    check(&SomeStruct::substruct.a, "int", "SomeStruct::substruct.a", __FILE__, __LINE__);

    printf("Success!\n");

    return 0;
}
<commit_msg>Fix introspection test<commit_after>#include "Halide.h"
#include <stdio.h>

// The check has to go in the Halide namespace, because get_source_location looks for the first thing outside of it
namespace Halide {
void check(const void *var, const std::string &type,
           const std::string &correct_name,
           const std::string &correct_file, int line) {
    std::string correct_loc = correct_file + ":" + std::to_string(line);
    std::string loc = Halide::Internal::Introspection::get_source_location();
    std::string name = Halide::Internal::Introspection::get_variable_name(var, type);

    if (name != correct_name) {
        printf("Mispredicted name: %s vs %s\n",
               name.c_str(), correct_name.c_str());
        exit(-1);
    }

    if (loc != correct_loc) {
        printf("Mispredicted source location: %s vs %s\n",
               loc.c_str(), correct_loc.c_str());
        exit(-1);
    }
}
}

using Halide::check;

int global_int = 7;

struct SomeStruct {
    int global_struct_a;
    int global_struct_b;
    static float static_float;
    static double static_member_double_array[17];
    static struct SubStruct {
        int a;
    } substruct;
} global_struct;

float SomeStruct::static_float = 3.0f;
double SomeStruct::static_member_double_array[17] = {0};
SomeStruct::SubStruct SomeStruct::substruct = {0};

float global_array[7];

namespace Foo {

int global_int_in_foo = 8;

namespace {
struct Bar {
    typedef int bint;
    bint bar_int;
    Bar(int x) : bar_int(x) {}
    ~Bar() {}
    void check_bar() {
        check(this, "Foo::{anonymous}::Bar", "b", __FILE__, __LINE__);
        check(&bar_int, "Foo::{anonymous}::Bar::bint", "b.bar_int", __FILE__, __LINE__);
    }
    int get() {
        return bar_int * 2;
    }
};

int g(int x) {
    Bar b(x*7);
    b.check_bar();
    return b.get();
}

}

int f(int x) {
    static float static_float_in_f = 0.3f;
    int y = g(x) + g(x-1);
    check(&y, "int", "y", __FILE__, __LINE__);
    check(&static_float_in_f, "float", "static_float_in_f", __FILE__, __LINE__);
    return y - 1;
}

}

typedef float fancy_float;

struct HeapObject {
    float f;
    fancy_float f2;
    int i;
    struct  {
        char c;
        double d;
        int i_array[20];
    } inner;
    HeapObject *ptr;
    struct inner2 {
        int a[5];
    };
    inner2 inner2_array[10];
};

int main(int argc, char **argv) {
    bool result = HalideIntrospectionCanary::test();

    if (result) {
        printf("Halide C++ introspection claims to be working with this build config\n");
    } else {
        printf("Halide C++ introspection doesn't claim to work with this build config. Not continuing.\n");
        return 0;
    }

    printf("Continuing with further tests...\n");

    Foo::f(17);

    // Make sure it works all the way up to main
    int secret_int = 5;
    check(&secret_int, "int", "secret_int", __FILE__, __LINE__);

    // Make sure it rejects heap variables
    int *on_the_heap = new int;
    check(on_the_heap, "int", "", __FILE__, __LINE__);
    delete on_the_heap;

    // .. unless they're members of explicitly registered objects
    HeapObject *obj = new HeapObject;
    static HeapObject *dummy_heap_object_ptr = NULL;
    Halide::Internal::Introspection::register_heap_object(obj, sizeof(HeapObject), &dummy_heap_object_ptr);
    check(&(obj->f), "float", "f", __FILE__, __LINE__);
    check(&(obj->f2), "fancy_float", "f2", __FILE__, __LINE__);
    check(&(obj->f2), "float", "f2", __FILE__, __LINE__);
    check(&(obj->i), "int", "i", __FILE__, __LINE__);
    check(&(obj->inner.c), "char", "inner.c", __FILE__, __LINE__);
    check(&(obj->inner.d), "double", "inner.d", __FILE__, __LINE__);
    check(&(obj->ptr), "HeapObject *", "ptr", __FILE__, __LINE__);
    // TODO:
    check(&(obj->inner.i_array[10]), "int", "inner.i_array[10]", __FILE__, __LINE__);
    check(&(obj->inner2_array[4].a[2]), "int", "inner2_array[4].a[2]", __FILE__, __LINE__);
    check(&(obj->inner.i_array), "int [20]", "inner.i_array", __FILE__, __LINE__);
    Halide::Internal::Introspection::deregister_heap_object(obj, sizeof(HeapObject));
    delete obj;

    // Make sure it works for arrays.
    float an_array[17];
    check(&an_array[5], "float", "an_array[5]", __FILE__, __LINE__);

    // Check what happens with lexical blocks which may reuse stack positions
    {
        int block_a = 3;
        (void)block_a;
        check(&block_a, "int", "block_a", __FILE__, __LINE__);
    }

    {
        int block_b = 3;
        (void)block_b;
        check(&block_b, "int", "block_b", __FILE__, __LINE__);
    }

    {
        int block_c = 3;
        (void)block_c;
        check(&block_c, "int", "block_c", __FILE__, __LINE__);
    }

    // Check we can name globals
    check(&global_int, "int", "global_int", __FILE__, __LINE__);
    check(&Foo::global_int_in_foo, "int", "Foo::global_int_in_foo", __FILE__, __LINE__);

    // Check we can name members of globals
    check(&global_struct.global_struct_a, "int", "global_struct.global_struct_a", __FILE__, __LINE__);
    check(&global_struct.global_struct_b, "int", "global_struct.global_struct_b", __FILE__, __LINE__);

    check(&global_array[4], "float", "global_array[4]", __FILE__, __LINE__);

    check(&SomeStruct::static_float, "float", "SomeStruct::static_float", __FILE__, __LINE__);

    check(&SomeStruct::static_member_double_array[5], "double", "SomeStruct::static_member_double_array[5]", __FILE__, __LINE__);

    check(&SomeStruct::substruct.a, "int", "SomeStruct::substruct.a", __FILE__, __LINE__);

    printf("Success!\n");

    return 0;
}
<|endoftext|>