Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 1 | // 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 | |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 5 | #ifndef CONTENT_BROWSER_SMS_WEBOTP_SERVICE_H_ |
| 6 | #define CONTENT_BROWSER_SMS_WEBOTP_SERVICE_H_ |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 7 | |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 8 | #include <memory> |
Ayu Ishii | 3a50e49 | 2019-11-26 01:49:30 | [diff] [blame] | 9 | #include <string> |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 10 | |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 11 | #include "base/callback_forward.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 12 | #include "base/memory/raw_ptr.h" |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 13 | #include "base/sequence_checker.h" |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 14 | #include "base/time/time.h" |
Yi Gu | 4f8c047 | 2020-12-10 17:45:28 | [diff] [blame] | 15 | #include "base/timer/timer.h" |
Yi Gu | 56cab02 | 2020-10-20 14:11:31 | [diff] [blame] | 16 | #include "content/browser/sms/sms_parser.h" |
Sam Goto | 5cf068e8 | 2019-11-04 23:08:44 | [diff] [blame] | 17 | #include "content/browser/sms/sms_queue.h" |
Majid Valipour | dcd50fa | 2020-07-20 16:59:43 | [diff] [blame] | 18 | #include "content/browser/sms/user_consent_handler.h" |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 19 | #include "content/common/content_export.h" |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 20 | #include "content/public/browser/document_service.h" |
Miyoung Shin | 8ff3aa89 | 2019-08-31 03:01:38 | [diff] [blame] | 21 | #include "mojo/public/cpp/bindings/pending_receiver.h" |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 22 | #include "third_party/blink/public/mojom/sms/webotp_service.mojom.h" |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 23 | #include "url/origin.h" |
Sam Goto | 9b201f9 | 2019-05-29 22:46:20 | [diff] [blame] | 24 | |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 25 | namespace content { |
| 26 | |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 27 | class RenderFrameHost; |
Sam Goto | 5cf068e8 | 2019-11-04 23:08:44 | [diff] [blame] | 28 | class SmsFetcher; |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 29 | |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 30 | // WebOTPService handles mojo connections from the renderer, observing the |
| 31 | // incoming SMS messages from an SmsFetcher. In practice, it is owned and |
| 32 | // managed by a RenderFrameHost. It accomplishes that via subclassing |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 33 | // DocumentService, which observes the lifecycle of a RenderFrameHost and |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 34 | // manages it own memory. Create() creates a self-managed instance of |
| 35 | // WebOTPService and binds it to the request. |
| 36 | class CONTENT_EXPORT WebOTPService |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 37 | : public DocumentService<blink::mojom::WebOTPService>, |
Sam Goto | 5cf068e8 | 2019-11-04 23:08:44 | [diff] [blame] | 38 | public SmsFetcher::Subscriber { |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 39 | public: |
Ken Buchanan | 8c41e56 | 2020-10-28 23:08:40 | [diff] [blame] | 40 | // Return value indicates success. Creation can fail if origin requirements |
| 41 | // are not met. |
| 42 | static bool Create(SmsFetcher*, |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 43 | RenderFrameHost*, |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 44 | mojo::PendingReceiver<blink::mojom::WebOTPService>); |
danakj | c70aec1f | 2022-07-07 15:48:19 | [diff] [blame^] | 45 | static WebOTPService& CreateForTesting( |
| 46 | SmsFetcher*, |
| 47 | const OriginList&, |
| 48 | RenderFrameHost&, |
| 49 | mojo::PendingReceiver<blink::mojom::WebOTPService>); |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 50 | |
| 51 | WebOTPService(const WebOTPService&) = delete; |
| 52 | WebOTPService& operator=(const WebOTPService&) = delete; |
| 53 | |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 54 | ~WebOTPService() override; |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 55 | |
Yi Gu | 835847b | 2021-03-18 02:58:36 | [diff] [blame] | 56 | using FailureType = SmsFetchFailureType; |
Yi Gu | 9621ff9 | 2020-10-08 04:38:10 | [diff] [blame] | 57 | using SmsParsingStatus = SmsParser::SmsParsingStatus; |
Majid Valipour | 24a2a30 | 2020-11-18 00:37:09 | [diff] [blame] | 58 | using UserConsent = SmsFetcher::UserConsent; |
Yi Gu | 9621ff9 | 2020-10-08 04:38:10 | [diff] [blame] | 59 | |
Daniel Cheng | eb5e854 | 2022-04-20 17:32:21 | [diff] [blame] | 60 | // content::DocumentService: |
| 61 | void WillBeDestroyed(DocumentServiceDestructionReason) override; |
| 62 | |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 63 | // blink::mojom::WebOTPService: |
Ayu Ishii | ac09053 | 2019-09-04 14:12:06 | [diff] [blame] | 64 | void Receive(ReceiveCallback) override; |
Ayu Ishii | 3a50e49 | 2019-11-26 01:49:30 | [diff] [blame] | 65 | void Abort() override; |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 66 | |
Sam Goto | 5cf068e8 | 2019-11-04 23:08:44 | [diff] [blame] | 67 | // content::SmsQueue::Subscriber |
Yi Gu | 684eb2b | 2021-03-09 00:40:37 | [diff] [blame] | 68 | void OnReceive(const OriginList&, |
| 69 | const std::string& one_time_code, |
| 70 | UserConsent) override; |
Yi Gu | 9621ff9 | 2020-10-08 04:38:10 | [diff] [blame] | 71 | void OnFailure(FailureType failure_type) override; |
Sam Goto | 5cf068e8 | 2019-11-04 23:08:44 | [diff] [blame] | 72 | |
Majid Valipour | dcd50fa | 2020-07-20 16:59:43 | [diff] [blame] | 73 | // Completes the in-flight sms otp code request. Invokes the receive callback, |
| 74 | // if one is available, with the provided status code and the existing one |
| 75 | // time code. |
| 76 | void CompleteRequest(blink::mojom::SmsStatus); |
Majid Valipour | 24a2a30 | 2020-11-18 00:37:09 | [diff] [blame] | 77 | void SetConsentHandlerForTesting(UserConsentHandler*); |
Majid Valipour | dcd50fa | 2020-07-20 16:59:43 | [diff] [blame] | 78 | |
Yi Gu | 4f8c047 | 2020-12-10 17:45:28 | [diff] [blame] | 79 | // Rejects the pending request if it has not been resolved naturally yet. |
| 80 | void OnTimeout(); |
| 81 | |
Yi Gu | ab30194 | 2020-12-10 20:34:03 | [diff] [blame] | 82 | void OnUserConsentComplete(UserConsentResult); |
| 83 | |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 84 | private: |
danakj | c70aec1f | 2022-07-07 15:48:19 | [diff] [blame^] | 85 | WebOTPService(SmsFetcher*, |
| 86 | const OriginList&, |
| 87 | RenderFrameHost&, |
| 88 | mojo::PendingReceiver<blink::mojom::WebOTPService>); |
| 89 | |
Sam Goto | 4fedd24 | 2019-08-22 03:35:32 | [diff] [blame] | 90 | void CleanUp(); |
Majid Valipour | 24a2a30 | 2020-11-18 00:37:09 | [diff] [blame] | 91 | UserConsentHandler* CreateConsentHandler(UserConsent); |
| 92 | UserConsentHandler* GetConsentHandler(); |
Yi Gu | 2968f98 | 2020-12-09 23:44:15 | [diff] [blame] | 93 | void RecordMetrics(blink::mojom::SmsStatus); |
Sam Goto | c108b7b | 2019-07-18 20:12:15 | [diff] [blame] | 94 | |
Sam Goto | 5cf068e8 | 2019-11-04 23:08:44 | [diff] [blame] | 95 | // |fetcher_| is safe because all instances of SmsFetcher are owned |
| 96 | // by the browser context, which transitively (through RenderFrameHost) owns |
| 97 | // and outlives this class. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 98 | raw_ptr<SmsFetcher> fetcher_; |
Sam Goto | c108b7b | 2019-07-18 20:12:15 | [diff] [blame] | 99 | |
Yi Gu | 5874e3cf | 2020-11-30 16:36:34 | [diff] [blame] | 100 | const OriginList origin_list_; |
Jun Cai | 2055a0d6 | 2019-07-24 17:11:06 | [diff] [blame] | 101 | ReceiveCallback callback_; |
Anton Bikineev | f62d1bf | 2021-05-15 17:56:07 | [diff] [blame] | 102 | absl::optional<std::string> one_time_code_; |
Ayu Ishii | ae662c2 | 2019-08-06 16:24:09 | [diff] [blame] | 103 | base::TimeTicks start_time_; |
Ayu Ishii | 9d303da5 | 2019-07-26 15:50:47 | [diff] [blame] | 104 | base::TimeTicks receive_time_; |
Yi Gu | 4f8c047 | 2020-12-10 17:45:28 | [diff] [blame] | 105 | // Timer to trigger timeout for any pending request. We (re)arm the timer |
| 106 | // every time we receive a new request. |
| 107 | base::DelayTimer timeout_timer_; |
Yi Gu | 7bb3619e | 2021-07-09 14:04:51 | [diff] [blame] | 108 | absl::optional<FailureType> delayed_rejection_reason_; |
Sam Goto | 36d9117 | 2019-07-18 02:55:21 | [diff] [blame] | 109 | |
Majid Valipour | 24a2a30 | 2020-11-18 00:37:09 | [diff] [blame] | 110 | // The ptr is valid only when we are handling an incoming otp response. |
| 111 | std::unique_ptr<UserConsentHandler> consent_handler_; |
| 112 | // This is used to inject a mock consent handler for testing and it is owned |
| 113 | // by test code. |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 114 | raw_ptr<UserConsentHandler> consent_handler_for_test_{nullptr}; |
Majid Valipour | 24a2a30 | 2020-11-18 00:37:09 | [diff] [blame] | 115 | |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 116 | SEQUENCE_CHECKER(sequence_checker_); |
Sam Goto | 4fedd24 | 2019-08-22 03:35:32 | [diff] [blame] | 117 | |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 118 | base::WeakPtrFactory<WebOTPService> weak_ptr_factory_{this}; |
Sam Goto | 9c87da7e | 2019-04-30 23:09:45 | [diff] [blame] | 119 | }; |
| 120 | |
| 121 | } // namespace content |
| 122 | |
Majid Valipour | ae11335e | 2020-10-14 04:09:24 | [diff] [blame] | 123 | #endif // CONTENT_BROWSER_SMS_WEBOTP_SERVICE_H_ |