| Index: content/browser/geolocation/core_location_data_provider_mac.mm | 
| =================================================================== | 
| --- content/browser/geolocation/core_location_data_provider_mac.mm	(revision 76230) | 
| +++ content/browser/geolocation/core_location_data_provider_mac.mm	(working copy) | 
| @@ -1,246 +0,0 @@ | 
| -// Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
| -// Use of this source code is governed by a BSD-style license that can be | 
| -// found in the LICENSE file. | 
| - | 
| -// This file contains the class definitions for the CoreLocation data provider | 
| -// class and the accompanying Objective C wrapper class. This data provider | 
| -// is used to allow the CoreLocation wrapper to run on the UI thread, since | 
| -// CLLocationManager's start and stop updating methods must be called from a | 
| -// thread with an active NSRunLoop.  Currently only the UI thread appears to | 
| -// fill that requirement. | 
| - | 
| -#include "content/browser/geolocation/core_location_data_provider_mac.h" | 
| - | 
| -#include "base/logging.h" | 
| -#include "base/time.h" | 
| -#include "content/browser/geolocation/core_location_provider_mac.h" | 
| -#include "content/browser/geolocation/geolocation_provider.h" | 
| - | 
| -// A few required declarations since the CoreLocation headers are not available | 
| -// with the Mac OS X 10.5 SDK. | 
| -// TODO(jorgevillatoro): Remove these declarations when we build against 10.6 | 
| - | 
| -// This idea was borrowed from wifi_data_provider_corewlan_mac.mm | 
| -typedef double CLLocationDegrees; | 
| -typedef double CLLocationAccuracy; | 
| -typedef double CLLocationSpeed; | 
| -typedef double CLLocationDirection; | 
| -typedef double CLLocationDistance; | 
| -typedef struct { | 
| -  CLLocationDegrees latitude; | 
| -  CLLocationDegrees longitude; | 
| -} CLLocationCoordinate2D; | 
| - | 
| -enum { | 
| -  kCLErrorLocationUnknown  = 0, | 
| -  kCLErrorDenied | 
| -}; | 
| - | 
| -@interface CLLocationManager : NSObject | 
| -+ (BOOL)locationServicesEnabled; | 
| -@property(assign) id delegate; | 
| -- (void)startUpdatingLocation; | 
| -- (void)stopUpdatingLocation; | 
| -@end | 
| - | 
| -@interface CLLocation : NSObject<NSCopying, NSCoding> | 
| -@property(readonly) CLLocationCoordinate2D coordinate; | 
| -@property(readonly) CLLocationDistance altitude; | 
| -@property(readonly) CLLocationAccuracy horizontalAccuracy; | 
| -@property(readonly) CLLocationAccuracy verticalAccuracy; | 
| -@property(readonly) CLLocationDirection course; | 
| -@property(readonly) CLLocationSpeed speed; | 
| -@end | 
| - | 
| -@protocol CLLocationManagerDelegate | 
| -- (void)locationManager:(CLLocationManager*)manager | 
| -    didUpdateToLocation:(CLLocation*)newLocation | 
| -           fromLocation:(CLLocation*)oldLocation; | 
| -- (void)locationManager:(CLLocationManager*)manager | 
| -       didFailWithError:(NSError*)error; | 
| -@end | 
| - | 
| -// This wrapper class receives CLLocation objects from CoreLocation, converts | 
| -// them to Geoposition objects, and passes them on to the data provider class | 
| -// Note: This class has some specific threading requirements, inherited from | 
| -//       CLLocationManager.  The location manaager's start and stop updating | 
| -//       methods must be called from a thread that has an active run loop (which | 
| -//       seems to only be the UI thread) | 
| -@interface CoreLocationWrapperMac : NSObject<CLLocationManagerDelegate> | 
| -{ | 
| - @private | 
| -  NSBundle* bundle_; | 
| -  Class locationManagerClass_; | 
| -  id locationManager_; | 
| -  CoreLocationDataProviderMac* dataProvider_; | 
| -} | 
| - | 
| -- (id)initWithDataProvider:(CoreLocationDataProviderMac*)dataProvider; | 
| -- (void)dealloc; | 
| - | 
| -// Can be called from any thread since it does not require an NSRunLoop. However | 
| -// it is not threadsafe to receive concurrent calls until after it's first | 
| -// successful call (to avoid |bundle_| being double initialized) | 
| -- (BOOL)locationDataAvailable; | 
| - | 
| -// These should always be called from BrowserThread::UI | 
| -- (void)startLocation; | 
| -- (void)stopLocation; | 
| - | 
| -// These should only be called by CLLocationManager | 
| -- (void)locationManager:(CLLocationManager*)manager | 
| -    didUpdateToLocation:(CLLocation*)newLocation | 
| -           fromLocation:(CLLocation*)oldLocation; | 
| -- (void)locationManager:(CLLocationManager*)manager | 
| -       didFailWithError:(NSError*)error; | 
| -- (BOOL)loadCoreLocationBundle; | 
| - | 
| -@end | 
| - | 
| -@implementation CoreLocationWrapperMac | 
| - | 
| -- (id)initWithDataProvider:(CoreLocationDataProviderMac*)dataProvider { | 
| -  DCHECK(dataProvider); | 
| -  dataProvider_ = dataProvider; | 
| -  self = [super init]; | 
| -  return self; | 
| -} | 
| - | 
| -- (void)dealloc { | 
| -  [locationManager_ release]; | 
| -  [locationManagerClass_ release]; | 
| -  [bundle_ release]; | 
| -  [super dealloc]; | 
| -} | 
| - | 
| -// Load the bundle and check to see if location services are enabled | 
| -// but don't do anything else | 
| -- (BOOL)locationDataAvailable { | 
| -  return ([self loadCoreLocationBundle] && | 
| -          [locationManagerClass_ locationServicesEnabled]); | 
| -} | 
| - | 
| -- (void)startLocation { | 
| -  if ([self locationDataAvailable]) { | 
| -    if (!locationManager_) { | 
| -      locationManager_ = [[locationManagerClass_ alloc] init]; | 
| -      [locationManager_ setDelegate:self]; | 
| -    } | 
| -    [locationManager_ startUpdatingLocation]; | 
| -  } | 
| -} | 
| - | 
| -- (void)stopLocation { | 
| -  [locationManager_ stopUpdatingLocation]; | 
| -} | 
| - | 
| -- (void)locationManager:(CLLocationManager*)manager | 
| -    didUpdateToLocation:(CLLocation*)newLocation | 
| -           fromLocation:(CLLocation*)oldLocation { | 
| -  Geoposition position; | 
| -  position.latitude  = [newLocation coordinate].latitude; | 
| -  position.longitude = [newLocation coordinate].longitude; | 
| -  position.altitude  = [newLocation altitude]; | 
| -  position.accuracy  = [newLocation horizontalAccuracy]; | 
| -  position.altitude_accuracy = [newLocation verticalAccuracy]; | 
| -  position.speed = [newLocation speed]; | 
| -  position.heading = [newLocation course]; | 
| -  position.timestamp = base::Time::Now(); | 
| -  position.error_code = Geoposition::ERROR_CODE_NONE; | 
| -  dataProvider_->UpdatePosition(&position); | 
| -} | 
| - | 
| -- (void)locationManager:(CLLocationManager*)manager | 
| -       didFailWithError:(NSError*)error { | 
| -  Geoposition position; | 
| -  switch ([error code]) { | 
| -    case kCLErrorLocationUnknown: | 
| -      position.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; | 
| -      break; | 
| -    case kCLErrorDenied: | 
| -      position.error_code = Geoposition::ERROR_CODE_PERMISSION_DENIED; | 
| -      break; | 
| -    default: | 
| -      NOTREACHED() << "Unknown CoreLocation error: " << [error code]; | 
| -      return; | 
| -  } | 
| -  dataProvider_->UpdatePosition(&position); | 
| -} | 
| - | 
| -- (BOOL)loadCoreLocationBundle { | 
| -  if (!bundle_) { | 
| -    bundle_ = [[NSBundle alloc] | 
| -        initWithPath:@"/System/Library/Frameworks/CoreLocation.framework"]; | 
| -    if (!bundle_) { | 
| -      DLOG(WARNING) << "Couldn't load CoreLocation Framework"; | 
| -      return NO; | 
| -    } | 
| - | 
| -    locationManagerClass_ = [bundle_ classNamed:@"CLLocationManager"]; | 
| -  } | 
| - | 
| -  return YES; | 
| -} | 
| - | 
| -@end | 
| - | 
| -CoreLocationDataProviderMac::CoreLocationDataProviderMac() { | 
| -  if (MessageLoop::current() != | 
| -      GeolocationProvider::GetInstance()->message_loop()) { | 
| -    NOTREACHED() << "CoreLocation data provider must be created on " | 
| -        "the Geolocation thread."; | 
| -  } | 
| -  provider_ = NULL; | 
| -  wrapper_.reset([[CoreLocationWrapperMac alloc] initWithDataProvider:this]); | 
| -} | 
| - | 
| -CoreLocationDataProviderMac::~CoreLocationDataProviderMac() { | 
| -} | 
| - | 
| -// Returns true if the CoreLocation wrapper can load the framework and | 
| -// location services are enabled.  The pointer argument will only be accessed | 
| -// in the origin thread. | 
| -bool CoreLocationDataProviderMac:: | 
| -    StartUpdating(CoreLocationProviderMac* provider) { | 
| -  DCHECK(provider); | 
| -  DCHECK(!provider_) << "StartUpdating called twice"; | 
| -  if (![wrapper_ locationDataAvailable]) return false; | 
| -  provider_ = provider; | 
| -  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 
| -     NewRunnableMethod(this, &CoreLocationDataProviderMac::StartUpdatingTask)); | 
| -  return true; | 
| -} | 
| - | 
| -// Clears provider_ so that any leftover messages from CoreLocation get ignored | 
| -void CoreLocationDataProviderMac::StopUpdating() { | 
| -  provider_ = NULL; | 
| -  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 
| -              NewRunnableMethod(this, | 
| -                               &CoreLocationDataProviderMac::StopUpdatingTask)); | 
| -} | 
| - | 
| -void CoreLocationDataProviderMac::UpdatePosition(Geoposition *position) { | 
| -  GeolocationProvider::GetInstance()->message_loop()->PostTask(FROM_HERE, | 
| -              NewRunnableMethod(this, | 
| -                               &CoreLocationDataProviderMac::PositionUpdated, | 
| -                               *position)); | 
| -} | 
| - | 
| -// Runs in BrowserThread::UI | 
| -void CoreLocationDataProviderMac::StartUpdatingTask() { | 
| -  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| -  [wrapper_ startLocation]; | 
| -} | 
| - | 
| -// Runs in BrowserThread::UI | 
| -void CoreLocationDataProviderMac::StopUpdatingTask() { | 
| -  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| -  [wrapper_ stopLocation]; | 
| -} | 
| - | 
| -void CoreLocationDataProviderMac::PositionUpdated(Geoposition position) { | 
| -  DCHECK(MessageLoop::current() == | 
| -         GeolocationProvider::GetInstance()->message_loop()); | 
| -  if (provider_) | 
| -    provider_->SetPosition(&position); | 
| -} | 
|  |