Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / location / location_manager.cc
index d07591c..1424701 100644 (file)
 #include "base/bind.h"
 #include "base/lazy_instance.h"
 #include "base/time/time.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/event_router.h"
-#include "chrome/browser/extensions/extension_system.h"
 #include "chrome/common/extensions/api/location.h"
-#include "chrome/common/extensions/extension.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/geolocation_provider.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
 #include "content/public/common/geoposition.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/common/extension.h"
 #include "extensions/common/permissions/permission_set.h"
+#include "extensions/common/permissions/permissions_data.h"
 
 using content::BrowserThread;
 
@@ -58,8 +57,7 @@ class DistanceBasedUpdatePolicy : public UpdatePolicy {
   {}
 
   // UpdatePolicy Implementation
-  virtual bool ShouldSendUpdate(const content::Geoposition& position) const
-      OVERRIDE {
+  bool ShouldSendUpdate(const content::Geoposition& position) const override {
     return !last_updated_position_.Validate() ||
         Distance(position.latitude,
                  position.longitude,
@@ -68,13 +66,12 @@ class DistanceBasedUpdatePolicy : public UpdatePolicy {
             distance_update_threshold_meters_;
   }
 
-  virtual void OnPositionReported(const content::Geoposition& position)
-      OVERRIDE {
+  void OnPositionReported(const content::Geoposition& position) override {
     last_updated_position_ = position;
   }
 
  private:
-  virtual ~DistanceBasedUpdatePolicy() {}
+  ~DistanceBasedUpdatePolicy() override {}
 
   // Calculates the distance between two latitude and longitude points.
   static double Distance(const double latitude1,
@@ -118,17 +115,17 @@ class TimeBasedUpdatePolicy : public UpdatePolicy {
   {}
 
   // UpdatePolicy Implementation
-  virtual bool ShouldSendUpdate(const content::Geoposition&) const OVERRIDE {
+  bool ShouldSendUpdate(const content::Geoposition&) const override {
     return (base::Time::Now() - last_update_time_).InMilliseconds() >
         time_between_updates_ms_;
   }
 
-  virtual void OnPositionReported(const content::Geoposition&) OVERRIDE {
+  void OnPositionReported(const content::Geoposition&) override {
     last_update_time_ = base::Time::Now();
   }
 
  private:
-  virtual ~TimeBasedUpdatePolicy() {}
+  ~TimeBasedUpdatePolicy() override {}
 
   base::Time last_update_time_;
   const double time_between_updates_ms_;
@@ -139,40 +136,20 @@ class TimeBasedUpdatePolicy : public UpdatePolicy {
 } // namespace updatepolicy
 
 // Request created by chrome.location.watchLocation() call.
-// Lives in the IO thread, except for the constructor.
-class LocationRequest
-    : public base::RefCountedThreadSafe<LocationRequest,
-                                        BrowserThread::DeleteOnIOThread> {
+class LocationRequest : public base::RefCounted<LocationRequest> {
  public:
   LocationRequest(
-      const base::WeakPtr<LocationManager>& location_manager,
+      LocationManager* location_manager,
       const std::string& extension_id,
       const std::string& request_name,
       const double* distance_update_threshold_meters,
       const double* time_between_updates_ms);
 
-  // Finishes the necessary setup for this object.
-  // Call this method immediately after taking a strong reference
-  // to this object.
-  //
-  // Ideally, we would do this at construction time, but currently
-  // our refcount starts at zero. BrowserThread::PostTask will take a ref
-  // and potentially release it before we are done, destroying us in the
-  // constructor.
-  void Initialize();
-
   const std::string& request_name() const { return request_name_; }
 
-  // Grants permission for using geolocation.
-  static void GrantPermission();
-
  private:
-  friend class base::DeleteHelper<LocationRequest>;
-  friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
-
-  virtual ~LocationRequest();
-
-  void AddObserverOnIOThread();
+  friend class base::RefCounted<LocationRequest>;
+   ~LocationRequest();
 
   void OnLocationUpdate(const content::Geoposition& position);
 
@@ -190,20 +167,21 @@ class LocationRequest
   const std::string extension_id_;
 
   // Owning location manager.
-  const base::WeakPtr<LocationManager> location_manager_;
+  LocationManager* location_manager_;
 
   // Holds Update Policies.
   typedef std::vector<scoped_refptr<updatepolicy::UpdatePolicy> >
       UpdatePolicyVector;
   UpdatePolicyVector update_policies_;
 
-  content::GeolocationProvider::LocationUpdateCallback callback_;
+  scoped_ptr<content::GeolocationProvider::Subscription>
+      geolocation_subscription_;
 
   DISALLOW_COPY_AND_ASSIGN(LocationRequest);
 };
 
 LocationRequest::LocationRequest(
-    const base::WeakPtr<LocationManager>& location_manager,
+    LocationManager* location_manager,
     const std::string& extension_id,
     const std::string& request_name,
     const double* distance_update_threshold_meters,
@@ -212,8 +190,6 @@ LocationRequest::LocationRequest(
       extension_id_(extension_id),
       location_manager_(location_manager) {
   // TODO(vadimt): use request_info.
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
   if (time_between_updates_ms) {
     update_policies_.push_back(
         new updatepolicy::TimeBasedUpdatePolicy(
@@ -225,58 +201,29 @@ LocationRequest::LocationRequest(
         new updatepolicy::DistanceBasedUpdatePolicy(
               *distance_update_threshold_meters));
   }
-}
-
-void LocationRequest::Initialize() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  callback_ = base::Bind(&LocationRequest::OnLocationUpdate,
-                         base::Unretained(this));
-
-  BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&LocationRequest::AddObserverOnIOThread,
-                 this));
-}
-
-void LocationRequest::GrantPermission() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
-}
-
-LocationRequest::~LocationRequest() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-  content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback(
-      callback_);
-}
-
-void LocationRequest::AddObserverOnIOThread() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
   // TODO(vadimt): This can get a location cached by GeolocationProvider,
   // contrary to the API definition which says that creating a location watch
   // will get new location.
-  content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
-      callback_, true);
+  geolocation_subscription_ = content::GeolocationProvider::GetInstance()->
+      AddLocationUpdateCallback(
+          base::Bind(&LocationRequest::OnLocationUpdate,
+                     base::Unretained(this)),
+          true);
+}
+
+LocationRequest::~LocationRequest() {
 }
 
 void LocationRequest::OnLocationUpdate(const content::Geoposition& position) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   if (ShouldSendUpdate(position)) {
     OnPositionReported(position);
-    BrowserThread::PostTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(&LocationManager::SendLocationUpdate,
-                   location_manager_,
-                   extension_id_,
-                   request_name_,
-                   position));
+    location_manager_->SendLocationUpdate(
+        extension_id_, request_name_, position);
   }
 }
 
 bool LocationRequest::ShouldSendUpdate(const content::Geoposition& position) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   for (UpdatePolicyVector::iterator it = update_policies_.begin();
        it != update_policies_.end();
        ++it) {
@@ -288,7 +235,6 @@ bool LocationRequest::ShouldSendUpdate(const content::Geoposition& position) {
 }
 
 void LocationRequest::OnPositionReported(const content::Geoposition& position) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   for (UpdatePolicyVector::iterator it = update_policies_.begin();
        it != update_policies_.end();
        ++it) {
@@ -296,12 +242,9 @@ void LocationRequest::OnPositionReported(const content::Geoposition& position) {
   }
 }
 
-LocationManager::LocationManager(Profile* profile)
-    : profile_(profile) {
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
-                 content::Source<Profile>(profile_));
-  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
-                 content::Source<Profile>(profile_));
+LocationManager::LocationManager(content::BrowserContext* context)
+    : browser_context_(context), extension_registry_observer_(this) {
+  extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
 }
 
 void LocationManager::AddLocationRequest(
@@ -309,26 +252,25 @@ void LocationManager::AddLocationRequest(
     const std::string& request_name,
     const double* distance_update_threshold_meters,
     const double* time_between_updates_ms) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // TODO(vadimt): Consider resuming requests after restarting the browser.
 
   // Override any old request with the same name.
   RemoveLocationRequest(extension_id, request_name);
 
   LocationRequestPointer location_request =
-      new LocationRequest(AsWeakPtr(),
+      new LocationRequest(this,
                           extension_id,
                           request_name,
                           distance_update_threshold_meters,
                           time_between_updates_ms);
-  location_request->Initialize();
   location_requests_.insert(
       LocationRequestMap::value_type(extension_id, location_request));
 }
 
 void LocationManager::RemoveLocationRequest(const std::string& extension_id,
                                             const std::string& name) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   std::pair<LocationRequestMap::iterator, LocationRequestMap::iterator>
       extension_range = location_requests_.equal_range(extension_id);
@@ -368,7 +310,7 @@ void LocationManager::SendLocationUpdate(
     const std::string& extension_id,
     const std::string& request_name,
     const content::Geoposition& position) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   scoped_ptr<base::ListValue> args(new base::ListValue());
   std::string event_name;
@@ -392,54 +334,42 @@ void LocationManager::SendLocationUpdate(
 
   scoped_ptr<Event> event(new Event(event_name, args.Pass()));
 
-  ExtensionSystem::Get(profile_)->event_router()->
-      DispatchEventToExtension(extension_id, event.Pass());
+  EventRouter::Get(browser_context_)
+      ->DispatchEventToExtension(extension_id, event.Pass());
 }
 
-void LocationManager::Observe(int type,
-                              const content::NotificationSource& source,
-                              const content::NotificationDetails& details) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  switch (type) {
-    case chrome::NOTIFICATION_EXTENSION_LOADED: {
-      // Grants permission to use geolocation once an extension with "location"
-      // permission is loaded.
-      const Extension* extension =
-          content::Details<const Extension>(details).ptr();
-
-      if (extension->HasAPIPermission(APIPermission::kLocation)) {
-          BrowserThread::PostTask(
-              BrowserThread::IO,
-              FROM_HERE,
-              base::Bind(&LocationRequest::GrantPermission));
-      }
-      break;
-    }
-    case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
-      // Delete all requests from the unloaded extension.
-      const Extension* extension =
-          content::Details<const UnloadedExtensionInfo>(details)->extension;
-      location_requests_.erase(extension->id());
-      break;
-    }
-    default:
-      NOTREACHED();
-      break;
+void LocationManager::OnExtensionLoaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension) {
+  // Grants permission to use geolocation once an extension with "location"
+  // permission is loaded.
+  if (extension->permissions_data()->HasAPIPermission(
+          APIPermission::kLocation)) {
+    content::GeolocationProvider::GetInstance()
+        ->UserDidOptIntoLocationServices();
   }
 }
 
-static base::LazyInstance<ProfileKeyedAPIFactory<LocationManager> >
-g_factory = LAZY_INSTANCE_INITIALIZER;
+void LocationManager::OnExtensionUnloaded(
+    content::BrowserContext* browser_context,
+    const Extension* extension,
+    UnloadedExtensionInfo::Reason reason) {
+  // Delete all requests from the unloaded extension.
+  location_requests_.erase(extension->id());
+}
+
+static base::LazyInstance<BrowserContextKeyedAPIFactory<LocationManager> >
+    g_factory = LAZY_INSTANCE_INITIALIZER;
 
 // static
-ProfileKeyedAPIFactory<LocationManager>* LocationManager::GetFactoryInstance() {
-  return &g_factory.Get();
+BrowserContextKeyedAPIFactory<LocationManager>*
+LocationManager::GetFactoryInstance() {
+  return g_factory.Pointer();
 }
 
- // static
-LocationManager* LocationManager::Get(Profile* profile) {
-  return ProfileKeyedAPIFactory<LocationManager>::GetForProfile(profile);
+// static
+LocationManager* LocationManager::Get(content::BrowserContext* context) {
+  return BrowserContextKeyedAPIFactory<LocationManager>::Get(context);
 }
 
 }  // namespace extensions