// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "base/metrics/histogram_functions.h"
#import "base/metrics/user_metrics.h"
#import "base/notreached.h"
#import "base/task/sequenced_task_runner.h"
#import "components/keyed_service/ios/browser_state_dependency_manager.h"
#import "components/profile_metrics/browser_profile_type.h"
#import "components/proxy_config/ios/proxy_service_factory.h"
#import "components/proxy_config/pref_proxy_config_tracker.h"
#import "components/sync_preferences/pref_service_syncable.h"
#import "components/user_prefs/user_prefs.h"
#import "ios/chrome/browser/net/model/ios_chrome_url_request_context_getter.h"
#import "ios/chrome/browser/prefs/model/ios_chrome_pref_service_factory.h"
#import "ios/chrome/browser/profile/model/off_the_record_profile_ios_impl.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
OffTheRecordChromeBrowserStateImpl::OffTheRecordChromeBrowserStateImpl(
scoped_refptr<base::SequencedTaskRunner> io_task_runner,
ChromeBrowserState* original_chrome_browser_state,
const base::FilePath& otr_path)
: ChromeBrowserState(otr_path,
/*browser_state_name=*/std::string(),
std::move(io_task_runner)),
original_chrome_browser_state_(original_chrome_browser_state),
start_time_(base::Time::Now()),
prefs_(CreateIncognitoBrowserStatePrefs(
static_cast<sync_preferences::PrefServiceSyncable*>(
original_chrome_browser_state->GetPrefs()))) {
BrowserStateDependencyManager::GetInstance()->MarkBrowserStateLive(this);
user_prefs::UserPrefs::Set(this, GetPrefs());
io_data_.reset(new OffTheRecordProfileIOSIOData::Handle(this));
profile_metrics::SetBrowserProfileType(
this, profile_metrics::BrowserProfileType::kIncognito);
base::RecordAction(base::UserMetricsAction("IncognitoMode_Started"));
// DO NOT ADD ANY INITIALISATION AFTER THIS LINE.
// The initialisation of the ChromeBrowserState is now complete and the
// service can be safely created.
BrowserStateDependencyManager::GetInstance()->CreateBrowserStateServices(
this);
}
OffTheRecordChromeBrowserStateImpl::~OffTheRecordChromeBrowserStateImpl() {
BrowserStateDependencyManager::GetInstance()->DestroyBrowserStateServices(
this);
if (pref_proxy_config_tracker_) {
pref_proxy_config_tracker_->DetachFromPrefService();
}
const base::TimeDelta duration = base::Time::Now() - start_time_;
base::UmaHistogramCustomCounts("Profile.Incognito.Lifetime",
duration.InMinutes(), 1,
base::Days(28).InMinutes(), 100);
// Clears any data the network stack contains that may be related to the
// OTR session.
GetApplicationContext()->GetIOSChromeIOThread()->ChangedToOnTheRecord();
}
ChromeBrowserState*
OffTheRecordChromeBrowserStateImpl::GetOriginalChromeBrowserState() {
return original_chrome_browser_state_;
}
bool OffTheRecordChromeBrowserStateImpl::HasOffTheRecordChromeBrowserState()
const {
return true;
}
ChromeBrowserState*
OffTheRecordChromeBrowserStateImpl::GetOffTheRecordChromeBrowserState() {
return this;
}
void OffTheRecordChromeBrowserStateImpl::
DestroyOffTheRecordChromeBrowserState() {
NOTREACHED_IN_MIGRATION();
}
BrowserStatePolicyConnector*
OffTheRecordChromeBrowserStateImpl::GetPolicyConnector() {
// Forward the call to the original (non-OTR) browser state.
return GetOriginalChromeBrowserState()->GetPolicyConnector();
}
policy::UserCloudPolicyManager*
OffTheRecordChromeBrowserStateImpl::GetUserCloudPolicyManager() {
// Forward the call to the original (non-OTR) browser state.
return GetOriginalChromeBrowserState()->GetUserCloudPolicyManager();
}
sync_preferences::PrefServiceSyncable*
OffTheRecordChromeBrowserStateImpl::GetSyncablePrefs() {
return prefs_.get();
}
bool OffTheRecordChromeBrowserStateImpl::IsOffTheRecord() const {
return true;
}
PrefProxyConfigTracker*
OffTheRecordChromeBrowserStateImpl::GetProxyConfigTracker() {
if (!pref_proxy_config_tracker_) {
pref_proxy_config_tracker_ =
ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
GetPrefs(), GetApplicationContext()->GetLocalState());
}
return pref_proxy_config_tracker_.get();
}
ProfileIOSIOData* OffTheRecordChromeBrowserStateImpl::GetIOData() {
return io_data_->io_data();
}
net::URLRequestContextGetter*
OffTheRecordChromeBrowserStateImpl::CreateRequestContext(
ProtocolHandlerMap* protocol_handlers) {
return io_data_->CreateMainRequestContextGetter(protocol_handlers).get();
}
base::WeakPtr<ChromeBrowserState>
OffTheRecordChromeBrowserStateImpl::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void OffTheRecordChromeBrowserStateImpl::ClearNetworkingHistorySince(
base::Time time,
base::OnceClosure completion) {
// Nothing to do here, our transport security state is read-only.
// Still, fire the callback to indicate we have finished, otherwise the
// BrowsingDataRemover will never be destroyed and the dialog will never be
// closed. We must do this asynchronously in order to avoid reentrancy issues.
if (!completion.is_null()) {
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE, std::move(completion));
}
}