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/aw_permission_request.h"
6#include "android_webview/native/permission/aw_permission_request_delegate.h"
7#include "android_webview/native/permission/permission_request_handler.h"
8#include "android_webview/native/permission/permission_request_handler_client.h"
9#include "base/bind.h"
10#include "base/callback.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace android_webview {
14
15class TestAwPermissionRequestDelegate : public AwPermissionRequestDelegate {
16 public:
17  TestAwPermissionRequestDelegate(
18      const GURL& origin, int64 resources, base::Callback<void(bool)> callback)
19      : origin_(origin),
20        resources_(resources),
21        callback_(callback) {}
22
23  // Get the origin which initiated the permission request.
24  virtual const GURL& GetOrigin() OVERRIDE {
25    return origin_;
26  }
27
28  // Get the resources the origin wanted to access.
29  virtual int64 GetResources() OVERRIDE {
30    return resources_;
31  }
32
33  // Notify the permission request is allowed or not.
34  virtual void NotifyRequestResult(bool allowed) OVERRIDE {
35    callback_.Run(allowed);
36  }
37
38 private:
39  GURL origin_;
40  int64 resources_;
41  base::Callback<void(bool)> callback_;
42};
43
44class TestPermissionRequestHandlerClient :
45      public PermissionRequestHandlerClient {
46 public:
47  struct Permission {
48    Permission()
49        :resources(0) {}
50    Permission(const GURL& origin, int64 resources)
51        : origin(origin),
52          resources(resources) {}
53    GURL origin;
54    int64 resources;
55  };
56
57  TestPermissionRequestHandlerClient()
58      : request_(NULL) {}
59
60  virtual void OnPermissionRequest(AwPermissionRequest* request) OVERRIDE {
61    request_ = request;
62    requested_permission_ =
63        Permission(request->GetOrigin(), request->GetResources());
64  }
65
66  virtual void OnPermissionRequestCanceled(
67      AwPermissionRequest* request) OVERRIDE{
68    canceled_permission_ =
69        Permission(request->GetOrigin(), request->GetResources());
70  }
71
72  AwPermissionRequest* request() {
73    return request_;
74  }
75
76  const Permission& requested_permission() {
77    return requested_permission_;
78  }
79
80  const Permission& canceled_permission() {
81    return canceled_permission_;
82  }
83
84  void Grant() {
85    request_->OnAccept(NULL, NULL, true);
86    request_ = NULL;
87  }
88
89  void Deny() {
90    request_->OnAccept(NULL, NULL, false);
91    request_ = NULL;
92  }
93
94  void Reset() {
95    request_ = NULL;
96    requested_permission_ = Permission();
97    canceled_permission_ = Permission();
98  }
99
100 private:
101  AwPermissionRequest* request_;
102  Permission requested_permission_;
103  Permission canceled_permission_;
104};
105
106class TestPermissionRequestHandler : public PermissionRequestHandler {
107 public:
108  TestPermissionRequestHandler(PermissionRequestHandlerClient* client)
109      : PermissionRequestHandler(client, NULL) {
110  }
111
112  const std::vector<base::WeakPtr<AwPermissionRequest> > requests() {
113    return requests_;
114  }
115
116  void PruneRequests() {
117    return PermissionRequestHandler::PruneRequests();
118  }
119};
120
121class PermissionRequestHandlerTest : public testing::Test {
122 public:
123  PermissionRequestHandlerTest()
124      : handler_(&client_),
125        allowed_(false) {}
126
127  void NotifyRequestResult(bool allowed) {
128    allowed_ = allowed;
129  }
130
131 protected:
132  virtual void SetUp() OVERRIDE {
133    testing::Test::SetUp();
134    origin_ = GURL("http://www.google.com");
135    resources_ =
136        AwPermissionRequest::VideoCapture | AwPermissionRequest::AudioCapture;
137    delegate_.reset(
138        new TestAwPermissionRequestDelegate(
139            origin_, resources_, base::Bind(
140                &PermissionRequestHandlerTest::NotifyRequestResult,
141                base::Unretained(this))));
142  }
143
144  const GURL& origin() {
145    return origin_;
146  }
147
148  int64 resources() {
149    return resources_;
150  }
151
152  scoped_ptr<AwPermissionRequestDelegate> delegate() {
153    return delegate_.Pass();
154  }
155
156  TestPermissionRequestHandler* handler() {
157    return  &handler_;
158  }
159
160  TestPermissionRequestHandlerClient* client() {
161    return &client_;
162  }
163
164  bool allowed() {
165    return allowed_;
166  }
167
168 private:
169  GURL origin_;
170  int64 resources_;
171  scoped_ptr<AwPermissionRequestDelegate> delegate_;
172  TestPermissionRequestHandlerClient client_;
173  TestPermissionRequestHandler handler_;
174  bool allowed_;
175};
176
177TEST_F(PermissionRequestHandlerTest, TestPermissionGranted) {
178  handler()->SendRequest(delegate().Pass());
179  // Verify Handler store the request correctly.
180  ASSERT_EQ(1u, handler()->requests().size());
181  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
182  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
183
184  // Verify client's onPermissionRequest was called
185  EXPECT_EQ(origin(), client()->request()->GetOrigin());
186  EXPECT_EQ(resources(), client()->request()->GetResources());
187
188  // Simulate the grant request.
189  client()->Grant();
190  // Verify the request is notified as granted
191  EXPECT_TRUE(allowed());
192  handler()->PruneRequests();
193  // Verify the weak reference in handler was removed.
194  EXPECT_TRUE(handler()->requests().empty());
195}
196
197TEST_F(PermissionRequestHandlerTest, TestPermissionDenied) {
198  handler()->SendRequest(delegate().Pass());
199  // Verify Handler store the request correctly.
200  ASSERT_EQ(1u, handler()->requests().size());
201  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
202  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
203
204  // Verify client's onPermissionRequest was called
205  EXPECT_EQ(origin(), client()->request()->GetOrigin());
206  EXPECT_EQ(resources(), client()->request()->GetResources());
207
208  // Simulate the deny request.
209  client()->Deny();
210  // Verify the request is notified as granted
211  EXPECT_FALSE(allowed());
212  handler()->PruneRequests();
213  // Verify the weak reference in handler was removed.
214  EXPECT_TRUE(handler()->requests().empty());
215}
216
217TEST_F(PermissionRequestHandlerTest, TestMultiplePermissionRequest) {
218  GURL origin1 = GURL("http://a.google.com");
219  int64 resources1 = AwPermissionRequest::Geolocation;
220
221  scoped_ptr<AwPermissionRequestDelegate> delegate1;
222  delegate1.reset(new TestAwPermissionRequestDelegate(
223      origin1, resources1,
224      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
225                 base::Unretained(this))));
226
227  // Send 1st request
228  handler()->SendRequest(delegate().Pass());
229  // Verify Handler store the request correctly.
230  ASSERT_EQ(1u, handler()->requests().size());
231  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
232  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
233  // Verify client's onPermissionRequest was called
234  EXPECT_EQ(origin(), client()->request()->GetOrigin());
235  EXPECT_EQ(resources(), client()->request()->GetResources());
236
237  // Send 2nd request
238  handler()->SendRequest(delegate1.Pass());
239  // Verify Handler store the request correctly.
240  ASSERT_EQ(2u, handler()->requests().size());
241  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
242  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
243  EXPECT_EQ(origin1, handler()->requests()[1]->GetOrigin());
244  EXPECT_EQ(resources1, handler()->requests()[1]->GetResources());
245  // Verify client's onPermissionRequest was called
246  EXPECT_EQ(origin1, client()->request()->GetOrigin());
247  EXPECT_EQ(resources1, client()->request()->GetResources());
248
249  // Send 3rd request which has same origin and resources as first one.
250  delegate1.reset(new TestAwPermissionRequestDelegate(origin(), resources(),
251      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
252                 base::Unretained(this))));
253  handler()->SendRequest(delegate1.Pass());
254  // Verify Handler store the request correctly.
255  ASSERT_EQ(3u, handler()->requests().size());
256  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
257  EXPECT_EQ(resources(), handler()->requests()[0]->GetResources());
258  EXPECT_EQ(origin1, handler()->requests()[1]->GetOrigin());
259  EXPECT_EQ(resources1, handler()->requests()[1]->GetResources());
260  EXPECT_EQ(origin(), handler()->requests()[2]->GetOrigin());
261  EXPECT_EQ(resources(), handler()->requests()[2]->GetResources());
262  // Verify client's onPermissionRequest was called
263  EXPECT_EQ(origin(), client()->request()->GetOrigin());
264  EXPECT_EQ(resources(), client()->request()->GetResources());
265
266  // Cancel the request.
267  handler()->CancelRequest(origin(), resources());
268  // Verify client's OnPermissionRequestCancled() was called.
269  EXPECT_EQ(origin(), client()->canceled_permission().origin);
270  EXPECT_EQ(resources(), client()->canceled_permission().resources);
271  // Verify Handler store the request correctly, the 1st and 3rd were removed.
272  handler()->PruneRequests();
273  ASSERT_EQ(1u, handler()->requests().size());
274  EXPECT_EQ(origin1, handler()->requests()[0]->GetOrigin());
275  EXPECT_EQ(resources1, handler()->requests()[0]->GetResources());
276}
277
278TEST_F(PermissionRequestHandlerTest, TestPreauthorizePermission) {
279  handler()->PreauthorizePermission(origin(), resources());
280
281  // Permission should granted without asking PermissionRequestHandlerClient.
282  handler()->SendRequest(delegate().Pass());
283  EXPECT_TRUE(allowed());
284  EXPECT_EQ(NULL, client()->request());
285
286  // Only ask one preauthorized resource, permission should granted
287  // without asking PermissionRequestHandlerClient.
288  scoped_ptr<AwPermissionRequestDelegate> delegate;
289  delegate.reset(new TestAwPermissionRequestDelegate(
290      origin(), AwPermissionRequest::AudioCapture,
291      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
292                 base::Unretained(this))));
293  client()->Reset();
294  handler()->SendRequest(delegate.Pass());
295  EXPECT_TRUE(allowed());
296  EXPECT_EQ(NULL, client()->request());
297}
298
299TEST_F(PermissionRequestHandlerTest, TestOriginNotPreauthorized) {
300  handler()->PreauthorizePermission(origin(), resources());
301
302  // Ask the origin which wasn't preauthorized.
303  GURL origin ("http://a.google.com/a/b");
304  scoped_ptr<AwPermissionRequestDelegate> delegate;
305  int64 requested_resources = AwPermissionRequest::AudioCapture;
306  delegate.reset(new TestAwPermissionRequestDelegate(
307      origin, requested_resources,
308      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
309                 base::Unretained(this))));
310  handler()->SendRequest(delegate.Pass());
311  EXPECT_EQ(origin, handler()->requests()[0]->GetOrigin());
312  EXPECT_EQ(requested_resources, handler()->requests()[0]->GetResources());
313  client()->Grant();
314  EXPECT_TRUE(allowed());
315}
316
317TEST_F(PermissionRequestHandlerTest, TestResourcesNotPreauthorized) {
318  handler()->PreauthorizePermission(origin(), resources());
319
320  // Ask the resources which weren't preauthorized.
321  scoped_ptr<AwPermissionRequestDelegate> delegate;
322  int64 requested_resources = AwPermissionRequest::AudioCapture
323    | AwPermissionRequest::Geolocation;
324  delegate.reset(new TestAwPermissionRequestDelegate(
325      origin(), requested_resources,
326      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
327                 base::Unretained(this))));
328
329  handler()->SendRequest(delegate.Pass());
330  EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin());
331  EXPECT_EQ(requested_resources, handler()->requests()[0]->GetResources());
332  client()->Deny();
333  EXPECT_FALSE(allowed());
334}
335
336TEST_F(PermissionRequestHandlerTest, TestPreauthorizeMultiplePermission) {
337  handler()->PreauthorizePermission(origin(), resources());
338  // Preauthorize another permission.
339  GURL origin ("http://a.google.com/a/b");
340  handler()->PreauthorizePermission(origin, AwPermissionRequest::Geolocation);
341  GURL origin_hostname ("http://a.google.com/");
342  scoped_ptr<AwPermissionRequestDelegate> delegate;
343  delegate.reset(new TestAwPermissionRequestDelegate(
344      origin_hostname, AwPermissionRequest::Geolocation,
345      base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult,
346                 base::Unretained(this))));
347  handler()->SendRequest(delegate.Pass());
348  EXPECT_TRUE(allowed());
349  EXPECT_EQ(NULL, client()->request());
350}
351
352}  // android_webview
353