Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Unified Diff: components/arc/arc_bridge_service_impl.cc

Issue 2582003002: Refactor ArcBridgeServiceImpl part 1. (Closed)
Patch Set: Fix the latest bug. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/arc/arc_bridge_service_impl.h ('k') | components/arc/arc_bridge_service_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 fbc8f0b08218bc6e2312da5d545ddd5e12d23381..3205cfe554abf92fd726c002a8289ec3f87ada58 100644
--- a/components/arc/arc_bridge_service_impl.cc
+++ b/components/arc/arc_bridge_service_impl.cc
@@ -22,13 +22,18 @@
#include "components/prefs/pref_service.h"
namespace arc {
+
namespace {
-constexpr int64_t kReconnectDelayInSeconds = 5;
+
+constexpr base::TimeDelta kDefaultRestartDelay =
+ base::TimeDelta::FromSeconds(5);
+
} // namespace
ArcBridgeServiceImpl::ArcBridgeServiceImpl(
const scoped_refptr<base::TaskRunner>& blocking_task_runner)
: session_started_(false),
+ restart_delay_(kDefaultRestartDelay),
factory_(base::Bind(ArcSession::Create, this, blocking_task_runner)),
weak_factory_(this) {}
@@ -57,13 +62,18 @@ void ArcBridgeServiceImpl::RequestStop() {
void ArcBridgeServiceImpl::OnShutdown() {
DCHECK(CalledOnValidThread());
+
VLOG(1) << "OnShutdown";
- if (!session_started_)
- return;
session_started_ = false;
- reconnect_ = false;
- if (arc_session_)
+ restart_timer_.Stop();
+ if (arc_session_) {
+ if (state() != State::STOPPING)
+ SetState(State::STOPPING);
arc_session_->OnShutdown();
+ }
+ // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously.
+ // In the observer method, |arc_session_| should be destroyed.
+ DCHECK(!arc_session_);
}
void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting(
@@ -72,8 +82,12 @@ void ArcBridgeServiceImpl::SetArcSessionFactoryForTesting(
factory_ = factory;
}
-void ArcBridgeServiceImpl::DisableReconnectDelayForTesting() {
- use_delay_before_reconnecting_ = false;
+void ArcBridgeServiceImpl::SetRestartDelayForTesting(
+ const base::TimeDelta& restart_delay) {
+ DCHECK_EQ(state(), State::STOPPED);
+ DCHECK(!arc_session_);
+ DCHECK(!restart_timer_.IsRunning());
+ restart_delay_ = restart_delay;
}
void ArcBridgeServiceImpl::PrerequisitesChanged() {
@@ -82,19 +96,16 @@ void ArcBridgeServiceImpl::PrerequisitesChanged() {
<< "state=" << static_cast<uint32_t>(state())
<< ", session_started=" << session_started_;
if (state() == State::STOPPED) {
- if (!session_started_)
+ 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";
- SetStopReason(StopReason::SHUTDOWN);
-
- if (arc_session_)
- arc_session_->RemoveObserver(this);
-
- SetState(State::CONNECTING);
- arc_session_ = factory_.Run();
- arc_session_->AddObserver(this);
- arc_session_->Start();
+ StartArcSession();
} else {
+ DCHECK(!restart_timer_.IsRunning());
if (session_started_)
return;
VLOG(0) << "Prerequisites stopped being met, stopping ARC";
@@ -102,16 +113,30 @@ void ArcBridgeServiceImpl::PrerequisitesChanged() {
}
}
+void ArcBridgeServiceImpl::StartArcSession() {
+ DCHECK(CalledOnValidThread());
+ DCHECK_EQ(state(), State::STOPPED);
+ DCHECK(!arc_session_);
+ DCHECK(!restart_timer_.IsRunning());
+
+ VLOG(1) << "Starting ARC instance";
+ SetStopReason(StopReason::SHUTDOWN);
+ arc_session_ = factory_.Run();
+ arc_session_->AddObserver(this);
+ SetState(State::CONNECTING);
+ arc_session_->Start();
+}
+
void ArcBridgeServiceImpl::StopInstance() {
DCHECK(CalledOnValidThread());
- if (state() == State::STOPPED || state() == State::STOPPING) {
+ DCHECK_NE(state(), State::STOPPED);
+ DCHECK(!restart_timer_.IsRunning());
+
+ if (state() == State::STOPPING) {
VLOG(1) << "StopInstance() called when ARC is not running";
return;
}
- // We were explicitly asked to stop, so do not reconnect.
- reconnect_ = false;
-
VLOG(1) << "Stopping ARC";
DCHECK(arc_session_.get());
SetState(State::STOPPING);
@@ -127,39 +152,47 @@ void ArcBridgeServiceImpl::OnSessionReady() {
return;
}
- // The container can be considered to have been successfully launched, so
- // restart if the connection goes down without being requested.
- reconnect_ = true;
VLOG(0) << "ARC ready";
SetState(State::READY);
}
void ArcBridgeServiceImpl::OnSessionStopped(StopReason stop_reason) {
DCHECK(CalledOnValidThread());
+ DCHECK(!restart_timer_.IsRunning());
+
VLOG(0) << "ARC stopped: " << stop_reason;
arc_session_->RemoveObserver(this);
arc_session_.reset();
- SetStopReason(stop_reason);
- SetState(State::STOPPED);
- if (reconnect_) {
+ // If READY, 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
+ // 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_);
+
// There was a previous invocation and it crashed for some reason. Try
- // starting the container again.
- reconnect_ = false;
- VLOG(0) << "ARC reconnecting";
- if (use_delay_before_reconnecting_) {
- // Instead of immediately trying to restart the container, give it some
- // time to finish tearing down in case it is still in the process of
- // stopping.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::Bind(&ArcBridgeServiceImpl::PrerequisitesChanged,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromSeconds(kReconnectDelayInSeconds));
- } else {
- // Restart immediately.
- PrerequisitesChanged();
- }
+ // starting ARC instance later again.
+ // Note that even |restart_delay_| is 0 (for testing), it needs to
+ // PostTask, because observer callback may call RequestStart()/Stop(),
+ // which can change restarting.
+ VLOG(0) << "ARC restarting";
+ restart_timer_.Start(FROM_HERE, restart_delay_,
+ base::Bind(&ArcBridgeServiceImpl::StartArcSession,
+ weak_factory_.GetWeakPtr()));
}
+
+ // TODO(hidehiko): Consider to let observers know whether there is scheduled
+ // restarting event, or not.
+ SetStopReason(stop_reason);
+ SetState(State::STOPPED);
}
} // namespace arc
« no previous file with comments | « components/arc/arc_bridge_service_impl.h ('k') | components/arc/arc_bridge_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698