| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/geolocation/geolocation_permission_context.h" | 5 #include "chrome/browser/geolocation/geolocation_permission_context.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/containers/hash_tables.h" | 12 #include "base/containers/hash_tables.h" |
| 13 #include "base/id_map.h" | 13 #include "base/id_map.h" |
| 14 #include "base/memory/scoped_vector.h" | 14 #include "base/memory/scoped_vector.h" |
| 15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
| 16 #include "base/test/simple_test_clock.h" | 16 #include "base/test/simple_test_clock.h" |
| 17 #include "base/time/clock.h" | 17 #include "base/time/clock.h" |
| 18 #include "chrome/browser/chrome_notification_types.h" | 18 #include "chrome/browser/chrome_notification_types.h" |
| 19 #include "chrome/browser/content_settings/host_content_settings_map.h" | 19 #include "chrome/browser/content_settings/host_content_settings_map.h" |
| 20 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | 20 #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
| 21 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h" | 21 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h" |
| 22 #include "chrome/browser/infobars/infobar_service.h" | 22 #include "chrome/browser/infobars/infobar_service.h" |
| 23 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 23 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 24 #include "chrome/test/base/testing_profile.h" | 24 #include "chrome/test/base/testing_profile.h" |
| 25 #include "components/content_settings/core/common/permission_request_id.h" | 25 #include "components/content_settings/core/common/permission_request_id.h" |
| 26 #include "components/infobars/core/confirm_infobar_delegate.h" | 26 #include "components/infobars/core/confirm_infobar_delegate.h" |
| 27 #include "components/infobars/core/infobar.h" | 27 #include "components/infobars/core/infobar.h" |
| 28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/navigation_details.h" | 29 #include "content/public/browser/navigation_details.h" |
| 30 #include "content/public/browser/notification_observer.h" |
| 30 #include "content/public/browser/notification_registrar.h" | 31 #include "content/public/browser/notification_registrar.h" |
| 31 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 32 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| 33 #include "content/public/test/mock_render_process_host.h" | 34 #include "content/public/test/mock_render_process_host.h" |
| 34 #include "content/public/test/test_renderer_host.h" | 35 #include "content/public/test/test_renderer_host.h" |
| 35 #include "content/public/test/test_utils.h" | 36 #include "content/public/test/test_utils.h" |
| 36 #include "content/public/test/web_contents_tester.h" | 37 #include "content/public/test/web_contents_tester.h" |
| 37 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 38 | 39 |
| 39 #if defined(OS_ANDROID) | 40 #if defined(OS_ANDROID) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 InfoBarService* infobar_service() { | 114 InfoBarService* infobar_service() { |
| 114 return InfoBarService::FromWebContents(web_contents()); | 115 return InfoBarService::FromWebContents(web_contents()); |
| 115 } | 116 } |
| 116 InfoBarService* infobar_service_for_tab(int tab) { | 117 InfoBarService* infobar_service_for_tab(int tab) { |
| 117 return InfoBarService::FromWebContents(extra_tabs_[tab]); | 118 return InfoBarService::FromWebContents(extra_tabs_[tab]); |
| 118 } | 119 } |
| 119 | 120 |
| 120 void RequestGeolocationPermission(content::WebContents* web_contents, | 121 void RequestGeolocationPermission(content::WebContents* web_contents, |
| 121 const PermissionRequestID& id, | 122 const PermissionRequestID& id, |
| 122 const GURL& requesting_frame); | 123 const GURL& requesting_frame); |
| 123 void RequestGeolocationPermission(content::WebContents* web_contents, | 124 |
| 124 const PermissionRequestID& id, | |
| 125 const GURL& requesting_frame, | |
| 126 base::Closure* cancel_callback); | |
| 127 void PermissionResponse(const PermissionRequestID& id, | 125 void PermissionResponse(const PermissionRequestID& id, |
| 128 bool allowed); | 126 bool allowed); |
| 129 void CheckPermissionMessageSent(int bridge_id, bool allowed); | 127 void CheckPermissionMessageSent(int bridge_id, bool allowed); |
| 130 void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed); | 128 void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed); |
| 131 void CheckPermissionMessageSentInternal(MockRenderProcessHost* process, | 129 void CheckPermissionMessageSentInternal(MockRenderProcessHost* process, |
| 132 int bridge_id, | 130 int bridge_id, |
| 133 bool allowed); | 131 bool allowed); |
| 134 void AddNewTab(const GURL& url); | 132 void AddNewTab(const GURL& url); |
| 135 void CheckTabContentsState(const GURL& requesting_frame, | 133 void CheckTabContentsState(const GURL& requesting_frame, |
| 136 ContentSetting expected_content_setting); | 134 ContentSetting expected_content_setting); |
| 137 | 135 |
| 138 scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_; | 136 // owned by the browser context |
| 137 GeolocationPermissionContext* geolocation_permission_context_; |
| 139 ClosedInfoBarTracker closed_infobar_tracker_; | 138 ClosedInfoBarTracker closed_infobar_tracker_; |
| 140 ScopedVector<content::WebContents> extra_tabs_; | 139 ScopedVector<content::WebContents> extra_tabs_; |
| 141 | 140 |
| 142 // A map between renderer child id and a pair represending the bridge id and | 141 // A map between renderer child id and a pair represending the bridge id and |
| 143 // whether the requested permission was allowed. | 142 // whether the requested permission was allowed. |
| 144 base::hash_map<int, std::pair<int, bool> > responses_; | 143 base::hash_map<int, std::pair<int, bool> > responses_; |
| 145 }; | 144 }; |
| 146 | 145 |
| 147 PermissionRequestID GeolocationPermissionContextTests::RequestID( | 146 PermissionRequestID GeolocationPermissionContextTests::RequestID( |
| 148 int bridge_id) { | 147 int bridge_id) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 160 extra_tabs_[tab]->GetRenderProcessHost()->GetID(), | 159 extra_tabs_[tab]->GetRenderProcessHost()->GetID(), |
| 161 extra_tabs_[tab]->GetRenderViewHost()->GetRoutingID(), | 160 extra_tabs_[tab]->GetRenderViewHost()->GetRoutingID(), |
| 162 bridge_id, | 161 bridge_id, |
| 163 GURL()); | 162 GURL()); |
| 164 } | 163 } |
| 165 | 164 |
| 166 void GeolocationPermissionContextTests::RequestGeolocationPermission( | 165 void GeolocationPermissionContextTests::RequestGeolocationPermission( |
| 167 content::WebContents* web_contents, | 166 content::WebContents* web_contents, |
| 168 const PermissionRequestID& id, | 167 const PermissionRequestID& id, |
| 169 const GURL& requesting_frame) { | 168 const GURL& requesting_frame) { |
| 170 RequestGeolocationPermission(web_contents, id, requesting_frame, NULL); | 169 geolocation_permission_context_->RequestPermission( |
| 171 } | 170 web_contents, id, requesting_frame, false, |
| 172 | |
| 173 void GeolocationPermissionContextTests::RequestGeolocationPermission( | |
| 174 content::WebContents* web_contents, | |
| 175 const PermissionRequestID& id, | |
| 176 const GURL& requesting_frame, | |
| 177 base::Closure* cancel_callback) { | |
| 178 geolocation_permission_context_->RequestGeolocationPermission( | |
| 179 web_contents, id.bridge_id(), requesting_frame, false, | |
| 180 base::Bind(&GeolocationPermissionContextTests::PermissionResponse, | 171 base::Bind(&GeolocationPermissionContextTests::PermissionResponse, |
| 181 base::Unretained(this), id), | 172 base::Unretained(this), id)); |
| 182 cancel_callback); | 173 content::RunAllBlockingPoolTasksUntilIdle(); |
| 183 content::RunAllBlockingPoolTasksUntilIdle(); | |
| 184 } | 174 } |
| 185 | 175 |
| 186 void GeolocationPermissionContextTests::PermissionResponse( | 176 void GeolocationPermissionContextTests::PermissionResponse( |
| 187 const PermissionRequestID& id, | 177 const PermissionRequestID& id, |
| 188 bool allowed) { | 178 bool allowed) { |
| 189 responses_[id.render_process_id()] = std::make_pair(id.bridge_id(), allowed); | 179 responses_[id.render_process_id()] = std::make_pair(id.bridge_id(), allowed); |
| 190 } | 180 } |
| 191 | 181 |
| 192 void GeolocationPermissionContextTests::CheckPermissionMessageSent( | 182 void GeolocationPermissionContextTests::CheckPermissionMessageSent( |
| 193 int bridge_id, | 183 int bridge_id, |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 requesting_frame_0, requesting_frame_0, | 450 requesting_frame_0, requesting_frame_0, |
| 461 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | 451 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); |
| 462 | 452 |
| 463 EXPECT_EQ(CONTENT_SETTING_ASK, | 453 EXPECT_EQ(CONTENT_SETTING_ASK, |
| 464 profile()->GetHostContentSettingsMap()->GetContentSetting( | 454 profile()->GetHostContentSettingsMap()->GetContentSetting( |
| 465 requesting_frame_1, requesting_frame_0, | 455 requesting_frame_1, requesting_frame_0, |
| 466 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | 456 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); |
| 467 | 457 |
| 468 NavigateAndCommit(requesting_frame_0); | 458 NavigateAndCommit(requesting_frame_0); |
| 469 EXPECT_EQ(0U, infobar_service()->infobar_count()); | 459 EXPECT_EQ(0U, infobar_service()->infobar_count()); |
| 460 |
| 470 // Request permission for two frames. | 461 // Request permission for two frames. |
| 471 base::Closure cancel_callback; | |
| 472 RequestGeolocationPermission( | 462 RequestGeolocationPermission( |
| 473 web_contents(), RequestID(0), requesting_frame_0, &cancel_callback); | 463 web_contents(), RequestID(0), requesting_frame_0); |
| 474 RequestGeolocationPermission( | 464 RequestGeolocationPermission( |
| 475 web_contents(), RequestID(1), requesting_frame_1); | 465 web_contents(), RequestID(1), requesting_frame_1); |
| 476 ASSERT_EQ(1U, infobar_service()->infobar_count()); | 466 ASSERT_EQ(1U, infobar_service()->infobar_count()); |
| 477 | 467 |
| 478 infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0); | 468 infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0); |
| 479 ConfirmInfoBarDelegate* infobar_delegate_0 = | 469 ConfirmInfoBarDelegate* infobar_delegate_0 = |
| 480 infobar_0->delegate()->AsConfirmInfoBarDelegate(); | 470 infobar_0->delegate()->AsConfirmInfoBarDelegate(); |
| 481 ASSERT_TRUE(infobar_delegate_0); | 471 ASSERT_TRUE(infobar_delegate_0); |
| 482 base::string16 text_0 = infobar_delegate_0->GetMessageText(); | 472 base::string16 text_0 = infobar_delegate_0->GetMessageText(); |
| 483 | 473 |
| 484 // Simulate the frame going away, ensure the infobar for this frame | 474 // Simulate the frame going away, ensure the infobar for this frame |
| 485 // is removed and the next pending infobar is created. | 475 // is removed and the next pending infobar is created. |
| 486 cancel_callback.Run(); | 476 geolocation_permission_context_->CancelPermissionRequest(web_contents(), |
| 477 RequestID(0)); |
| 487 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | 478 EXPECT_EQ(1U, closed_infobar_tracker_.size()); |
| 488 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0)); | 479 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0)); |
| 489 closed_infobar_tracker_.Clear(); | 480 closed_infobar_tracker_.Clear(); |
| 490 ASSERT_EQ(1U, infobar_service()->infobar_count()); | 481 ASSERT_EQ(1U, infobar_service()->infobar_count()); |
| 491 | 482 |
| 492 infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0); | 483 infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0); |
| 493 ConfirmInfoBarDelegate* infobar_delegate_1 = | 484 ConfirmInfoBarDelegate* infobar_delegate_1 = |
| 494 infobar_1->delegate()->AsConfirmInfoBarDelegate(); | 485 infobar_1->delegate()->AsConfirmInfoBarDelegate(); |
| 495 ASSERT_TRUE(infobar_delegate_1); | 486 ASSERT_TRUE(infobar_delegate_1); |
| 496 base::string16 text_1 = infobar_delegate_1->GetMessageText(); | 487 base::string16 text_1 = infobar_delegate_1->GetMessageText(); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 | 640 |
| 650 // Delete the tab contents. | 641 // Delete the tab contents. |
| 651 DeleteContents(); | 642 DeleteContents(); |
| 652 | 643 |
| 653 // During contents destruction, the infobar will have been closed, and the | 644 // During contents destruction, the infobar will have been closed, and the |
| 654 // pending request should have been cleared without an infobar being created. | 645 // pending request should have been cleared without an infobar being created. |
| 655 ASSERT_EQ(1U, closed_infobar_tracker_.size()); | 646 ASSERT_EQ(1U, closed_infobar_tracker_.size()); |
| 656 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar)); | 647 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar)); |
| 657 } | 648 } |
| 658 | 649 |
| 659 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) { | |
| 660 GURL requesting_frame_0("http://www.example.com/geolocation"); | |
| 661 GURL requesting_frame_1("http://www.example-2.com/geolocation"); | |
| 662 NavigateAndCommit(requesting_frame_0); | |
| 663 NavigateAndCommit(requesting_frame_1); | |
| 664 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 665 // Go back: navigate to a pending entry before requesting geolocation | |
| 666 // permission. | |
| 667 web_contents()->GetController().GoBack(); | |
| 668 // Request permission for the committed frame (not the pending one). | |
| 669 RequestGeolocationPermission( | |
| 670 web_contents(), RequestID(0), requesting_frame_1); | |
| 671 // Ensure the infobar is created. | |
| 672 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 673 infobars::InfoBarDelegate* infobar_delegate = | |
| 674 infobar_service()->infobar_at(0)->delegate(); | |
| 675 ASSERT_TRUE(infobar_delegate); | |
| 676 // Ensure the infobar wouldn't expire for a navigation to the committed entry. | |
| 677 content::LoadCommittedDetails details; | |
| 678 details.entry = web_contents()->GetController().GetLastCommittedEntry(); | |
| 679 EXPECT_FALSE(infobar_delegate->ShouldExpire( | |
| 680 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details))); | |
| 681 // Ensure the infobar will expire when we commit the pending navigation. | |
| 682 details.entry = web_contents()->GetController().GetActiveEntry(); | |
| 683 EXPECT_TRUE(infobar_delegate->ShouldExpire( | |
| 684 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details))); | |
| 685 | |
| 686 // Delete the tab contents. | |
| 687 DeleteContents(); | |
| 688 } | |
| 689 | |
| 690 TEST_F(GeolocationPermissionContextTests, LastUsageAudited) { | 650 TEST_F(GeolocationPermissionContextTests, LastUsageAudited) { |
| 691 GURL requesting_frame("http://www.example.com/geolocation"); | 651 GURL requesting_frame("http://www.example.com/geolocation"); |
| 692 NavigateAndCommit(requesting_frame); | 652 NavigateAndCommit(requesting_frame); |
| 693 | 653 |
| 694 base::SimpleTestClock* test_clock = new base::SimpleTestClock; | 654 base::SimpleTestClock* test_clock = new base::SimpleTestClock; |
| 695 test_clock->SetNow(base::Time::UnixEpoch() + | 655 test_clock->SetNow(base::Time::UnixEpoch() + |
| 696 base::TimeDelta::FromSeconds(10)); | 656 base::TimeDelta::FromSeconds(10)); |
| 697 | 657 |
| 698 HostContentSettingsMap* map = profile()->GetHostContentSettingsMap(); | 658 HostContentSettingsMap* map = profile()->GetHostContentSettingsMap(); |
| 699 map->SetPrefClockForTesting(scoped_ptr<base::Clock>(test_clock)); | 659 map->SetPrefClockForTesting(scoped_ptr<base::Clock>(test_clock)); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 // it is the embedder. | 775 // it is the embedder. |
| 816 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(), | 776 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(), |
| 817 requesting_frame_0.GetOrigin(), | 777 requesting_frame_0.GetOrigin(), |
| 818 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(), | 778 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(), |
| 819 13); | 779 13); |
| 820 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(), | 780 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(), |
| 821 requesting_frame_0.GetOrigin(), | 781 requesting_frame_0.GetOrigin(), |
| 822 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(), | 782 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(), |
| 823 11); | 783 11); |
| 824 } | 784 } |
| OLD | NEW |