1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/geolocation/geolocation_permission_context_android.h"
6
7#include "base/prefs/pref_service.h"
8#include "chrome/browser/android/google_location_settings_helper.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/common/pref_names.h"
11#include "content/public/browser/browser_thread.h"
12#include "content/public/browser/web_contents.h"
13
14GeolocationPermissionContextAndroid::
15PermissionRequestInfo::PermissionRequestInfo()
16    : id(0, 0, 0, GURL()),
17      user_gesture(false) {}
18
19GeolocationPermissionContextAndroid::
20    GeolocationPermissionContextAndroid(Profile* profile)
21    : GeolocationPermissionContext(profile),
22      google_location_settings_helper_(
23          GoogleLocationSettingsHelper::Create()) {
24}
25
26GeolocationPermissionContextAndroid::~GeolocationPermissionContextAndroid() {
27}
28
29void GeolocationPermissionContextAndroid::ProceedDecidePermission(
30    content::WebContents* web_contents,
31    const PermissionRequestInfo& info,
32    base::Callback<void(bool)> callback) {
33  // Super class implementation expects everything in UI thread instead.
34  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
35  GeolocationPermissionContext::DecidePermission(
36      web_contents, info.id, info.requesting_frame, info.user_gesture,
37      info.embedder, callback);
38}
39
40void GeolocationPermissionContextAndroid::CheckSystemLocation(
41    content::WebContents* web_contents,
42    const PermissionRequestInfo& info,
43    base::Callback<void(bool)> callback) {
44  // Check to see if the feature in its entirety has been disabled.
45  // This must happen before other services (e.g. tabs, extensions)
46  // get an opportunity to allow the geolocation request.
47  bool enabled = google_location_settings_helper_->IsSystemLocationEnabled();
48
49  base::Closure ui_closure;
50  if (enabled) {
51    ui_closure = base::Bind(
52        &GeolocationPermissionContextAndroid::ProceedDecidePermission,
53        this, web_contents, info, callback);
54  } else {
55    ui_closure = base::Bind(
56        &GeolocationPermissionContextAndroid::PermissionDecided,
57        this, info.id, info.requesting_frame, info.embedder, callback, false);
58  }
59
60  // This method is executed from the BlockingPool, post the result
61  // back to the UI thread.
62  content::BrowserThread::PostTask(
63      content::BrowserThread::UI, FROM_HERE, ui_closure);
64}
65
66void GeolocationPermissionContextAndroid::DecidePermission(
67    content::WebContents* web_contents,
68    const PermissionRequestID& id,
69    const GURL& requesting_frame,
70    bool user_gesture,
71    const GURL& embedder,
72    base::Callback<void(bool)> callback) {
73
74  PermissionRequestInfo info;
75  info.id = id;
76  info.requesting_frame = requesting_frame;
77  info.user_gesture = user_gesture;
78  info.embedder = embedder;
79
80  // Called on the UI thread. However, do the work on a separate thread
81  // to avoid strict mode violation.
82  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
83  content::BrowserThread::PostBlockingPoolTask(FROM_HERE,
84      base::Bind(
85          &GeolocationPermissionContextAndroid::CheckSystemLocation,
86          this, web_contents, info, callback));
87}
88