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#ifndef CHROME_BROWSER_GEOLOCATION_GEOLOCATION_PERMISSION_CONTEXT_H_
6#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_PERMISSION_CONTEXT_H_
7
8#include <map>
9#include <string>
10
11#include "base/callback.h"
12#include "base/containers/scoped_ptr_hash_map.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "chrome/browser/content_settings/permission_queue_controller.h"
16#include "chrome/browser/geolocation/geolocation_permission_context_extensions.h"
17
18namespace content {
19class WebContents;
20}
21
22class GeolocationPermissionRequest;
23class PermissionRequestID;
24class Profile;
25
26// This manages Geolocation permissions flow, and delegates UI handling via
27// PermissionQueueController.
28class GeolocationPermissionContext
29    : public base::RefCountedThreadSafe<GeolocationPermissionContext> {
30 public:
31  explicit GeolocationPermissionContext(Profile* profile);
32
33  // See ContentBrowserClient method of the same name.
34  void RequestGeolocationPermission(
35      content::WebContents* web_contents,
36      int bridge_id,
37      const GURL& requesting_frame,
38      bool user_gesture,
39      base::Callback<void(bool)> result_callback,
40      base::Closure* cancel_callback);
41
42  // Called on the UI thread when the profile is about to be destroyed.
43  void ShutdownOnUIThread();
44
45  // Notifies whether or not the corresponding bridge is allowed to use
46  // geolocation via
47  // GeolocationPermissionContext::SetGeolocationPermissionResponse().
48  // Called on the UI thread.
49  void NotifyPermissionSet(const PermissionRequestID& id,
50                           const GURL& requesting_frame,
51                           base::Callback<void(bool)> callback,
52                           bool allowed);
53
54 protected:
55  virtual ~GeolocationPermissionContext();
56
57  Profile* profile() const { return profile_; }
58
59  // Return an instance of the infobar queue controller, creating it
60  // if necessary.
61  PermissionQueueController* QueueController();
62
63  void CancelGeolocationPermissionRequest(
64      int render_process_id,
65      int render_view_id,
66      int bridge_id);
67
68  // GeolocationPermissionContext implementation:
69  // Decide whether the geolocation permission should be granted.
70  // Calls PermissionDecided if permission can be decided non-interactively,
71  // or NotifyPermissionSet if permission decided by presenting an
72  // infobar to the user. Called on the UI thread.
73  virtual void DecidePermission(content::WebContents* web_contents,
74                                const PermissionRequestID& id,
75                                const GURL& requesting_frame,
76                                bool user_gesture,
77                                const GURL& embedder,
78                                base::Callback<void(bool)> callback);
79
80  // Called when permission is granted without interactively asking
81  // the user. Can be overridden to introduce additional UI flow.
82  // Should ultimately ensure that NotifyPermissionSet is called.
83  // Called on the UI thread.
84  virtual void PermissionDecided(const PermissionRequestID& id,
85                                 const GURL& requesting_frame,
86                                 const GURL& embedder,
87                                 base::Callback<void(bool)> callback,
88                                 bool allowed);
89
90  // Create an PermissionQueueController. overriden in derived classes to
91  // provide additional UI flow.  Called on the UI thread.
92  virtual PermissionQueueController* CreateQueueController();
93
94 private:
95  friend class base::RefCountedThreadSafe<GeolocationPermissionContext>;
96  friend class GeolocationPermissionRequest;
97
98  // Removes any pending InfoBar request.
99  void CancelPendingInfobarRequest(const PermissionRequestID& id);
100
101  // Creates and show an info bar.
102  void CreateInfoBarRequest(const PermissionRequestID& id,
103                            const GURL& requesting_frame,
104                            const GURL& embedder,
105                            base::Callback<void(bool)> callback);
106
107  // Notify the context that a particular request object is no longer needed.
108  void RequestFinished(GeolocationPermissionRequest* request);
109
110  // These must only be accessed from the UI thread.
111  Profile* const profile_;
112  bool shutting_down_;
113  scoped_ptr<PermissionQueueController> permission_queue_controller_;
114  GeolocationPermissionContextExtensions extensions_context_;
115
116  base::ScopedPtrHashMap<std::string, GeolocationPermissionRequest>
117      pending_requests_;
118
119  DISALLOW_COPY_AND_ASSIGN(GeolocationPermissionContext);
120};
121
122#endif  // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_PERMISSION_CONTEXT_H_
123