Skip to content

Commit

Permalink
Implement ipfs service in browser process
Browse files Browse the repository at this point in the history
  • Loading branch information
yrliou committed Jun 30, 2020
1 parent b493e5f commit 6eb0166
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 24 deletions.
3 changes: 3 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ By installing this extension, you are agreeing to the Google Widevine Terms of U
<message name="IDS_UTILITY_PROCESS_LEDGER_NAME" desc="The utility process running ledger">
Bat Ledger Service
</message>
<message name="IDS_UTILITY_PROCESS_IPFS_NAME" desc="The utility process which manages IPFS daemon">
IPFS Service
</message>
<message name="IDS_SETTINGS_BRAVE_GET_STARTED_TITLE" desc="The title for the Get Started section in settings">
Get started
</message>
Expand Down
9 changes: 9 additions & 0 deletions browser/browser_context_keyed_service_factories.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "brave/browser/search_engines/search_engine_tracker.h"
#include "brave/browser/tor/tor_profile_service_factory.h"
#include "brave/components/brave_ads/browser/ads_service_factory.h"
#include "brave/components/ipfs/browser/buildflags/buildflags.h"
#include "brave/browser/brave_rewards/rewards_service_factory.h"
#include "brave/components/greaselion/browser/buildflags/buildflags.h"
#include "brave/browser/ntp_background_images/view_counter_service_factory.h"
Expand All @@ -30,6 +31,10 @@
#include "brave/browser/brave_wallet/brave_wallet_service_factory.h"
#endif

#if BUILDFLAG(IPFS_ENABLED)
#include "brave/browser/ipfs/ipfs_service_factory.h"
#endif

namespace brave {

void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
Expand All @@ -54,6 +59,10 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
#if BUILDFLAG(BRAVE_WALLET_ENABLED)
BraveWalletServiceFactory::GetInstance();
#endif

#if BUILDFLAG(IPFS_ENABLED)
ipfs::IpfsServiceFactory::GetInstance();
#endif
}

} // namespace brave
4 changes: 4 additions & 0 deletions browser/ipfs/ipfs_service_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "chrome/browser/profiles/profile.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"

namespace ipfs {

// static
IpfsServiceFactory* IpfsServiceFactory::GetInstance() {
return base::Singleton<IpfsServiceFactory>::get();
Expand Down Expand Up @@ -39,3 +41,5 @@ content::BrowserContext* IpfsServiceFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
return chrome::GetBrowserContextRedirectedInIncognito(context);
}

} // namespace ipfs
5 changes: 4 additions & 1 deletion browser/ipfs/ipfs_service_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"

