| Index: components/arc/arc_bridge_service_impl.cc
|
| diff --git a/components/arc/arc_bridge_service_impl.cc b/components/arc/arc_bridge_service_impl.cc
|
| index 3205cfe554abf92fd726c002a8289ec3f87ada58..d276e61abfa96631a3b7edaa1a714374e9e4c082 100644
|
| --- a/components/arc/arc_bridge_service_impl.cc
|
| +++ b/components/arc/arc_bridge_service_impl.cc
|
| @@ -4,22 +4,10 @@
|
|
|
| #include "components/arc/arc_bridge_service_impl.h"
|
|
|
| -#include <string>
|
| -#include <utility>
|
| -
|
| -#include "base/command_line.h"
|
| -#include "base/json/json_writer.h"
|
| -#include "base/sequenced_task_runner.h"
|
| -#include "base/sys_info.h"
|
| -#include "base/task_runner_util.h"
|
| -#include "base/threading/thread_task_runner_handle.h"
|
| -#include "base/time/time.h"
|
| -#include "chromeos/chromeos_switches.h"
|
| -#include "chromeos/dbus/dbus_method_call_status.h"
|
| -#include "chromeos/dbus/dbus_thread_manager.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/task_runner.h"
|
| #include "components/arc/arc_session.h"
|
| -#include "components/prefs/pref_registry_simple.h"
|
| -#include "components/prefs/pref_service.h"
|
|
|
| namespace arc {
|
|
|
| @@ -32,39 +20,78 @@ constexpr base::TimeDelta kDefaultRestartDelay =
|
|
|
| ArcBridgeServiceImpl::ArcBridgeServiceImpl(
|
| const scoped_refptr<base::TaskRunner>& blocking_task_runner)
|
| - : session_started_(false),
|
| - restart_delay_(kDefaultRestartDelay),
|
| + : restart_delay_(kDefaultRestartDelay),
|
| factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)),
|
| - weak_factory_(this) {}
|
| + weak_ptr_factory_(this) {}
|
|
|
| ArcBridgeServiceImpl::~ArcBridgeServiceImpl() {
|
| + DCHECK(CalledOnValidThread());
|
| if (arc_session_)
|
| arc_session_->RemoveObserver(this);
|
| }
|
|
|
| void ArcBridgeServiceImpl::RequestStart() {
|
| DCHECK(CalledOnValidThread());
|
| - if (session_started_)
|
| +
|
| + // Consecutive RequestStart() call. Do nothing.
|
| + if (run_requested_)
|
| return;
|
| +
|
| VLOG(1) << "Session started";
|
| - session_started_ = true;
|
| - PrerequisitesChanged();
|
| + run_requested_ = true;
|
| + // Here |run_requested_| transitions from false to true. So, |restart_timer_|
|
| + // must be stopped (either not even started, or has been cancelled in
|
| + // previous RequestStop() call).
|
| + DCHECK(!restart_timer_.IsRunning());
|
| +
|
| + if (arc_session_) {
|
| + // In this case, RequestStop() was called, and before |arc_session_| had
|
| + // finished stopping, RequestStart() was called. Do nothing in that case,
|
| + // since when |arc_session_| does actually stop, OnSessionStopped() will
|
| + // be called, where it should automatically restart.
|
| + DCHECK_EQ(state(), State::STOPPING);
|
| + } else {
|
| + DCHECK_EQ(state(), State::STOPPED);
|
| + StartArcSession();
|
| + }
|
| }
|
|
|
| void ArcBridgeServiceImpl::RequestStop() {
|
| DCHECK(CalledOnValidThread());
|
| - if (!session_started_)
|
| +
|
| + // Consecutive RequestStop() call. Do nothing.
|
| + if (!run_requested_)
|
| return;
|
| +
|
| VLOG(1) << "Session ended";
|
| - session_started_ = false;
|
| - PrerequisitesChanged();
|
| + run_requested_ = false;
|
| +
|
| + if (arc_session_) {
|
| + // The |state_| could be either STARTING, RUNNING or STOPPING.
|
| + DCHECK_NE(state(), State::STOPPED);
|
| +
|
| + if (state() == State::STOPPING) {
|
| + // STOPPING is found in the senario of "RequestStart() -> RequestStop()
|
| + // -> RequestStart() -> RequestStop()" case.
|
| + // In the first RequestStop() call, |state_| is set to STOPPING,
|
| + // and in the second RequestStop() finds it (so this is the second call).
|
| + // In that case, ArcSession::Stop() is already called, so do nothing.
|
| + return;
|
| + }
|
| + SetState(State::STOPPING);
|
| + arc_session_->Stop();
|
| + } else {
|
| + DCHECK_EQ(state(), State::STOPPED);
|
| + // In case restarting is in progress, cancel it.
|
| + restart_timer_.Stop();
|
| + }
|
| }
|
|
|
| void ArcBridgeServiceImpl::OnShutdown() {
|
| DCHECK(CalledOnValidThread());
|
|
|
| VLOG(1) << "OnShutdown";
|
| - session_started_ = false;
|
| + run_requested_ = false;
|
| restart_timer_.Stop();
|
| if (arc_session_) {
|
| if (state() != State::STOPPING)
|
| @@ -79,6 +106,9 @@ void ArcBridgeServiceImpl::OnShutdown() {
|
| void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting(
|
| const ArcSessionFactory& factory) {
|
| DCHECK(!factory.is_null());
|
| + DCHECK_EQ(state(), State::STOPPED);
|
| + DCHECK(!arc_session_);
|
| + DCHECK(!restart_timer_.IsRunning());
|
| factory_ = factory;
|
| }
|
|
|
| @@ -90,29 +120,6 @@ void ArcBridgeServiceImpl::SetRestartDelayForTesting(
|
| restart_delay_ = restart_delay;
|
| }
|
|
|
| -void ArcBridgeServiceImpl::PrerequisitesChanged() {
|
| - DCHECK(CalledOnValidThread());
|
| - VLOG(1) << "Prerequisites changed. "
|
| - << "state=" << static_cast<uint32_t>(state())
|
| - << ", session_started=" << session_started_;
|
| - if (state() == State::STOPPED) {
|
| - if (!session_started_) {
|
| - // We were explicitly asked to stop, so do not restart.
|
| - restart_timer_.Stop();
|
| - return;
|
| - }
|
| - DCHECK(!restart_timer_.IsRunning());
|
| - VLOG(0) << "Prerequisites met, starting ARC";
|
| - StartArcSession();
|
| - } else {
|
| - DCHECK(!restart_timer_.IsRunning());
|
| - if (session_started_)
|
| - return;
|
| - VLOG(0) << "Prerequisites stopped being met, stopping ARC";
|
| - StopInstance();
|
| - }
|
| -}
|
| -
|
| void ArcBridgeServiceImpl::StartArcSession() {
|
| DCHECK(CalledOnValidThread());
|
| DCHECK_EQ(state(), State::STOPPED);
|
| @@ -123,60 +130,43 @@ void ArcBridgeServiceImpl::StartArcSession() {
|
| SetStopReason(StopReason::SHUTDOWN);
|
| arc_session_ = factory_.Run();
|
| arc_session_->AddObserver(this);
|
| - SetState(State::CONNECTING);
|
| + SetState(State::STARTING);
|
| arc_session_->Start();
|
| }
|
|
|
| -void ArcBridgeServiceImpl::StopInstance() {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_NE(state(), State::STOPPED);
|
| - DCHECK(!restart_timer_.IsRunning());
|
| -
|
| - if (state() == State::STOPPING) {
|
| - VLOG(1) << "StopInstance() called when ARC is not running";
|
| - return;
|
| - }
|
| -
|
| - VLOG(1) << "Stopping ARC";
|
| - DCHECK(arc_session_.get());
|
| - SetState(State::STOPPING);
|
| -
|
| - // Note: this can call OnStopped() internally as a callback.
|
| - arc_session_->Stop();
|
| -}
|
| -
|
| void ArcBridgeServiceImpl::OnSessionReady() {
|
| DCHECK(CalledOnValidThread());
|
| - if (state() != State::CONNECTING) {
|
| - VLOG(1) << "StopInstance() called while connecting";
|
| - return;
|
| - }
|
| + DCHECK_EQ(state(), State::STARTING);
|
| + DCHECK(arc_session_);
|
| + DCHECK(!restart_timer_.IsRunning());
|
|
|
| VLOG(0) << "ARC ready";
|
| - SetState(State::READY);
|
| + SetState(State::RUNNING);
|
| }
|
|
|
| void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
|
| DCHECK(CalledOnValidThread());
|
| + DCHECK_NE(state(), State::STOPPED);
|
| + DCHECK(arc_session_);
|
| DCHECK(!restart_timer_.IsRunning());
|
|
|
| VLOG(0) << "ARC stopped: " << stop_reason;
|
| arc_session_->RemoveObserver(this);
|
| arc_session_.reset();
|
|
|
| - // If READY, ARC instance unexpectedly crashed so we need to restart it
|
| + // If RUNNING, ARC instance unexpectedly crashed so we need to restart it
|
| // automatically.
|
| // If STOPPING, at least once RequestStop() is called. If |session_started_|
|
| // is true, RequestStart() is following so schedule to restart ARC session.
|
| // Otherwise, do nothing.
|
| - // If CONNECTING, ARC instance has not been booted properly, so do not
|
| + // If STARTING, ARC instance has not been booted properly, so do not
|
| // restart it automatically.
|
| - if (state() == State::READY ||
|
| - (state() == State::STOPPING && session_started_)) {
|
| - // This check is for READY case. In READY case |session_started_| should be
|
| - // always true, because if once RequestStop() is called, the state() will
|
| - // be set to STOPPING.
|
| - DCHECK(session_started_);
|
| + if (state() == State::RUNNING ||
|
| + (state() == State::STOPPING && run_requested_)) {
|
| + // This check is for READY case. In RUNNING case |run_requested_| should
|
| + // be always true, because if once RequestStop() is called, the state()
|
| + // will be set to STOPPING.
|
| + DCHECK(run_requested_);
|
|
|
| // There was a previous invocation and it crashed for some reason. Try
|
| // starting ARC instance later again.
|
| @@ -186,7 +176,7 @@ void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
|
| VLOG(0) << "ARC restarting";
|
| restart_timer_.Start(FROM_HERE, restart_delay_,
|
| base::Bind(&ArcBridgeServiceImpl::StartArcSession,
|
| - weak_factory_.GetWeakPtr()));
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| }
|
|
|
| // TODO(hidehiko): Consider to let observers know whether there is scheduled
|
|
|