1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "osp/impl/service_publisher_impl.h"
6 
7 #include "util/osp_logging.h"
8 
9 namespace openscreen {
10 namespace osp {
11 namespace {
12 
IsTransitionValid(ServicePublisher::State from,ServicePublisher::State to)13 bool IsTransitionValid(ServicePublisher::State from,
14                        ServicePublisher::State to) {
15   using State = ServicePublisher::State;
16   switch (from) {
17     case State::kStopped:
18       return to == State::kStarting || to == State::kStopping;
19     case State::kStarting:
20       return to == State::kRunning || to == State::kStopping ||
21              to == State::kSuspended;
22     case State::kRunning:
23       return to == State::kSuspended || to == State::kStopping;
24     case State::kStopping:
25       return to == State::kStopped;
26     case State::kSuspended:
27       return to == State::kRunning || to == State::kStopping;
28     default:
29       OSP_DCHECK(false) << "unknown State value: " << static_cast<int>(from);
30       break;
31   }
32   return false;
33 }
34 
35 }  // namespace
36 
37 ServicePublisherImpl::Delegate::Delegate() = default;
38 ServicePublisherImpl::Delegate::~Delegate() = default;
39 
SetPublisherImpl(ServicePublisherImpl * publisher)40 void ServicePublisherImpl::Delegate::SetPublisherImpl(
41     ServicePublisherImpl* publisher) {
42   OSP_DCHECK(!publisher_);
43   publisher_ = publisher;
44 }
45 
ServicePublisherImpl(Observer * observer,Delegate * delegate)46 ServicePublisherImpl::ServicePublisherImpl(Observer* observer,
47                                            Delegate* delegate)
48     : ServicePublisher(observer), delegate_(delegate) {
49   delegate_->SetPublisherImpl(this);
50 }
51 
52 ServicePublisherImpl::~ServicePublisherImpl() = default;
53 
Start()54 bool ServicePublisherImpl::Start() {
55   if (state_ != State::kStopped)
56     return false;
57   state_ = State::kStarting;
58   delegate_->StartPublisher();
59   return true;
60 }
StartAndSuspend()61 bool ServicePublisherImpl::StartAndSuspend() {
62   if (state_ != State::kStopped)
63     return false;
64   state_ = State::kStarting;
65   delegate_->StartAndSuspendPublisher();
66   return true;
67 }
Stop()68 bool ServicePublisherImpl::Stop() {
69   if (state_ == State::kStopped || state_ == State::kStopping)
70     return false;
71 
72   state_ = State::kStopping;
73   delegate_->StopPublisher();
74   return true;
75 }
Suspend()76 bool ServicePublisherImpl::Suspend() {
77   if (state_ != State::kRunning && state_ != State::kStarting)
78     return false;
79 
80   delegate_->SuspendPublisher();
81   return true;
82 }
Resume()83 bool ServicePublisherImpl::Resume() {
84   if (state_ != State::kSuspended)
85     return false;
86 
87   delegate_->ResumePublisher();
88   return true;
89 }
90 
SetState(State state)91 void ServicePublisherImpl::SetState(State state) {
92   OSP_DCHECK(IsTransitionValid(state_, state));
93   state_ = state;
94   if (observer_)
95     MaybeNotifyObserver();
96 }
97 
MaybeNotifyObserver()98 void ServicePublisherImpl::MaybeNotifyObserver() {
99   OSP_DCHECK(observer_);
100   switch (state_) {
101     case State::kRunning:
102       observer_->OnStarted();
103       break;
104     case State::kStopped:
105       observer_->OnStopped();
106       break;
107     case State::kSuspended:
108       observer_->OnSuspended();
109       break;
110     default:
111       break;
112   }
113 }
114 
115 }  // namespace osp
116 }  // namespace openscreen
117