blob: c60543176385c455fe43f1df3e4cf299dc250c5e [file] [log] [blame]
Sam Goto9c87da7e2019-04-30 23:09:451// Copyright 2019 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
Sam Gotoc1294cab2019-07-15 22:36:015#include "content/browser/sms/sms_service.h"
Sam Goto9c87da7e2019-04-30 23:09:456
Sam Goto36d91172019-07-18 02:55:217#include <iterator>
8#include <queue>
Sam Gotoc1294cab2019-07-15 22:36:019#include <utility>
Sam Goto9c87da7e2019-04-30 23:09:4510
11#include "base/bind.h"
12#include "base/callback_helpers.h"
Sam Goto36d91172019-07-18 02:55:2113#include "base/optional.h"
Ayu Ishii9d303da52019-07-26 15:50:4714#include "content/browser/sms/sms_metrics.h"
Sam Gotoc108b7b2019-07-18 20:12:1515#include "content/public/browser/sms_dialog.h"
16#include "content/public/browser/web_contents.h"
17#include "content/public/browser/web_contents_delegate.h"
Sam Goto36d91172019-07-18 02:55:2118
19using blink::mojom::SmsStatus;
Sam Goto9c87da7e2019-04-30 23:09:4520
21namespace content {
22
Sam Goto36d91172019-07-18 02:55:2123SmsService::SmsService(SmsProvider* provider,
24 const url::Origin& origin,
25 RenderFrameHost* host,
26 blink::mojom::SmsReceiverRequest request)
27 : FrameServiceBase(host, std::move(request)),
28 sms_provider_(provider),
29 origin_(origin) {}
30
31SmsService::SmsService(SmsProvider* provider,
32 RenderFrameHost* host,
33 blink::mojom::SmsReceiverRequest request)
34 : SmsService(provider,
35 host->GetLastCommittedOrigin(),
36 host,
37 std::move(request)) {}
Sam Goto9c87da7e2019-04-30 23:09:4538
Sam Gotoc1294cab2019-07-15 22:36:0139SmsService::~SmsService() {
Jun Cai2055a0d62019-07-24 17:11:0640 if (callback_)
41 Process(SmsStatus::kTimeout, base::nullopt);
Sam Goto9c87da7e2019-04-30 23:09:4542}
43
Sam Goto36d91172019-07-18 02:55:2144// static
45void SmsService::Create(SmsProvider* provider,
46 RenderFrameHost* host,
47 blink::mojom::SmsReceiverRequest request) {
48 DCHECK(host);
49
50 // SmsService owns itself. It will self-destruct when a mojo interface
51 // error occurs, the render frame host is deleted, or the render frame host
52 // navigates to a new document.
53 new SmsService(provider, host, std::move(request));
Sam Goto9c87da7e2019-04-30 23:09:4554}
55
Sam Goto36d91172019-07-18 02:55:2156void SmsService::Receive(base::TimeDelta timeout, ReceiveCallback callback) {
Sam Goto9c87da7e2019-04-30 23:09:4557 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Jun Cai2055a0d62019-07-24 17:11:0658 if (callback_) {
Sam Gotoc108b7b2019-07-18 20:12:1559 std::move(callback).Run(blink::mojom::SmsStatus::kCancelled, base::nullopt);
60 return;
61 }
Sam Goto36d91172019-07-18 02:55:2162
Jun Cai2055a0d62019-07-24 17:11:0663 DCHECK(!prompt_);
64 DCHECK(!sms_);
Sam Goto36d91172019-07-18 02:55:2165
Ayu Ishiiae662c22019-08-06 16:24:0966 start_time_ = base::TimeTicks::Now();
67
Jun Cai2055a0d62019-07-24 17:11:0668 sms_provider_->AddObserver(this);
69
70 callback_ = std::move(callback);
71 // The |timer_| is owned by |this|, so it is safe to hold raw pointers to
72 // |this| here in the callback.
73 timer_.Start(FROM_HERE, timeout,
74 base::BindOnce(&SmsService::OnTimeout, base::Unretained(this)));
Sam Gotoc108b7b2019-07-18 20:12:1575
76 Prompt();
77
Sam Goto36d91172019-07-18 02:55:2178 sms_provider_->Retrieve();
79}
80
81bool SmsService::OnReceive(const url::Origin& origin, const std::string& sms) {
82 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
83 if (origin_ != origin)
84 return false;
85
Jun Cai2055a0d62019-07-24 17:11:0686 DCHECK(prompt_);
87 DCHECK(!sms_);
88 DCHECK(timer_.IsRunning());
Ayu Ishiiae662c22019-08-06 16:24:0989 DCHECK(!start_time_.is_null());
90
91 RecordSmsReceiveTime(base::TimeTicks::Now() - start_time_);
Sam Goto36d91172019-07-18 02:55:2192
Jun Cai2055a0d62019-07-24 17:11:0693 timer_.Stop();
94 sms_provider_->RemoveObserver(this);
Sam Goto36d91172019-07-18 02:55:2195
Jun Cai2055a0d62019-07-24 17:11:0696 sms_ = sms;
Ayu Ishii9d303da52019-07-26 15:50:4797 receive_time_ = base::TimeTicks::Now();
Jun Cai129e30b22019-07-29 23:53:1498 prompt_->SmsReceived();
Sam Goto36d91172019-07-18 02:55:2199 return true;
100}
101
Jun Cai2055a0d62019-07-24 17:11:06102void SmsService::Process(blink::mojom::SmsStatus status,
103 base::Optional<std::string> sms) {
Sam Goto36d91172019-07-18 02:55:21104 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
105
Jun Cai2055a0d62019-07-24 17:11:06106 DCHECK(callback_);
Sam Goto36d91172019-07-18 02:55:21107
Jun Cai2055a0d62019-07-24 17:11:06108 std::move(callback_).Run(status, sms);
Sam Goto36d91172019-07-18 02:55:21109
Jun Cai2055a0d62019-07-24 17:11:06110 Dismiss();
111}
112
113void SmsService::OnTimeout() {
114 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
115
116 DCHECK(callback_);
117 DCHECK(!timer_.IsRunning());
118
119 std::move(callback_).Run(blink::mojom::SmsStatus::kTimeout, base::nullopt);
120
121 Dismiss();
122}
123
Jun Cai7421705b2019-08-05 21:14:40124void SmsService::OnConfirm() {
Jun Cai2055a0d62019-07-24 17:11:06125 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
126
127 DCHECK(sms_);
Ayu Ishii9d303da52019-07-26 15:50:47128 DCHECK(!receive_time_.is_null());
129 RecordContinueOnSuccessTime(base::TimeTicks::Now() - receive_time_);
Jun Cai2055a0d62019-07-24 17:11:06130
131 Process(SmsStatus::kSuccess, sms_);
Sam Goto9c87da7e2019-04-30 23:09:45132}
133
Sam Gotoc108b7b2019-07-18 20:12:15134void SmsService::OnCancel() {
135 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
136
Ayu Ishii9d303da52019-07-26 15:50:47137 // Record only when SMS has already been received.
138 if (sms_) {
139 DCHECK(!receive_time_.is_null());
140 RecordCancelOnSuccessTime(base::TimeTicks::Now() - receive_time_);
141 }
142
Jun Cai2055a0d62019-07-24 17:11:06143 Process(SmsStatus::kCancelled, base::nullopt);
Sam Gotoc108b7b2019-07-18 20:12:15144}
145
146void SmsService::Prompt() {
147 WebContents* web_contents =
148 content::WebContents::FromRenderFrameHost(render_frame_host());
149 prompt_ = web_contents->GetDelegate()->CreateSmsDialog();
150 if (prompt_) {
Jun Cai2055a0d62019-07-24 17:11:06151 prompt_->Open(
152 render_frame_host(),
Jun Cai7421705b2019-08-05 21:14:40153 base::BindOnce(&SmsService::OnConfirm, base::Unretained(this)),
Jun Cai2055a0d62019-07-24 17:11:06154 base::BindOnce(&SmsService::OnCancel, base::Unretained(this)));
Sam Gotoc108b7b2019-07-18 20:12:15155 }
156}
157
158void SmsService::Dismiss() {
159 if (prompt_) {
160 prompt_->Close();
161 prompt_.reset();
162 }
Jun Cai2055a0d62019-07-24 17:11:06163
164 timer_.Stop();
165 callback_.Reset();
166 sms_.reset();
Ayu Ishiiae662c22019-08-06 16:24:09167 start_time_ = base::TimeTicks();
Ayu Ishii9d303da52019-07-26 15:50:47168 receive_time_ = base::TimeTicks();
Jun Cai2055a0d62019-07-24 17:11:06169 sms_provider_->RemoveObserver(this);
Sam Gotoc108b7b2019-07-18 20:12:15170}
171
Sam Goto9c87da7e2019-04-30 23:09:45172} // namespace content