// 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 "content/renderer/geolocation_dispatcher.h"

#include "content/public/common/geoposition.h"
#include "content/renderer/render_view_impl.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebGeolocationPermissionRequest.h"
#include "third_party/WebKit/public/web/WebGeolocationPermissionRequestManager.h"
#include "third_party/WebKit/public/web/WebGeolocationClient.h"
#include "third_party/WebKit/public/web/WebGeolocationPosition.h"
#include "third_party/WebKit/public/web/WebGeolocationError.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"

using blink::WebGeolocationController;
using blink::WebGeolocationError;
using blink::WebGeolocationPermissionRequest;
using blink::WebGeolocationPermissionRequestManager;
using blink::WebGeolocationPosition;

namespace content {

GeolocationDispatcher::GeolocationDispatcher(RenderFrame* render_frame)
    : RenderFrameObserver(render_frame),
      pending_permissions_(new WebGeolocationPermissionRequestManager()),
      enable_high_accuracy_(false) {
}

GeolocationDispatcher::~GeolocationDispatcher() {}

void GeolocationDispatcher::startUpdating() {
  if (!geolocation_service_) {
    render_frame()->GetServiceRegistry()->ConnectToRemoteService(
        &geolocation_service_);
  }
  if (enable_high_accuracy_)
    geolocation_service_->SetHighAccuracy(true);
  QueryNextPosition();
}

void GeolocationDispatcher::stopUpdating() {
  geolocation_service_.reset();
}

void GeolocationDispatcher::setEnableHighAccuracy(bool enable_high_accuracy) {
  // GeolocationController calls setEnableHighAccuracy(true) before
  // startUpdating in response to the first high-accuracy Geolocation
  // subscription. When the last high-accuracy Geolocation unsubscribes
  // it calls setEnableHighAccuracy(false) after stopUpdating.
  bool has_changed = enable_high_accuracy_ != enable_high_accuracy;
  enable_high_accuracy_ = enable_high_accuracy;
  // We have a different accuracy requirement. Request browser to update.
  if (geolocation_service_ && has_changed)
    geolocation_service_->SetHighAccuracy(enable_high_accuracy_);
}

void GeolocationDispatcher::setController(
    WebGeolocationController* controller) {
  controller_.reset(controller);
}

bool GeolocationDispatcher::lastPosition(WebGeolocationPosition&) {
  // The latest position is stored in the browser, not the renderer, so we
  // would have to fetch it synchronously to give a good value here.  The
  // WebCore::GeolocationController already caches the last position it
  // receives, so there is not much benefit to more position caching here.
  return false;
}

// TODO(jknotten): Change the messages to use a security origin, so no
// conversion is necessary.
void GeolocationDispatcher::requestPermission(
    const WebGeolocationPermissionRequest& permissionRequest) {
  if (!permission_service_.get()) {
    render_frame()->GetServiceRegistry()->ConnectToRemoteService(
        &permission_service_);
  }

  int permission_request_id = pending_permissions_->add(permissionRequest);

  permission_service_->RequestPermission(
      PERMISSION_NAME_GEOLOCATION,
      permissionRequest.securityOrigin().toString().utf8(),
      blink::WebUserGestureIndicator::isProcessingUserGesture(),
      base::Bind(&GeolocationDispatcher::OnPermissionSet,
                 base::Unretained(this),
                 permission_request_id));
}

void GeolocationDispatcher::cancelPermissionRequest(
    const blink::WebGeolocationPermissionRequest& permissionRequest) {
  int permission_request_id;
  pending_permissions_->remove(permissionRequest, permission_request_id);
}

// Permission for using geolocation has been set.
void GeolocationDispatcher::OnPermissionSet(
    int permission_request_id,
    PermissionStatus status) {
  WebGeolocationPermissionRequest permissionRequest;
  if (!pending_permissions_->remove(permission_request_id, permissionRequest))
    return;

  permissionRequest.setIsAllowed(status == PERMISSION_STATUS_GRANTED);
}

void GeolocationDispatcher::QueryNextPosition() {
  DCHECK(geolocation_service_);
  geolocation_service_->QueryNextPosition(
      base::Bind(&GeolocationDispatcher::OnPositionUpdate,
                 base::Unretained(this)));
}

void GeolocationDispatcher::OnPositionUpdate(MojoGeopositionPtr geoposition) {
  QueryNextPosition();

  if (geoposition->valid) {
    controller_->positionChanged(WebGeolocationPosition(
        geoposition->timestamp,
        geoposition->latitude,
        geoposition->longitude,
        geoposition->accuracy,
        // Lowest point on land is at approximately -400 meters.
            geoposition->altitude > -10000.,
        geoposition->altitude,
        geoposition->altitude_accuracy >= 0.,
        geoposition->altitude_accuracy,
        geoposition->heading >= 0. && geoposition->heading <= 360.,
        geoposition->heading,
        geoposition->speed >= 0.,
        geoposition->speed));
  } else {
    WebGeolocationError::Error code;
    switch (geoposition->error_code) {
      case Geoposition::ERROR_CODE_PERMISSION_DENIED:
        code = WebGeolocationError::ErrorPermissionDenied;
        break;
      case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
        code = WebGeolocationError::ErrorPositionUnavailable;
        break;
      default:
        NOTREACHED() << geoposition->error_code;
        return;
    }
    controller_->errorOccurred(WebGeolocationError(
        code, blink::WebString::fromUTF8(geoposition->error_message)));
  }
}

}  // namespace content
