OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 "base/logging.h" | |
6 #include "base/time/time.h" | |
7 #include "components/copresence/copresence_state_impl.h" | |
8 #include "components/copresence/proto/data.pb.h" | |
9 #include "components/copresence/public/copresence_constants.h" | |
10 #include "components/copresence/public/copresence_observer.h" | |
11 | |
12 namespace copresence { | |
13 | |
14 namespace { | |
15 | |
16 template<class T> | |
17 void CheckUnchangedFields(const T& new_token, const T& current_token) { | |
18 if (current_token.id.empty()) | |
19 return; | |
20 | |
21 // These fields identify the token. | |
22 DCHECK_EQ(new_token.id, current_token.id); | |
23 DCHECK_EQ(new_token.medium, current_token.medium); | |
24 | |
25 // start_time may not be changed. | |
26 DCHECK_EQ(new_token.start_time, current_token.start_time); | |
27 } | |
28 | |
29 void UpdateToken(const TransmittedToken& new_token, | |
30 TransmittedToken* current_token) { | |
31 CheckUnchangedFields(new_token, *current_token); | |
32 | |
33 current_token->stop_time = new_token.stop_time; | |
34 current_token->broadcast_confirmed = new_token.broadcast_confirmed; | |
35 } | |
36 | |
37 void UpdateToken(const ReceivedToken& new_token, | |
38 ReceivedToken* current_token) { | |
39 CheckUnchangedFields(new_token, *current_token); | |
40 | |
41 current_token->last_time = new_token.last_time; | |
42 if (new_token.valid != ReceivedToken::UNKNOWN) | |
43 current_token->valid = new_token.valid; | |
44 } | |
45 | |
46 } // namespace | |
47 | |
48 | |
49 // Public functions. | |
50 | |
51 CopresenceStateImpl::CopresenceStateImpl() {} | |
52 | |
53 CopresenceStateImpl::~CopresenceStateImpl() {} | |
54 | |
55 void CopresenceStateImpl::AddObserver(CopresenceObserver* observer) { | |
56 DCHECK(observer); | |
57 bool not_duplicate = observers_.insert(observer).second; | |
58 DCHECK(not_duplicate); | |
59 } | |
60 | |
61 void CopresenceStateImpl::RemoveObserver(CopresenceObserver* observer) { | |
62 DCHECK(observer); | |
63 int elts_deleted = observers_.erase(observer); | |
64 DCHECK_GT(elts_deleted, 0); | |
65 } | |
66 | |
67 const std::vector<Directive>& CopresenceStateImpl::active_directives() { | |
68 return active_directives_; | |
69 } | |
70 | |
71 const std::map<std::string, TransmittedToken>& | |
72 CopresenceStateImpl::transmitted_tokens() { | |
73 return transmitted_tokens_; | |
74 } | |
75 | |
76 const std::map<std::string, ReceivedToken>& | |
77 CopresenceStateImpl::received_tokens() { | |
78 return received_tokens_; | |
79 } | |
80 | |
81 // TODO(ckehoe): Only send updates if the directives have really changed. | |
82 void CopresenceStateImpl::UpdateDirectives( | |
83 const std::vector<Directive>& directives) { | |
84 active_directives_ = directives; | |
85 UpdateTransmittingTokens(); | |
86 | |
87 for (CopresenceObserver* observer : observers_) | |
88 observer->DirectivesUpdated(); | |
89 } | |
90 | |
91 void CopresenceStateImpl::UpdateTransmittedToken( | |
92 const TransmittedToken& token) { | |
93 UpdateToken(token, &transmitted_tokens_[token.id]); | |
xiyuan
2014/12/18 18:10:51
General question: when would a token be removed fr
Charlie
2014/12/19 03:53:33
Currently this doesn't happen. This is useful to a
| |
94 for (CopresenceObserver* observer : observers_) | |
95 observer->TokenTransmitted(transmitted_tokens_[token.id]); | |
96 } | |
97 | |
98 // TODO(ckehoe): Check which tokens are no longer heard and report them lost. | |
99 void CopresenceStateImpl::UpdateReceivedToken(const ReceivedToken& token) { | |
100 DCHECK(!token.id.empty()); | |
101 | |
102 // TODO(ckehoe): Have CopresenceManagerImpl::AudioCheck() use this to check | |
103 // if we can hear our token, and delete the logic from the AudioManager. | |
104 if (transmitted_tokens_.count(token.id) > 0) { | |
105 transmitted_tokens_[token.id].broadcast_confirmed = true; | |
106 for (CopresenceObserver* observer : observers_) | |
107 observer->TokenTransmitted(transmitted_tokens_[token.id]); | |
108 } else { | |
109 ReceivedToken& stored_token = received_tokens_[token.id]; | |
110 UpdateToken(token, &stored_token); | |
111 | |
112 // The decoder doesn't track when this token was heard before, | |
113 // so it should just fill in the last_time. | |
114 // If we've never seen this token, we populate the start time too. | |
115 if (stored_token.start_time.is_null()) | |
116 stored_token.start_time = token.last_time; | |
117 | |
118 for (CopresenceObserver* observer : observers_) | |
119 observer->TokenReceived(stored_token); | |
120 } | |
121 } | |
122 | |
123 void CopresenceStateImpl::UpdateTokenStatus(const std::string& token_id, | |
124 TokenStatus status) { | |
125 if (transmitted_tokens_.count(token_id) > 0) { | |
126 LOG_IF(ERROR, status != VALID) | |
127 << "Broadcast token " << token_id << " is invalid"; | |
128 } else if (received_tokens_.count(token_id) > 0) { | |
129 received_tokens_[token_id].valid = status == VALID ? | |
130 ReceivedToken::VALID : ReceivedToken::INVALID; | |
131 for (CopresenceObserver* observer : observers_) | |
132 observer->TokenReceived(received_tokens_[token_id]); | |
133 } else { | |
134 LOG(ERROR) << "Got status update for unrecognized token " << token_id; | |
135 } | |
136 } | |
137 | |
138 | |
139 // Private functions. | |
140 | |
141 void CopresenceStateImpl::UpdateTransmittingTokens() { | |
142 std::set<std::string> tokens_to_update; | |
143 for (const auto& token_entry : transmitted_tokens_) | |
144 tokens_to_update.insert(token_entry.first); | |
145 | |
146 for (const Directive& directive : active_directives_) { | |
147 const TokenInstruction& instruction = directive.token_instruction(); | |
148 if (instruction.token_instruction_type() == TRANSMIT) { | |
149 tokens_to_update.erase(instruction.token_id()); | |
150 | |
151 TransmittedToken& token = transmitted_tokens_[instruction.token_id()]; | |
152 token.id = instruction.token_id(); | |
153 token.medium = instruction.medium(); | |
154 token.start_time = base::Time::Now(); | |
155 token.stop_time = base::Time::Now() + | |
156 base::TimeDelta::FromMilliseconds(directive.ttl_millis()); | |
157 | |
158 for (CopresenceObserver* observer : observers_) | |
159 observer->TokenTransmitted(token); | |
160 } | |
161 } | |
162 | |
163 // Tokens not updated above are no longer transmitting. | |
164 base::Time now = base::Time::Now(); | |
165 for (const std::string& token : tokens_to_update) { | |
166 if (transmitted_tokens_[token].stop_time > now) | |
167 transmitted_tokens_[token].stop_time = now; | |
168 for (CopresenceObserver* observer : observers_) | |
169 observer->TokenTransmitted(transmitted_tokens_[token]); | |
170 } | |
171 } | |
172 | |
173 } // namespace copresence | |
OLD | NEW |