• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "android_webview/native/permission/permission_request_handler.h"
6 
7 #include "android_webview/native/permission/aw_permission_request.h"
8 #include "android_webview/native/permission/aw_permission_request_delegate.h"
9 #include "android_webview/native/permission/permission_request_handler_client.h"
10 #include "base/android/scoped_java_ref.h"
11 #include "base/bind.h"
12 #include "content/public/browser/navigation_details.h"
13 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/web_contents.h"
15 
16 using base::android::ScopedJavaLocalRef;
17 
18 namespace android_webview {
19 
20 namespace {
21 
GetActiveEntryID(content::WebContents * web_contents)22 int GetActiveEntryID(content::WebContents* web_contents) {
23   if (!web_contents) return 0;
24 
25   content::NavigationEntry* active_entry =
26       web_contents->GetController().GetActiveEntry();
27   return active_entry ? active_entry->GetUniqueID() : 0;
28 }
29 
30 }  // namespace
31 
PermissionRequestHandler(PermissionRequestHandlerClient * client,content::WebContents * web_contents)32 PermissionRequestHandler::PermissionRequestHandler(
33     PermissionRequestHandlerClient* client, content::WebContents* web_contents)
34     : content::WebContentsObserver(web_contents),
35       client_(client),
36       contents_unique_id_(GetActiveEntryID(web_contents)) {
37 }
38 
~PermissionRequestHandler()39 PermissionRequestHandler::~PermissionRequestHandler() {
40   CancelAllRequests();
41 }
42 
SendRequest(scoped_ptr<AwPermissionRequestDelegate> request)43 void PermissionRequestHandler::SendRequest(
44     scoped_ptr<AwPermissionRequestDelegate> request) {
45   if (Preauthorized(request->GetOrigin(), request->GetResources())) {
46     request->NotifyRequestResult(true);
47     return;
48   }
49 
50   AwPermissionRequest* aw_request = new AwPermissionRequest(request.Pass());
51   requests_.push_back(
52       base::WeakPtr<AwPermissionRequest>(aw_request->GetWeakPtr()));
53   client_->OnPermissionRequest(aw_request);
54   PruneRequests();
55 }
56 
CancelRequest(const GURL & origin,int64 resources)57 void PermissionRequestHandler::CancelRequest(const GURL& origin,
58                                              int64 resources) {
59   // The request list might have multiple requests with same origin and
60   // resources.
61   RequestIterator i = FindRequest(origin, resources);
62   while (i != requests_.end()) {
63     CancelRequest(i);
64     requests_.erase(i);
65     i = FindRequest(origin, resources);
66   }
67 }
68 
PreauthorizePermission(const GURL & origin,int64 resources)69 void PermissionRequestHandler::PreauthorizePermission(const GURL& origin,
70                                                       int64 resources) {
71   if (!resources)
72     return;
73 
74   std::string key = origin.GetOrigin().spec();
75   if (key.empty()) {
76     LOG(ERROR) << "The origin of preauthorization is empty, ignore it.";
77     return;
78   }
79 
80   preauthorized_permission_[key] |= resources;
81 }
82 
NavigationEntryCommitted(const content::LoadCommittedDetails & details)83 void PermissionRequestHandler::NavigationEntryCommitted(
84     const content::LoadCommittedDetails& details) {
85   const content::PageTransition transition = details.entry->GetTransitionType();
86   if (details.is_navigation_to_different_page() ||
87       content::PageTransitionStripQualifier(transition) ==
88       content::PAGE_TRANSITION_RELOAD ||
89       contents_unique_id_ != details.entry->GetUniqueID()) {
90     CancelAllRequests();
91     contents_unique_id_ = details.entry->GetUniqueID();
92   }
93 }
94 
95 PermissionRequestHandler::RequestIterator
FindRequest(const GURL & origin,int64 resources)96 PermissionRequestHandler::FindRequest(const GURL& origin,
97                                       int64 resources) {
98   RequestIterator i;
99   for (i = requests_.begin(); i != requests_.end(); ++i) {
100     if (i->get() && i->get()->GetOrigin() == origin &&
101         i->get()->GetResources() == resources) {
102       break;
103     }
104   }
105   return i;
106 }
107 
CancelRequest(RequestIterator i)108 void PermissionRequestHandler::CancelRequest(RequestIterator i) {
109   if (i->get())
110     client_->OnPermissionRequestCanceled(i->get());
111   // The request's grant()/deny() could be called upon
112   // OnPermissionRequestCanceled. Delete AwPermissionRequest if it still
113   // exists.
114   if (i->get())
115     delete i->get();
116 }
117 
CancelAllRequests()118 void PermissionRequestHandler::CancelAllRequests() {
119   for (RequestIterator i = requests_.begin(); i != requests_.end(); ++i)
120     CancelRequest(i);
121 }
122 
PruneRequests()123 void PermissionRequestHandler::PruneRequests() {
124   for (RequestIterator i = requests_.begin(); i != requests_.end();) {
125     if (!i->get())
126       i = requests_.erase(i);
127     else
128       ++i;
129   }
130 }
131 
Preauthorized(const GURL & origin,int64 resources)132 bool PermissionRequestHandler::Preauthorized(const GURL& origin,
133                                               int64 resources) {
134   std::map<std::string, int64>::iterator i =
135       preauthorized_permission_.find(origin.GetOrigin().spec());
136 
137   return i != preauthorized_permission_.end() &&
138       (resources & i->second) == resources;
139 }
140 
141 }  // namespace android_webivew
142