blob: a90a37dcb4edf93934dc81f748775d243e20aee3 [file] [log] [blame]
Sam Goto5cf068e82019-11-04 23:08:441// 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
5#include "content/browser/sms/sms_fetcher_impl.h"
6
7#include "base/callback.h"
8#include "content/browser/browser_main_loop.h"
Sam Gotoa03e01e2019-11-09 00:44:429#include "content/browser/sms/sms_parser.h"
Sam Goto5cf068e82019-11-04 23:08:4410#include "content/public/browser/browser_context.h"
11#include "content/public/browser/content_browser_client.h"
12#include "content/public/common/content_client.h"
Sam Goto5cf068e82019-11-04 23:08:4413
14namespace content {
15
16const char kSmsFetcherImplKeyName[] = "sms_fetcher";
17
Ayu Ishiiae5d9bf2020-05-01 18:50:0918SmsFetcherImpl::SmsFetcherImpl(BrowserContext* context, SmsProvider* provider)
19 : context_(context), provider_(provider) {
Sam Goto5cf068e82019-11-04 23:08:4420 if (provider_)
21 provider_->AddObserver(this);
22}
23
24SmsFetcherImpl::~SmsFetcherImpl() {
25 if (provider_)
26 provider_->RemoveObserver(this);
27}
28
29// static
30SmsFetcher* SmsFetcher::Get(BrowserContext* context) {
31 if (!context->GetUserData(kSmsFetcherImplKeyName)) {
Ayu Ishiiae5d9bf2020-05-01 18:50:0932 auto fetcher = std::make_unique<SmsFetcherImpl>(
33 context, BrowserMainLoop::GetInstance()->GetSmsProvider());
Sam Goto5cf068e82019-11-04 23:08:4434 context->SetUserData(kSmsFetcherImplKeyName, std::move(fetcher));
35 }
36
37 return static_cast<SmsFetcherImpl*>(
38 context->GetUserData(kSmsFetcherImplKeyName));
39}
40
Ayu Ishiifdabd1a2020-04-28 01:50:3241// TODO(crbug.com/1015645): Add implementation.
Sam Goto5cf068e82019-11-04 23:08:4442void SmsFetcherImpl::Subscribe(const url::Origin& origin,
43 SmsQueue::Subscriber* subscriber) {
Ayu Ishii419bd6b2019-12-12 00:38:0844 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Ayu Ishiifdabd1a2020-04-28 01:50:3245 NOTIMPLEMENTED();
46}
47
48void SmsFetcherImpl::Subscribe(const url::Origin& origin,
49 SmsQueue::Subscriber* subscriber,
50 RenderFrameHost* render_frame_host) {
51 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
52 DCHECK(subscriber);
53 DCHECK(render_frame_host);
Ayu Ishiib09941712020-04-10 01:23:2554 // Should not be called multiple times for the same subscriber and origin.
55 DCHECK(!subscribers_.HasSubscriber(origin, subscriber));
Ayu Ishiiaca91ae2020-01-10 00:32:3356
Sam Goto5cf068e82019-11-04 23:08:4457 subscribers_.Push(origin, subscriber);
58
59 // Fetches a remote SMS.
60 GetContentClient()->browser()->FetchRemoteSms(
61 context_, origin,
62 base::BindOnce(&SmsFetcherImpl::OnRemote,
63 weak_ptr_factory_.GetWeakPtr()));
64
65 // Fetches a local SMS.
66 if (provider_)
Ayu Ishiifdabd1a2020-04-28 01:50:3267 provider_->Retrieve(render_frame_host);
Sam Goto5cf068e82019-11-04 23:08:4468}
69
70void SmsFetcherImpl::Unsubscribe(const url::Origin& origin,
71 SmsQueue::Subscriber* subscriber) {
Ayu Ishiib09941712020-04-10 01:23:2572 // Unsubscribe does not make a call to the provider because currently there
73 // is no mechanism to cancel a subscription.
Ayu Ishii419bd6b2019-12-12 00:38:0874 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sam Goto5cf068e82019-11-04 23:08:4475 subscribers_.Remove(origin, subscriber);
76}
77
78bool SmsFetcherImpl::Notify(const url::Origin& origin,
Ayu Ishii72b58152020-03-16 06:24:0479 const std::string& one_time_code) {
Ayu Ishii419bd6b2019-12-12 00:38:0880 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Ayu Ishiib09941712020-04-10 01:23:2581 // The received OTP is returned to the first subscriber for the origin.
Sam Goto5cf068e82019-11-04 23:08:4482 auto* subscriber = subscribers_.Pop(origin);
83
84 if (!subscriber)
85 return false;
86
Ayu Ishii72b58152020-03-16 06:24:0487 subscriber->OnReceive(one_time_code);
Sam Goto5cf068e82019-11-04 23:08:4488 return true;
89}
90
91void SmsFetcherImpl::OnRemote(base::Optional<std::string> sms) {
Ayu Ishii419bd6b2019-12-12 00:38:0892 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
93
Sam Gotoa03e01e2019-11-09 00:44:4294 if (!sms)
95 return;
96
Yi Gued665e12020-10-13 15:55:3497 // TODO(yigu): We should log when the sms cannot be parsed similar to local
98 // SMSes.
99 SmsParser::Result result = SmsParser::Parse(*sms);
100 if (!result.IsValid())
Sam Gotoa03e01e2019-11-09 00:44:42101 return;
102
Yi Gued665e12020-10-13 15:55:34103 Notify(result.origin, result.one_time_code);
Sam Goto5cf068e82019-11-04 23:08:44104}
105
106bool SmsFetcherImpl::OnReceive(const url::Origin& origin,
Ayu Ishii72b58152020-03-16 06:24:04107 const std::string& one_time_code) {
Ayu Ishii419bd6b2019-12-12 00:38:08108 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Ayu Ishii72b58152020-03-16 06:24:04109 return Notify(origin, one_time_code);
Sam Goto5cf068e82019-11-04 23:08:44110}
111
Yi Gued665e12020-10-13 15:55:34112void SmsFetcherImpl::NotifyParsingFailure(SmsParser::SmsParsingStatus status) {
113 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
114 subscribers_.NotifyParsingFailure(status);
115}
116
Sam Goto5cf068e82019-11-04 23:08:44117bool SmsFetcherImpl::HasSubscribers() {
Ayu Ishii419bd6b2019-12-12 00:38:08118 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sam Goto5cf068e82019-11-04 23:08:44119 return subscribers_.HasSubscribers();
120}
121
Sam Goto5cf068e82019-11-04 23:08:44122} // namespace content