Commit 3b6b0e8b authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

weblayer: Factor out profile_disk_operations

Factor out code that manipulate profile directories into its own file,
to prepare for upcoming changes to now deleting profile data work.

There are some behavior changes:

The cache directory is created on the UI thread on ProfileImpl
construction, rather than lazily when first requested. Cache directory
is likely to be requested soon after profile creation, so should not
affect performance much.

The cache directory is now empty for incognito. The return value is
never actually used for incognito profile, so this should not change
anything.

Bug: 1065585
Change-Id: I06f86235be34f1bc30247004b57cf9c3762248f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2140038
Commit-Queue: Bo <boliu@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#757901}
parent 75885564
......@@ -150,6 +150,8 @@ source_set("weblayer_lib_base") {
"browser/persistence/browser_persister.h",
"browser/persistence/minimal_browser_persister.cc",
"browser/persistence/minimal_browser_persister.h",
"browser/profile_disk_operations.cc",
"browser/profile_disk_operations.h",
"browser/profile_impl.cc",
"browser/profile_impl.h",
"browser/ssl_error_controller_client.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "weblayer/browser/profile_disk_operations.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "weblayer/common/weblayer_paths.h"
namespace weblayer {
namespace {
bool IsNameValid(const std::string& name) {
for (char c : name) {
if (!(base::IsAsciiDigit(c) || base::IsAsciiAlpha(c) || c == '_'))
return false;
}
return true;
}
// Return the data path directory to profiles.
base::FilePath GetProfileRootDataDir() {
base::FilePath path;
CHECK(base::PathService::Get(DIR_USER_DATA, &path));
return path.AppendASCII("profiles");
}
} // namespace
ProfileInfo CreateProfileInfo(const std::string& name) {
CHECK(IsNameValid(name));
if (name.empty())
return {name, base::FilePath(), base::FilePath()};
base::FilePath data_path = GetProfileRootDataDir().AppendASCII(name.c_str());
if (!base::PathExists(data_path))
base::CreateDirectory(data_path);
base::FilePath cache_path = data_path;
#if defined(OS_POSIX)
CHECK(base::PathService::Get(base::DIR_CACHE, &cache_path));
cache_path = cache_path.AppendASCII("profiles").AppendASCII(name.c_str());
if (!base::PathExists(cache_path))
base::CreateDirectory(cache_path);
#endif
return {name, data_path, cache_path};
}
base::FilePath ComputeBrowserPersisterDataBaseDir(const ProfileInfo& info) {
base::FilePath base_path;
if (info.data_path.empty()) {
CHECK(base::PathService::Get(DIR_USER_DATA, &base_path));
base_path = base_path.AppendASCII("Incognito Restore Data");
} else {
base_path = info.data_path.AppendASCII("Restore Data");
}
return base_path;
}
void NukeProfileFromDisk(const ProfileInfo& info) {
if (info.name.empty()) {
// Incognito. Just delete session data.
base::DeleteFileRecursively(ComputeBrowserPersisterDataBaseDir(info));
return;
}
base::DeleteFileRecursively(info.data_path);
#if defined(OS_POSIX)
base::DeleteFileRecursively(info.cache_path);
#endif
}
std::vector<std::string> ListProfileNames() {
base::FilePath root_dir = GetProfileRootDataDir();
std::vector<std::string> profile_names;
base::FileEnumerator enumerator(root_dir, /*recursive=*/false,
base::FileEnumerator::DIRECTORIES);
for (base::FilePath path = enumerator.Next(); !path.empty();
path = enumerator.Next()) {
std::string name = enumerator.GetInfo().GetName().MaybeAsASCII();
if (IsNameValid(name))
profile_names.push_back(name);
}
return profile_names;
}
} // namespace weblayer
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBLAYER_BROWSER_PROFILE_DISK_OPERATIONS_H_
#define WEBLAYER_BROWSER_PROFILE_DISK_OPERATIONS_H_
#include <string>
#include <vector>
#include "base/files/file_path.h"
namespace weblayer {
struct ProfileInfo {
// The profile name supplied by client code. Name can only contain
// alphanumeric and underscore to be valid. The empty name is valid and
// indicates the incognito profile.
std::string name;
// Path where persistent profile data is stored. This will be empty for the
// incognito profile with empty name.
base::FilePath data_path;
// Path where cache profile data is stored. Depending on the OS, this may
// be the same as |data_path|; the OS may delete data in this directory.
base::FilePath cache_path;
};
// |name| must be a valid profile name. Ensures that both data and cache path
// directories are created.
ProfileInfo CreateProfileInfo(const std::string& name);
base::FilePath ComputeBrowserPersisterDataBaseDir(const ProfileInfo& info);
void NukeProfileFromDisk(const ProfileInfo& info);
// Return names of profiles on disk. Invalid profile names are ignored.
std::vector<std::string> ListProfileNames();
} // namespace weblayer
#endif // WEBLAYER_BROWSER_PROFILE_DISK_OPERATIONS_H_
......@@ -11,10 +11,6 @@
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
......@@ -32,7 +28,6 @@
#include "weblayer/browser/browser_context_impl.h"
#include "weblayer/browser/cookie_manager_impl.h"
#include "weblayer/browser/tab_impl.h"
#include "weblayer/common/weblayer_paths.h"
#if defined(OS_ANDROID)
#include "base/android/callback_android.h"
......@@ -54,85 +49,14 @@ namespace weblayer {
namespace {
bool IsNameValid(const std::string& name) {
for (size_t i = 0; i < name.size(); ++i) {
char c = name[i];
if (!(base::IsAsciiDigit(c) || base::IsAsciiAlpha(c) || c == '_')) {
return false;
}
}
return true;
}
// Return the data path directory to profiles.
base::FilePath GetProfileRootDataDir() {
base::FilePath path;
CHECK(base::PathService::Get(DIR_USER_DATA, &path));
return path.AppendASCII("profiles");
}
#if defined(OS_POSIX)
base::FilePath ComputeCachePath(const std::string& profile_name) {
base::FilePath path;
CHECK(base::PathService::Get(base::DIR_CACHE, &path));
return path.AppendASCII("profiles").AppendASCII(profile_name.c_str());
}
#endif // OS_POSIX
base::FilePath ComputeBrowserPersisterDataBaseDir(
const base::FilePath& data_path) {
base::FilePath base_path;
if (data_path.empty()) {
CHECK(base::PathService::Get(DIR_USER_DATA, &base_path));
base_path = base_path.AppendASCII("Incognito Restore Data");
} else {
base_path = data_path.AppendASCII("Restore Data");
}
return base_path;
}
void NukeProfileFromDisk(const std::string& profile_name,
const base::FilePath& data_path) {
if (data_path.empty()) {
// Incognito. Just delete session data.
base::DeleteFileRecursively(ComputeBrowserPersisterDataBaseDir(data_path));
return;
}
base::DeleteFileRecursively(data_path);
#if defined(OS_POSIX)
base::DeleteFileRecursively(ComputeCachePath(profile_name));
#endif
}
#if defined(OS_ANDROID)
// Returned path only contains the directory name.
// Invalid profile names are ignored.
std::vector<base::FilePath> ListProfileNames() {
base::FilePath root_dir = GetProfileRootDataDir();
std::vector<base::FilePath> profile_names;
base::FileEnumerator enumerator(root_dir, /*recursive=*/false,
base::FileEnumerator::DIRECTORIES);
for (base::FilePath path = enumerator.Next(); !path.empty();
path = enumerator.Next()) {
base::FilePath name = enumerator.GetInfo().GetName();
if (IsNameValid(name.MaybeAsASCII())) {
profile_names.push_back(name);
}
}
return profile_names;
}
void PassFilePathsToJavaCallback(
const base::android::ScopedJavaGlobalRef<jobject>& callback,
const std::vector<base::FilePath>& file_paths) {
std::vector<std::string> strings;
for (const auto& path : file_paths) {
strings.push_back(path.value());
}
const std::vector<std::string>& file_paths) {
base::android::RunObjectCallbackAndroid(
callback, base::android::ToJavaArrayOfStrings(
base::android::AttachCurrentThread(), strings));
base::android::AttachCurrentThread(), file_paths));
}
#endif // OS_ANDROID
......@@ -171,33 +95,15 @@ class ProfileImpl::DataClearer : public content::BrowsingDataRemover::Observer {
base::FilePath ProfileImpl::GetCachePath(content::BrowserContext* context) {
DCHECK(context);
ProfileImpl* profile = FromBrowserContext(context);
#if defined(OS_POSIX)
base::FilePath path = ComputeCachePath(profile->name_);
{
base::ScopedAllowBlocking allow_blocking;
if (!base::PathExists(path))
base::CreateDirectory(path);
}
return path;
#else
return profile->data_path_;
#endif
return profile->info_.cache_path;
}
ProfileImpl::ProfileImpl(const std::string& name)
: name_(name),
download_directory_(BrowserContextImpl::GetDefaultDownloadDirectory()) {
if (!name.empty()) {
CHECK(IsNameValid(name));
{
base::ScopedAllowBlocking allow_blocking;
data_path_ = GetProfileRootDataDir().AppendASCII(name.c_str());
if (!base::PathExists(data_path_))
base::CreateDirectory(data_path_);
}
: download_directory_(BrowserContextImpl::GetDefaultDownloadDirectory()) {
{
base::ScopedAllowBlocking allow_blocking;
info_ = CreateProfileInfo(name);
}
// Ensure WebCacheManager is created so that it starts observing
// OnRenderProcessHostCreated events.
web_cache::WebCacheManager::GetInstance();
......@@ -218,7 +124,8 @@ content::BrowserContext* ProfileImpl::GetBrowserContext() {
if (browser_context_)
return browser_context_.get();
browser_context_ = std::make_unique<BrowserContextImpl>(this, data_path_);
browser_context_ =
std::make_unique<BrowserContextImpl>(this, info_.data_path);
locale_change_subscription_ =
i18n::RegisterLocaleChangeCallback(base::BindRepeating(
&ProfileImpl::OnLocaleChanged, base::Unretained(this)));
......@@ -290,16 +197,14 @@ void ProfileImpl::NukeDataAfterRemovingData(
// static
void ProfileImpl::DoNukeData(std::unique_ptr<ProfileImpl> profile,
base::OnceClosure done_callback) {
std::string name = profile->name_;
base::FilePath data_path = profile->data_path_;
ProfileInfo info = profile->info_;
profile.reset();
base::ThreadPool::PostTaskAndReply(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce(&NukeProfileFromDisk, name, data_path),
std::move(done_callback));
base::BindOnce(&NukeProfileFromDisk, info), std::move(done_callback));
}
void ProfileImpl::ClearRendererCache() {
......@@ -463,7 +368,7 @@ void ProfileImpl::DecrementBrowserImplCount() {
}
base::FilePath ProfileImpl::GetBrowserPersisterDataBaseDir() const {
return ComputeBrowserPersisterDataBaseDir(data_path_);
return ComputeBrowserPersisterDataBaseDir(info_);
}
} // namespace weblayer
......@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "weblayer/browser/i18n_util.h"
#include "weblayer/browser/profile_disk_operations.h"
#include "weblayer/public/profile.h"
#if defined(OS_ANDROID)
......@@ -53,7 +54,7 @@ class ProfileImpl : public Profile {
void DownloadsInitialized();
// Path data is stored at, empty if off-the-record.
const base::FilePath& data_path() const { return data_path_; }
const base::FilePath& data_path() const { return info_.data_path; }
DownloadDelegate* download_delegate() { return download_delegate_; }
// Profile implementation:
......@@ -107,9 +108,7 @@ class ProfileImpl : public Profile {
// Callback when the system locale has been updated.
void OnLocaleChanged();
const std::string name_;
base::FilePath data_path_;
ProfileInfo info_;
std::unique_ptr<BrowserContextImpl> browser_context_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment