droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 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 | #ifndef COMPONENTS_TRANSLATE_IOS_BROWSER_TRANSLATE_CONTROLLER_H_ |
| 6 | #define COMPONENTS_TRANSLATE_IOS_BROWSER_TRANSLATE_CONTROLLER_H_ |
| 7 | |
John Z Wu | 31d0dd6 | 2018-11-02 00:59:29 | [diff] [blame] | 8 | #include <iterator> |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 9 | #include <memory> |
John Z Wu | 31d0dd6 | 2018-11-02 00:59:29 | [diff] [blame] | 10 | #include <set> |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 11 | #include <string> |
| 12 | |
| 13 | #include "base/gtest_prod_util.h" |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 14 | #include "base/macros.h" |
| 15 | #include "base/memory/weak_ptr.h" |
John Z Wu | ae98b4a | 2018-08-27 22:32:23 | [diff] [blame] | 16 | #include "components/translate/core/common/translate_errors.h" |
Eugene But | d3564aaea | 2019-08-13 15:50:45 | [diff] [blame] | 17 | #import "ios/web/public/web_state.h" |
Eugene But | bef79e4 | 2019-09-10 17:17:14 | [diff] [blame] | 18 | #include "ios/web/public/web_state_observer.h" |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 19 | #include "services/network/public/cpp/simple_url_loader.h" |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 20 | |
| 21 | @class JsTranslateManager; |
| 22 | class GURL; |
| 23 | |
| 24 | namespace base { |
| 25 | class DictionaryValue; |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 26 | } // namespace base |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 27 | |
| 28 | namespace web { |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 29 | class NavigationContext; |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 30 | } // namespace web |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 31 | |
| 32 | namespace translate { |
| 33 | |
| 34 | // TranslateController controls the translation of the page, by injecting the |
| 35 | // translate scripts and monitoring the status. |
| 36 | class TranslateController : public web::WebStateObserver { |
| 37 | public: |
| 38 | // Observer class to monitor the progress of the translation. |
| 39 | class Observer { |
| 40 | public: |
| 41 | // Called when the translate script is ready. |
John Z Wu | ae98b4a | 2018-08-27 22:32:23 | [diff] [blame] | 42 | // |error_type| Indicates error code. |
| 43 | virtual void OnTranslateScriptReady(TranslateErrors::Type error_type, |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 44 | double load_time, |
| 45 | double ready_time) = 0; |
| 46 | |
| 47 | // Called when the translation is complete. |
John Z Wu | ae98b4a | 2018-08-27 22:32:23 | [diff] [blame] | 48 | // |error_type| Indicates error code. |
| 49 | virtual void OnTranslateComplete(TranslateErrors::Type error_type, |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 50 | const std::string& original_language, |
| 51 | double translation_time) = 0; |
| 52 | }; |
| 53 | |
| 54 | TranslateController(web::WebState* web_state, JsTranslateManager* manager); |
| 55 | ~TranslateController() override; |
| 56 | |
| 57 | // Sets the observer. |
| 58 | void set_observer(Observer* observer) { observer_ = observer; } |
| 59 | |
| 60 | // Injects the translate script. |
| 61 | void InjectTranslateScript(const std::string& translate_script); |
| 62 | |
| 63 | // Reverts the translation. |
| 64 | void RevertTranslation(); |
| 65 | |
| 66 | // Starts the translation. Must be called when the translation script is |
| 67 | // ready. |
| 68 | void StartTranslation(const std::string& source_language, |
| 69 | const std::string& target_language); |
| 70 | |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 71 | // Changes the JsTranslateManager used by this TranslateController. |
| 72 | // Only used for testing. |
stkhapugin | 2393ab2 | 2017-01-20 15:34:45 | [diff] [blame] | 73 | void SetJsTranslateManagerForTesting(JsTranslateManager* manager); |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 74 | |
| 75 | private: |
| 76 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
| 77 | OnJavascriptCommandReceived); |
| 78 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
Olivier Robin | 7b03f40 | 2018-06-21 13:17:04 | [diff] [blame] | 79 | OnIFrameJavascriptCommandReceived); |
| 80 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 81 | OnTranslateScriptReadyTimeoutCalled); |
| 82 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
| 83 | OnTranslateScriptReadyCalled); |
| 84 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, TranslationSuccess); |
| 85 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, TranslationFailure); |
John Z Wu | 7a1c7f1 | 2018-09-12 16:00:09 | [diff] [blame] | 86 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, OnTranslateLoadJavascript); |
John Z Wu | 8eb0e149 | 2020-08-24 19:17:38 | [diff] [blame] | 87 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
| 88 | OnTranslateSendRequestWithValidCommand); |
| 89 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
| 90 | OnTranslateSendRequestWithBadURL); |
| 91 | FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, |
| 92 | OnTranslateSendRequestWithBadMethod); |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 93 | |
| 94 | // Called when a JavaScript command is received. |
| 95 | bool OnJavascriptCommandReceived(const base::DictionaryValue& command, |
| 96 | const GURL& url, |
Olivier Robin | 7b03f40 | 2018-06-21 13:17:04 | [diff] [blame] | 97 | bool interacting, |
Olivier Robin | 2520625 | 2018-09-11 09:09:41 | [diff] [blame] | 98 | web::WebFrame* sender_frame); |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 99 | // Methods to handle specific JavaScript commands. |
| 100 | // Return false if the command is invalid. |
| 101 | bool OnTranslateReady(const base::DictionaryValue& command); |
| 102 | bool OnTranslateComplete(const base::DictionaryValue& command); |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 103 | bool OnTranslateLoadJavaScript(const base::DictionaryValue& command); |
John Z Wu | 31d0dd6 | 2018-11-02 00:59:29 | [diff] [blame] | 104 | bool OnTranslateSendRequest(const base::DictionaryValue& command); |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 105 | |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 106 | // The callback when the script is fetched or a server error occurred. |
| 107 | void OnScriptFetchComplete(std::unique_ptr<std::string> response_body); |
John Z Wu | 31d0dd6 | 2018-11-02 00:59:29 | [diff] [blame] | 108 | // The callback when translate requests have completed. |
| 109 | void OnRequestFetchComplete( |
| 110 | std::set<std::unique_ptr<network::SimpleURLLoader>>::iterator it, |
| 111 | std::string url, |
| 112 | int request_id, |
| 113 | std::unique_ptr<std::string> response_body); |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 114 | |
| 115 | // web::WebStateObserver implementation: |
Sylvain Defresne | 3212e2a | 2017-10-18 21:32:49 | [diff] [blame] | 116 | void WebStateDestroyed(web::WebState* web_state) override; |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 117 | void DidStartNavigation(web::WebState* web_state, |
| 118 | web::NavigationContext* navigation_context) override; |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 119 | |
Sylvain Defresne | 4051ebd | 2017-11-13 18:12:01 | [diff] [blame] | 120 | // The WebState this instance is observing. Will be null after |
| 121 | // WebStateDestroyed has been called. |
| 122 | web::WebState* web_state_ = nullptr; |
| 123 | |
John Z Wu | 31d0dd6 | 2018-11-02 00:59:29 | [diff] [blame] | 124 | // Used to fetch translate requests. There may be multiple requests in flight. |
| 125 | std::set<std::unique_ptr<network::SimpleURLLoader>> request_fetchers_; |
John Z Wu | dfaa429 | 2018-09-07 01:10:26 | [diff] [blame] | 126 | // Used to fetch additional scripts needed for translate. |
| 127 | std::unique_ptr<network::SimpleURLLoader> script_fetcher_; |
| 128 | |
Yi Su | 77b7a81 | 2019-07-23 08:11:16 | [diff] [blame] | 129 | // Subscription for JS message. |
| 130 | std::unique_ptr<web::WebState::ScriptCommandSubscription> subscription_; |
| 131 | |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 132 | Observer* observer_; |
Sylvain Defresne | 2fc15b34 | 2020-03-02 17:29:40 | [diff] [blame] | 133 | __strong JsTranslateManager* js_manager_; |
droger | bfba8a4 | 2014-12-16 21:58:13 | [diff] [blame] | 134 | base::WeakPtrFactory<TranslateController> weak_method_factory_; |
| 135 | |
| 136 | DISALLOW_COPY_AND_ASSIGN(TranslateController); |
| 137 | }; |
| 138 | |
| 139 | } // namespace translate |
| 140 | |
| 141 | #endif // COMPONENTS_TRANSLATE_IOS_BROWSER_TRANSLATE_CONTROLLER_H_ |