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.
5 #include "components/copresence/copresence_manager_impl.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/timer/timer.h"
12 #include "components/copresence/handlers/directive_handler_impl.h"
13 #include "components/copresence/handlers/gcm_handler_impl.h"
14 #include "components/copresence/proto/rpcs.pb.h"
15 #include "components/copresence/public/whispernet_client.h"
16 #include "components/copresence/rpc/rpc_handler.h"
20 const int kPollTimerIntervalMs
= 3000; // milliseconds.
21 const int kAudioCheckIntervalMs
= 1000; // milliseconds.
25 namespace copresence
{
29 CopresenceManagerImpl::CopresenceManagerImpl(CopresenceDelegate
* delegate
)
30 : delegate_(delegate
),
31 whispernet_init_callback_(base::Bind(
32 &CopresenceManagerImpl::WhispernetInitComplete
,
33 // This callback gets cancelled when we are destroyed.
34 base::Unretained(this))),
36 directive_handler_(new DirectiveHandlerImpl
),
37 poll_timer_(new base::RepeatingTimer
<CopresenceManagerImpl
>),
38 audio_check_timer_(new base::RepeatingTimer
<CopresenceManagerImpl
>) {
40 DCHECK(delegate_
->GetWhispernetClient());
41 delegate_
->GetWhispernetClient()->Initialize(
42 whispernet_init_callback_
.callback());
44 if (delegate
->GetGCMDriver())
45 gcm_handler_
.reset(new GCMHandlerImpl(delegate
->GetGCMDriver(),
46 directive_handler_
.get()));
48 rpc_handler_
.reset(new RpcHandler(delegate
,
49 directive_handler_
.get(),
53 CopresenceManagerImpl::~CopresenceManagerImpl() {
54 whispernet_init_callback_
.Cancel();
57 // Returns false if any operations were malformed.
58 void CopresenceManagerImpl::ExecuteReportRequest(
59 const ReportRequest
& request
,
60 const std::string
& app_id
,
61 const std::string
& auth_token
,
62 const StatusCallback
& callback
) {
63 // If initialization has failed, reject all requests.
69 // We'll need to modify the ReportRequest, so we make our own copy to send.
70 scoped_ptr
<ReportRequest
> request_copy(new ReportRequest(request
));
71 rpc_handler_
->SendReportRequest(
72 request_copy
.Pass(), app_id
, auth_token
, callback
);
78 void CopresenceManagerImpl::WhispernetInitComplete(bool success
) {
80 DVLOG(3) << "Whispernet initialized successfully.";
82 // We destroy |directive_handler_| before |rpc_handler_|, hence passing
83 // in |rpc_handler_|'s pointer is safe here.
84 directive_handler_
->Start(delegate_
->GetWhispernetClient(),
85 base::Bind(&RpcHandler::ReportTokens
,
86 base::Unretained(rpc_handler_
.get())));
89 poll_timer_
->Start(FROM_HERE
,
90 base::TimeDelta::FromMilliseconds(kPollTimerIntervalMs
),
91 base::Bind(&CopresenceManagerImpl::PollForMessages
,
92 base::Unretained(this)));
93 audio_check_timer_
->Start(
94 FROM_HERE
, base::TimeDelta::FromMilliseconds(kAudioCheckIntervalMs
),
95 base::Bind(&CopresenceManagerImpl::AudioCheck
, base::Unretained(this)));
97 LOG(ERROR
) << "Whispernet initialization failed!";
102 void CopresenceManagerImpl::PollForMessages() {
103 // Report our currently playing tokens.
104 const std::string
& audible_token
=
105 directive_handler_
->GetCurrentAudioToken(AUDIBLE
);
106 const std::string
& inaudible_token
=
107 directive_handler_
->GetCurrentAudioToken(INAUDIBLE
);
109 std::vector
<AudioToken
> tokens
;
110 if (!audible_token
.empty())
111 tokens
.push_back(AudioToken(audible_token
, true));
112 if (!inaudible_token
.empty())
113 tokens
.push_back(AudioToken(inaudible_token
, false));
116 rpc_handler_
->ReportTokens(tokens
);
119 void CopresenceManagerImpl::AudioCheck() {
120 if (!directive_handler_
->GetCurrentAudioToken(AUDIBLE
).empty() &&
121 !directive_handler_
->IsAudioTokenHeard(AUDIBLE
)) {
122 delegate_
->HandleStatusUpdate(AUDIO_FAIL
);
123 } else if (!directive_handler_
->GetCurrentAudioToken(INAUDIBLE
).empty() &&
124 !directive_handler_
->IsAudioTokenHeard(INAUDIBLE
)) {
125 delegate_
->HandleStatusUpdate(AUDIO_FAIL
);
129 } // namespace copresence