Chromium Code Reviews| Index: components/arc/arc_bridge_bootstrap.cc |
| diff --git a/components/arc/arc_bridge_bootstrap.cc b/components/arc/arc_bridge_bootstrap.cc |
| index c9cafb21c37bc8eb7d66cd01da3edb1689bedc96..652bb68a6d606cece70c964b9e84ca6bdaa2e24b 100644 |
| --- a/components/arc/arc_bridge_bootstrap.cc |
| +++ b/components/arc/arc_bridge_bootstrap.cc |
| @@ -21,6 +21,7 @@ |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "base/threading/worker_pool.h" |
| #include "chromeos/cryptohome/cryptohome_parameters.h" |
| +#include "chromeos/dbus/cryptohome_client.h" |
| #include "chromeos/dbus/dbus_method_call_status.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "chromeos/dbus/session_manager_client.h" |
| @@ -42,6 +43,8 @@ const base::FilePath::CharType kArcBridgeSocketPath[] = |
| const char kArcBridgeSocketGroup[] = "arc-bridge"; |
| +const uint64_t kCriticalDiskFreeBytes = 64 << 20; // 64MB |
| + |
| // This is called when StopArcInstance D-Bus method completes. Since we have the |
| // ArcInstanceStopped() callback and are notified if StartArcInstance fails, we |
| // don't need to do anything when StopArcInstance completes. |
| @@ -65,6 +68,8 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap, |
| // |
| // STOPPED |
| // Start() -> |
| + // DISK_SPACE_CHECKING |
| + // CheckDiskSpace() -> OnDiskSpaceChecked() -> |
| // SOCKET_CREATING |
| // CreateSocket() -> OnSocketCreated() -> |
| // STARTING |
| @@ -85,7 +90,7 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap, |
| // When the instance crashes while it was ready, it will be stopped: |
| // READY -> STOPPING -> STOPPED |
| // and then restarted: |
| - // STOPPED -> SOCKET_CREATING -> ... -> READY). |
| + // STOPPED -> DISK_SPACE_CHECKING -> ... -> READY). |
| // |
| // Note: Order of constants below matters. Please make sure to sort them |
| // in chronological order. |
| @@ -93,6 +98,9 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap, |
| // ARC is not currently running. |
| STOPPED, |
| + // Checking the disk space. |
| + DISK_SPACE_CHECKING, |
| + |
| // An UNIX socket is being created. |
| SOCKET_CREATING, |
| @@ -121,6 +129,10 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap, |
| // functions when they encounter an error during boot. |
| void AbortBoot(ArcBridgeService::StopReason reason); |
| + // Called after checking the device disk space. |
| + void OnDiskSpaceChecked(chromeos::DBusMethodCallStatus call_status, |
| + uint64_t disk_free_bytes); |
| + |
| // Creates the UNIX socket on the bootstrap thread and then processes its |
| // file descriptor. |
| static base::ScopedFD CreateSocket(); |
| @@ -180,6 +192,29 @@ void ArcBridgeBootstrapImpl::Start() { |
| return; |
| } |
| stop_reason_ = ArcBridgeService::StopReason::SHUTDOWN; |
| + // TODO(crbug.com/628124): Move disk space checking logic to session_manager |
| + // to avoid extra D-Bus method call cost. |
| + SetState(State::DISK_SPACE_CHECKING); |
| + chromeos::CryptohomeClient* cryptohome_client = |
| + chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); |
| + cryptohome_client->GetFreeDiskSpace(base::Bind( |
| + &ArcBridgeBootstrapImpl::OnDiskSpaceChecked, weak_factory_.GetWeakPtr())); |
| +} |
| + |
| +void ArcBridgeBootstrapImpl::OnDiskSpaceChecked( |
| + chromeos::DBusMethodCallStatus call_status, |
| + uint64_t disk_free_bytes) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
|
hidehiko
2016/07/14 14:10:26
Could you check if Stop() is called between start(
Shuhei Takahashi
2016/07/15 06:06:09
Done.
|
| + if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) { |
| + LOG(ERROR) << "ARC: Failed to check free disk space."; |
| + AbortBoot(ArcBridgeService::StopReason::GENERIC_BOOT_FAILURE); |
| + return; |
| + } |
| + if (disk_free_bytes < kCriticalDiskFreeBytes) { |
| + LOG(ERROR) << "ARC: The device is too low on disk space to start ARC"; |
| + AbortBoot(ArcBridgeService::StopReason::LOW_DISK_SPACE); |
| + return; |
| + } |
| SetState(State::SOCKET_CREATING); |
| base::PostTaskAndReplyWithResult( |
| base::WorkerPool::GetTaskRunner(true).get(), FROM_HERE, |