class IpfsService;
class Profile;
namespace ipfs {
class IpfsService;

class IpfsServiceFactory : public BrowserContextKeyedServiceFactory {
public:
Expand All @@ -32,4 +33,6 @@ class IpfsServiceFactory : public BrowserContextKeyedServiceFactory {
DISALLOW_COPY_AND_ASSIGN(IpfsServiceFactory);
};

} // namespace ipfs

#endif // BRAVE_BROWSER_IPFS_IPFS_SERVICE_FACTORY_H_
8 changes: 8 additions & 0 deletions browser/profiles/brave_profile_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "brave/components/brave_wallet/browser/buildflags/buildflags.h"
#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h"
#include "brave/components/ipfs/browser/buildflags/buildflags.h"
#include "brave/content/browser/webui/brave_shared_resources_data_source.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
Expand Down Expand Up @@ -61,6 +62,10 @@
#include "brave/browser/gcm_driver/brave_gcm_channel_status.h"
#endif

#if BUILDFLAG(IPFS_ENABLED)
#include "brave/browser/ipfs/ipfs_service_factory.h"
#endif

using content::BrowserThread;

BraveProfileManager::BraveProfileManager(const base::FilePath& user_data_dir)
Expand Down Expand Up @@ -148,6 +153,9 @@ void BraveProfileManager::DoFinalInitForServices(Profile* profile,
#if BUILDFLAG(BRAVE_WALLET_ENABLED)
BraveWalletServiceFactory::GetForProfile(profile);
#endif
#if BUILDFLAG(IPFS_ENABLED)
ipfs::IpfsServiceFactory::GetForProfile(profile);
#endif
#if !BUILDFLAG(USE_GCM_FROM_PLATFORM)
gcm::BraveGCMChannelStatus* status =
gcm::BraveGCMChannelStatus::GetForProfile(profile);
Expand Down
4 changes: 4 additions & 0 deletions components/ipfs/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ source_set("browser") {
]

deps = [
"//base",
"//brave/app:brave_generated_resources_grit",
"//chrome/common:constants",
"//content/public/browser",
"//third_party/re2",
]
}
58 changes: 41 additions & 17 deletions components/ipfs/browser/brave_ipfs_client_updater.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

Expand All @@ -8,6 +9,8 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "third_party/re2/src/re2/re2.h"

namespace ipfs {
Expand All @@ -17,11 +20,13 @@ std::string BraveIpfsClientUpdater::g_ipfs_client_component_id_(
std::string BraveIpfsClientUpdater::g_ipfs_client_component_base64_public_key_(
kIpfsClientComponentBase64PublicKey);

BraveIpfsClientUpdater::BraveIpfsClientUpdater(BraveComponent::Delegate* delegate)
BraveIpfsClientUpdater::BraveIpfsClientUpdater(
BraveComponent::Delegate* delegate)
: BraveComponent(delegate),
task_runner_(base::CreateSequencedTaskRunner(
{base::ThreadPool(), base::MayBlock()})),
registered_(false) {
registered_(false),
weak_ptr_factory_(this) {
}

BraveIpfsClientUpdater::~BraveIpfsClientUpdater() {
Expand All @@ -37,21 +42,18 @@ void BraveIpfsClientUpdater::Register() {
registered_ = true;
}

base::FilePath BraveIpfsClientUpdater::GetExecutablePath() const {
return executable_path_;
}
namespace {

void BraveIpfsClientUpdater::InitExecutablePath(
const base::FilePath& install_dir) {
base::FilePath InitExecutablePath(const base::FilePath& install_dir) {
base::FilePath executable_path;
base::FileEnumerator traversal(install_dir, false,
base::FileEnumerator::FILES,
FILE_PATH_LITERAL("ipfs-*"));
FILE_PATH_LITERAL("go-ipfs_v*"));
for (base::FilePath current = traversal.Next(); !current.empty();
current = traversal.Next()) {
base::FileEnumerator::FileInfo file_info = traversal.GetInfo();
if (!RE2::FullMatch(file_info.GetName().MaybeAsASCII(),
"ipfs-client"))
"go-ipfs_v\\d+\\.\\d+\\.\\d+\\_\\w+-amd64"))
continue;
executable_path = current;
break;
Expand All @@ -60,7 +62,7 @@ void BraveIpfsClientUpdater::InitExecutablePath(
if (executable_path.empty()) {
LOG(ERROR) << "Failed to locate Ipfs client executable in "
<< install_dir.value().c_str();
return;
return base::FilePath();
}

#if defined(OS_POSIX)
Expand All @@ -70,20 +72,42 @@ void BraveIpfsClientUpdater::InitExecutablePath(
if (!base::SetPosixFilePermissions(executable_path, 0755)) {
LOG(ERROR) << "Failed to set executable permission on "
<< executable_path.value().c_str();
return;
return base::FilePath();
}
#endif // defined(OS_POSIX)
#endif // defined(OS_POSIX)

return executable_path;
}

} // namespace

executable_path_ = executable_path;
void BraveIpfsClientUpdater::SetExecutablePath(const base::FilePath& path) {
executable_path_ = path;
for (Observer& observer : observers_)
observer.OnExecutableReady(path);
}

base::FilePath BraveIpfsClientUpdater::GetExecutablePath() const {
return executable_path_;
}

void BraveIpfsClientUpdater::OnComponentReady(
const std::string& component_id,
const base::FilePath& install_dir,
const std::string& manifest) {
GetTaskRunner()->PostTask(
FROM_HERE, base::Bind(&BraveIpfsClientUpdater::InitExecutablePath,
base::Unretained(this), install_dir));
base::PostTaskAndReplyWithResult(
GetTaskRunner().get(), FROM_HERE,
base::BindOnce(&InitExecutablePath, install_dir),
base::BindOnce(&BraveIpfsClientUpdater::SetExecutablePath,
weak_ptr_factory_.GetWeakPtr()));
}

void BraveIpfsClientUpdater::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}

void BraveIpfsClientUpdater::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}

// static
Expand Down
28 changes: 24 additions & 4 deletions components/ipfs/browser/brave_ipfs_client_updater.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMPONENTS_IPFS_BROWSER_BRAVE_IPFS_CLIENT_UPDATER_H_
#define BRAVE_COMPONENTS_IPFS_BROWSER_BRAVE_IPFS_CLIENT_UPDATER_H_

#include <memory>
#include <string>

#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/sequenced_task_runner.h"
#include "brave/components/brave_component_updater/browser/brave_component.h"

Expand Down Expand Up @@ -52,15 +58,26 @@ const std::string kIpfsClientComponentBase64PublicKey =

class BraveIpfsClientUpdater : public BraveComponent {
public:
BraveIpfsClientUpdater(BraveComponent::Delegate* delegate);
~BraveIpfsClientUpdater() override;
class Observer : public base::CheckedObserver {
public:
virtual void OnExecutableReady(const base::FilePath& path) = 0;

protected:
~Observer() override = default;
};

explicit BraveIpfsClientUpdater(BraveComponent::Delegate* delegate);
~BraveIpfsClientUpdater() override;

void Register();
base::FilePath GetExecutablePath() const;
scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() {
return task_runner_;
}

void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);

protected:
void OnComponentReady(const std::string& component_id,
const base::FilePath& install_dir,
Expand All @@ -74,10 +91,13 @@ class BraveIpfsClientUpdater : public BraveComponent {
static void SetComponentIdAndBase64PublicKeyForTest(
const std::string& component_id,
const std::string& component_base64_public_key);
void InitExecutablePath(const base::FilePath& install_dir);
void SetExecutablePath(const base::FilePath& path);

scoped_refptr<base::SequencedTaskRunner> task_runner_;
bool registered_;
base::FilePath executable_path_;
base::ObserverList<Observer> observers_;
base::WeakPtrFactory<BraveIpfsClientUpdater> weak_ptr_factory_;

DISALLOW_COPY_AND_ASSIGN(BraveIpfsClientUpdater);
};
Expand Down
90 changes: 90 additions & 0 deletions components/ipfs/browser/ipfs_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,95 @@

#include "brave/components/ipfs/browser/ipfs_service.h"

#include <utility>

#include "base/path_service.h"
#include "brave/browser/brave_browser_process_impl.h"
#include "brave/grit/brave_generated_resources.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/service_process_host.h"

namespace ipfs {

IpfsService::IpfsService(content::BrowserContext* context) {
g_brave_browser_process->ipfs_client_updater()->AddObserver(this);
OnExecutableReady(GetIpfsExecutablePath());
}

IpfsService::~IpfsService() = default;

base::FilePath IpfsService::GetIpfsExecutablePath() {
return g_brave_browser_process->ipfs_client_updater()->GetExecutablePath();
}

void IpfsService::OnExecutableReady(const base::FilePath& path) {
if (path.empty())
return;

g_brave_browser_process->ipfs_client_updater()->RemoveObserver(this);
LaunchIfNotRunning(path);
}

void IpfsService::LaunchIfNotRunning(const base::FilePath& executable_path) {
if (ipfs_service_.is_bound())
return;

content::ServiceProcessHost::Launch(
ipfs_service_.BindNewPipeAndPassReceiver(),
content::ServiceProcessHost::Options()
.WithDisplayName(IDS_UTILITY_PROCESS_IPFS_NAME)
.WithSandboxType(service_manager::SandboxType::kNoSandbox)
.Pass());

ipfs_service_.set_disconnect_handler(
base::BindOnce(
&IpfsService::OnIpfsCrashed,
base::Unretained(this)));

ipfs_service_->SetCrashHandler(
base::Bind(&IpfsService::OnIpfsDaemonCrashed,
base::Unretained(this)));

base::FilePath user_data_dir;
base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
DCHECK(!user_data_dir.empty());

base::FilePath data_root_path =
user_data_dir.Append(FILE_PATH_LITERAL("ipfs"));
base::FilePath config_path =
data_root_path.Append(FILE_PATH_LITERAL("config"));

auto config = mojom::IpfsConfig::New(
executable_path,
config_path,
data_root_path);

ipfs_service_->Launch(
std::move(config),
base::Bind(&IpfsService::OnIpfsLaunched,
base::Unretained(this)));
}

void IpfsService::OnIpfsCrashed() {
VLOG(0) << "IPFS utility process crashed";
Shutdown();
}

void IpfsService::OnIpfsDaemonCrashed(int64_t pid) {
VLOG(0) << "IPFS daemon crashed";
}

void IpfsService::OnIpfsLaunched(bool result, int64_t pid) {
if (result) {
ipfs_pid_ = pid;
} else {
VLOG(0) << "Failed to launch IPFS";
}
}

void IpfsService::Shutdown() {
ipfs_service_.reset();
ipfs_pid_ = -1;
}

} // namespace ipfs
Loading

0 comments on commit 6eb0166

Please sign in to comment.