| Index: components/arc/arc_bridge_bootstrap.cc
|
| diff --git a/components/arc/arc_bridge_bootstrap.cc b/components/arc/arc_bridge_bootstrap.cc
|
| index 77e15c42adb2ac02ae8a596d108ca3b0be1f95d6..e51ddf397d62b426b628cab64d8fcbab9b2d7d14 100644
|
| --- a/components/arc/arc_bridge_bootstrap.cc
|
| +++ b/components/arc/arc_bridge_bootstrap.cc
|
| @@ -73,11 +73,11 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap,
|
| // AcceptInstanceConnection() -> OnInstanceConnected() ->
|
| // READY
|
| //
|
| - // When Stop() is called from any state, either because an operation
|
| - // resulted in an error or because the user is logging out:
|
| + // When Stop() or AbortBoot() is called from any state, either because an
|
| + // operation resulted in an error or because the user is logging out:
|
| //
|
| // (any)
|
| - // Stop() ->
|
| + // Stop()/AbortBoot() ->
|
| // STOPPING
|
| // StopInstance() ->
|
| // STOPPED
|
| @@ -86,6 +86,9 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap,
|
| // READY -> STOPPING -> STOPPED
|
| // and then restarted:
|
| // STOPPED -> SOCKET_CREATING -> ... -> READY).
|
| + //
|
| + // Note: Order of constants below matters. Please make sure to sort them
|
| + // in chronological order.
|
| enum class State {
|
| // ARC is not currently running.
|
| STOPPED,
|
| @@ -114,6 +117,10 @@ class ArcBridgeBootstrapImpl : public ArcBridgeBootstrap,
|
| void Stop() override;
|
|
|
| private:
|
| + // Aborts ARC instance boot. This is called from various state-machine
|
| + // functions when they encounter an error during boot.
|
| + void AbortBoot(AbortReason reason);
|
| +
|
| // Creates the UNIX socket on the bootstrap thread and then processes its
|
| // file descriptor.
|
| static base::ScopedFD CreateSocket();
|
| @@ -236,7 +243,7 @@ void ArcBridgeBootstrapImpl::OnSocketCreated(base::ScopedFD socket_fd) {
|
|
|
| if (!socket_fd.is_valid()) {
|
| LOG(ERROR) << "ARC: Error creating socket";
|
| - Stop();
|
| + AbortBoot(AbortReason::GENERIC_BOOT_FAILURE);
|
| return;
|
| }
|
|
|
| @@ -261,7 +268,7 @@ void ArcBridgeBootstrapImpl::OnInstanceStarted(base::ScopedFD socket_fd,
|
| // Roll back the state to SOCKET_CREATING to avoid sending the D-Bus signal
|
| // to stop the failed instance.
|
| SetState(State::SOCKET_CREATING);
|
| - Stop();
|
| + AbortBoot(AbortReason::GENERIC_BOOT_FAILURE);
|
| return;
|
| }
|
| if (state_ != State::STARTING) {
|
| @@ -318,12 +325,14 @@ void ArcBridgeBootstrapImpl::OnInstanceConnected(base::ScopedFD fd) {
|
| }
|
| if (!fd.is_valid()) {
|
| LOG(ERROR) << "Invalid handle";
|
| + AbortBoot(AbortReason::GENERIC_BOOT_FAILURE);
|
| return;
|
| }
|
| mojo::ScopedMessagePipeHandle server_pipe = mojo::edk::CreateMessagePipe(
|
| mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(fd.release())));
|
| if (!server_pipe.is_valid()) {
|
| LOG(ERROR) << "Invalid pipe";
|
| + AbortBoot(AbortReason::GENERIC_BOOT_FAILURE);
|
| return;
|
| }
|
| SetState(State::READY);
|
| @@ -339,11 +348,10 @@ void ArcBridgeBootstrapImpl::Stop() {
|
| VLOG(1) << "Stop() called when ARC is not running";
|
| return;
|
| }
|
| - if (state_ == State::SOCKET_CREATING) {
|
| + if (state_ < State::STARTING) {
|
| // This was stopped before the D-Bus command to start the instance. Skip
|
| // the D-Bus command to stop it.
|
| - SetState(State::STOPPING);
|
| - ArcInstanceStopped(true);
|
| + SetState(State::STOPPED);
|
| return;
|
| }
|
| SetState(State::STOPPING);
|
| @@ -354,13 +362,21 @@ void ArcBridgeBootstrapImpl::Stop() {
|
| base::Bind(&DoNothingInstanceStopped));
|
| }
|
|
|
| +void ArcBridgeBootstrapImpl::AbortBoot(AbortReason reason) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(delegate_);
|
| + delegate_->OnAborting(reason);
|
| + Stop();
|
| +}
|
| +
|
| void ArcBridgeBootstrapImpl::ArcInstanceStopped(bool clean) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (!clean)
|
| + if (!clean) {
|
| LOG(ERROR) << "ARC instance crashed";
|
| - DCHECK(delegate_);
|
| + DCHECK(delegate_);
|
| + delegate_->OnAborting(AbortReason::CRASH);
|
| + }
|
| SetState(State::STOPPED);
|
| - delegate_->OnStopped();
|
| }
|
|
|
| void ArcBridgeBootstrapImpl::SetState(State state) {
|
| @@ -369,6 +385,10 @@ void ArcBridgeBootstrapImpl::SetState(State state) {
|
| DCHECK(state_ != state);
|
| state_ = state;
|
| VLOG(2) << "State: " << static_cast<uint32_t>(state_);
|
| + if (state_ == State::STOPPED) {
|
| + DCHECK(delegate_);
|
| + delegate_->OnStopped();
|
| + }
|
| }
|
|
|
| } // namespace
|
|
|