-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Storage Access API service skeleton
This creates a new service and a corresponding tab helper which observes non-main-frame user interactions. The service currently does not do anything, but will eventually renew Storage Access API permission grants at most once per day per grant per profile. Bug: 1450356 Change-Id: I7beebaf5b977d0c7fc5853b8f8f29028263402e5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4574776 Reviewed-by: Shuran Huang <shuuran@chromium.org> Reviewed-by: Scott Violet <sky@chromium.org> Commit-Queue: Chris Fredrickson <cfredric@chromium.org> Cr-Commit-Position: refs/heads/main@{#1153513}
- Loading branch information
Showing
16 changed files
with
479 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
chrome/browser/storage_access_api/storage_access_api_service.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_H_ | ||
#define CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_H_ | ||
|
||
namespace url { | ||
class Origin; | ||
} // namespace url | ||
|
||
// An abstract class providing the interface for the Storage Access API service. | ||
// This class exists so that a different implementation may be used in tests. | ||
class StorageAccessAPIService { | ||
public: | ||
// May renew Storage Access API permission grants associated with the given | ||
// origins. | ||
// | ||
// The implementations of this method may apply rate limiting and caching in | ||
// order to avoid unnecessary disk writes. | ||
virtual void RenewPermissionGrant(const url::Origin& embedded_origin, | ||
const url::Origin& top_frame_origin) = 0; | ||
}; | ||
|
||
#endif // CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_H_ |
42 changes: 42 additions & 0 deletions
42
chrome/browser/storage_access_api/storage_access_api_service_factory.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/storage_access_api/storage_access_api_service_factory.h" | ||
|
||
#include "base/no_destructor.h" | ||
#include "chrome/browser/profiles/profile_keyed_service_factory.h" | ||
#include "chrome/browser/profiles/profile_selections.h" | ||
#include "chrome/browser/storage_access_api/storage_access_api_service_impl.h" | ||
|
||
// static | ||
StorageAccessAPIServiceImpl* | ||
StorageAccessAPIServiceFactory::GetForBrowserContext( | ||
content::BrowserContext* context) { | ||
return static_cast<StorageAccessAPIServiceImpl*>( | ||
StorageAccessAPIServiceFactory::GetInstance() | ||
->GetServiceForBrowserContext(context, /*create=*/true)); | ||
} | ||
|
||
// static | ||
StorageAccessAPIServiceFactory* StorageAccessAPIServiceFactory::GetInstance() { | ||
static base::NoDestructor<StorageAccessAPIServiceFactory> instance; | ||
return instance.get(); | ||
} | ||
|
||
StorageAccessAPIServiceFactory::StorageAccessAPIServiceFactory() | ||
: ProfileKeyedServiceFactory( | ||
"StorageAccessAPIService", | ||
ProfileSelections::Builder() | ||
.WithRegular(ProfileSelection::kOwnInstance) | ||
.WithGuest(ProfileSelection::kOwnInstance) | ||
.WithSystem(ProfileSelection::kNone) | ||
.Build()) {} | ||
|
||
StorageAccessAPIServiceFactory::~StorageAccessAPIServiceFactory() = default; | ||
|
||
std::unique_ptr<KeyedService> | ||
StorageAccessAPIServiceFactory::BuildServiceInstanceForBrowserContext( | ||
content::BrowserContext* context) const { | ||
return std::make_unique<StorageAccessAPIServiceImpl>(context); | ||
} |
45 changes: 45 additions & 0 deletions
45
chrome/browser/storage_access_api/storage_access_api_service_factory.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_FACTORY_H_ | ||
#define CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_FACTORY_H_ | ||
|
||
#include "base/no_destructor.h" | ||
#include "chrome/browser/profiles/profile_keyed_service_factory.h" | ||
|
||
namespace content { | ||
class BrowserContext; | ||
} // namespace content | ||
|
||
class StorageAccessAPIServiceImpl; | ||
|
||
// Singleton that owns StorageAccessAPIServiceImpl objects and associates them | ||
// with corresponding Profiles. | ||
// | ||
// Listens for each Profile's destruction notification and cleans up the | ||
// associated StorageAccessAPIServiceImpl. | ||
class StorageAccessAPIServiceFactory : public ProfileKeyedServiceFactory { | ||
public: | ||
StorageAccessAPIServiceFactory(const StorageAccessAPIServiceFactory&) = | ||
delete; | ||
StorageAccessAPIServiceFactory& operator=( | ||
const StorageAccessAPIServiceFactory&) = delete; | ||
|
||
static StorageAccessAPIServiceImpl* GetForBrowserContext( | ||
content::BrowserContext* context); | ||
|
||
static StorageAccessAPIServiceFactory* GetInstance(); | ||
|
||
private: | ||
friend base::NoDestructor<StorageAccessAPIServiceFactory>; | ||
|
||
StorageAccessAPIServiceFactory(); | ||
~StorageAccessAPIServiceFactory() override; | ||
|
||
// BrowserContextKeyedServiceFactory: | ||
std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( | ||
content::BrowserContext* context) const override; | ||
}; | ||
|
||
#endif // CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_FACTORY_H_ |
54 changes: 54 additions & 0 deletions
54
chrome/browser/storage_access_api/storage_access_api_service_factory_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/storage_access_api/storage_access_api_service_factory.h" | ||
|
||
#include "base/memory/raw_ptr.h" | ||
#include "chrome/browser/storage_access_api/storage_access_api_service_impl.h" | ||
#include "chrome/test/base/testing_browser_process.h" | ||
#include "chrome/test/base/testing_profile.h" | ||
#include "chrome/test/base/testing_profile_manager.h" | ||
#include "content/public/test/browser_task_environment.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
class StorageAccessAPIServiceFactoryTest : public testing::Test { | ||
public: | ||
StorageAccessAPIServiceFactoryTest() = default; | ||
|
||
void SetUp() override { | ||
ASSERT_TRUE(profile_manager_.SetUp()); | ||
profile_ = profile_manager_.CreateTestingProfile("Profile"); | ||
} | ||
|
||
void TearDown() override { profile_manager_.DeleteAllTestingProfiles(); } | ||
|
||
TestingProfile* profile() { return profile_; } | ||
|
||
private: | ||
content::BrowserTaskEnvironment env_; | ||
TestingProfileManager profile_manager_ = | ||
TestingProfileManager(TestingBrowserProcess::GetGlobal()); | ||
raw_ptr<TestingProfile> profile_ = nullptr; | ||
}; | ||
|
||
TEST_F(StorageAccessAPIServiceFactoryTest, RegularProfile_ServiceCreated) { | ||
EXPECT_NE(nullptr, | ||
StorageAccessAPIServiceFactory::GetForBrowserContext(profile())); | ||
} | ||
|
||
TEST_F(StorageAccessAPIServiceFactoryTest, OffTheRecordProfile_OwnInstance) { | ||
StorageAccessAPIServiceImpl* original_service = | ||
StorageAccessAPIServiceFactory::GetForBrowserContext( | ||
profile()->GetOriginalProfile()); | ||
|
||
ASSERT_NE(nullptr, original_service); | ||
|
||
auto otr_profile_id = Profile::OTRProfileID::CreateUniqueForTesting(); | ||
auto* otr_service = StorageAccessAPIServiceFactory::GetForBrowserContext( | ||
profile()->GetOffTheRecordProfile(otr_profile_id, | ||
/*create_if_needed=*/true)); | ||
|
||
EXPECT_NE(nullptr, otr_service); | ||
EXPECT_NE(original_service, otr_service); | ||
} |
27 changes: 27 additions & 0 deletions
27
chrome/browser/storage_access_api/storage_access_api_service_impl.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include <utility> | ||
|
||
#include "chrome/browser/storage_access_api/storage_access_api_service_impl.h" | ||
|
||
StorageAccessAPIServiceImpl::StorageAccessAPIServiceImpl( | ||
content::BrowserContext* browser_context) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
CHECK(browser_context); | ||
} | ||
|
||
StorageAccessAPIServiceImpl::~StorageAccessAPIServiceImpl() = default; | ||
|
||
void StorageAccessAPIServiceImpl::RenewPermissionGrant( | ||
const url::Origin& embedded_origin, | ||
const url::Origin& top_frame_origin) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
|
||
// TODO(https://crbug.com/1450356): implement grant renewal. | ||
} | ||
|
||
void StorageAccessAPIServiceImpl::Shutdown() { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
} |
44 changes: 44 additions & 0 deletions
44
chrome/browser/storage_access_api/storage_access_api_service_impl.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_IMPL_H_ | ||
#define CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_IMPL_H_ | ||
|
||
#include "base/sequence_checker.h" | ||
#include "chrome/browser/storage_access_api/storage_access_api_service.h" | ||
#include "components/keyed_service/core/keyed_service.h" | ||
|
||
namespace content { | ||
class BrowserContext; | ||
} // namespace content | ||
|
||
namespace url { | ||
class Origin; | ||
} // namespace url | ||
|
||
// A profile keyed service for Storage Access API state. | ||
// | ||
// This service always exists for a Profile, regardless of whether the Storage | ||
// Access API feature is enabled. | ||
class StorageAccessAPIServiceImpl : public StorageAccessAPIService, | ||
public KeyedService { | ||
public: | ||
explicit StorageAccessAPIServiceImpl(content::BrowserContext* context); | ||
StorageAccessAPIServiceImpl(const StorageAccessAPIServiceImpl&) = delete; | ||
StorageAccessAPIServiceImpl& operator=(const StorageAccessAPIServiceImpl&) = | ||
delete; | ||
~StorageAccessAPIServiceImpl() override; | ||
|
||
// StorageAccessAPIService: | ||
void RenewPermissionGrant(const url::Origin& embedded_origin, | ||
const url::Origin& top_frame_origin) override; | ||
|
||
// KeyedService: | ||
void Shutdown() override; | ||
|
||
private: | ||
SEQUENCE_CHECKER(sequence_checker_); | ||
}; | ||
|
||
#endif // CHROME_BROWSER_STORAGE_ACCESS_API_STORAGE_ACCESS_API_SERVICE_IMPL_H_ |
58 changes: 58 additions & 0 deletions
58
chrome/browser/storage_access_api/storage_access_api_service_impl_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/storage_access_api/storage_access_api_service_impl.h" | ||
|
||
#include "base/memory/raw_ptr.h" | ||
#include "chrome/browser/storage_access_api/storage_access_api_service_factory.h" | ||
#include "chrome/test/base/testing_browser_process.h" | ||
#include "chrome/test/base/testing_profile.h" | ||
#include "chrome/test/base/testing_profile_manager.h" | ||
#include "content/public/test/browser_task_environment.h" | ||
#include "testing/gmock/include/gmock/gmock.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
class StorageAccessAPIServiceImplTest : public testing::Test { | ||
public: | ||
StorageAccessAPIServiceImplTest() = default; | ||
|
||
void SetUp() override { | ||
profile_manager_ = std::make_unique<TestingProfileManager>( | ||
TestingBrowserProcess::GetGlobal()); | ||
ASSERT_TRUE(profile_manager_->SetUp()); | ||
profile_ = profile_manager_->CreateTestingProfile("TestProfile"); | ||
service_ = StorageAccessAPIServiceFactory::GetForBrowserContext(profile_); | ||
ASSERT_NE(service_, nullptr); | ||
} | ||
|
||
void TearDown() override { | ||
DCHECK(service_); | ||
// Even though we reassign this in SetUp, service may be persisted between | ||
// tests if the factory has already created a service for the testing | ||
// profile being used. | ||
profile_manager_->DeleteAllTestingProfiles(); | ||
profile_manager_.reset(); | ||
} | ||
|
||
content::BrowserTaskEnvironment& env() { return env_; } | ||
|
||
protected: | ||
Profile* profile() { return profile_; } | ||
StorageAccessAPIServiceImpl* service() { return service_; } | ||
|
||
private: | ||
content::BrowserTaskEnvironment env_; | ||
std::unique_ptr<TestingProfileManager> profile_manager_; | ||
raw_ptr<Profile> profile_; | ||
raw_ptr<StorageAccessAPIServiceImpl> service_; | ||
}; | ||
|
||
TEST_F(StorageAccessAPIServiceImplTest, RenewPermissionGrant) { | ||
StorageAccessAPIServiceImpl* service = | ||
StorageAccessAPIServiceFactory::GetForBrowserContext(profile()); | ||
|
||
ASSERT_NE(nullptr, service); | ||
|
||
// TODO(https://crbug.com/1450356): test grant renewal. | ||
} |
40 changes: 40 additions & 0 deletions
40
chrome/browser/storage_access_api/storage_access_api_tab_helper.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/storage_access_api/storage_access_api_tab_helper.h" | ||
|
||
#include "chrome/browser/storage_access_api/storage_access_api_service.h" | ||
#include "chrome/browser/storage_access_api/storage_access_api_service_factory.h" | ||
#include "content/public/browser/render_frame_host.h" | ||
#include "content/public/browser/web_contents_observer.h" | ||
#include "content/public/browser/web_contents_user_data.h" | ||
|
||
StorageAccessAPITabHelper::~StorageAccessAPITabHelper() = default; | ||
|
||
void StorageAccessAPITabHelper::FrameReceivedUserActivation( | ||
content::RenderFrameHost* rfh) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
CHECK(service_); | ||
|
||
if (rfh->IsInPrimaryMainFrame()) { | ||
// No need to do anything in a main frame. | ||
return; | ||
} | ||
|
||
service_->RenewPermissionGrant( | ||
rfh->GetLastCommittedOrigin(), | ||
rfh->GetParentOrOuterDocument()->GetLastCommittedOrigin()); | ||
} | ||
|
||
StorageAccessAPITabHelper::StorageAccessAPITabHelper( | ||
content::WebContents* web_contents, | ||
StorageAccessAPIService* service) | ||
: content::WebContentsObserver(web_contents), | ||
content::WebContentsUserData<StorageAccessAPITabHelper>(*web_contents), | ||
service_(service) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
CHECK(service_); | ||
} | ||
|
||
WEB_CONTENTS_USER_DATA_KEY_IMPL(StorageAccessAPITabHelper); |
Oops, something went wrong.