blob: dadd0a7bf33802b10d0878aac893332b31f0ad2b [file] [log] [blame]
drogerbfba8a42014-12-16 21:58:131// 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 Wu31d0dd62018-11-02 00:59:298#include <iterator>
John Z Wudfaa4292018-09-07 01:10:269#include <memory>
John Z Wu31d0dd62018-11-02 00:59:2910#include <set>
drogerbfba8a42014-12-16 21:58:1311#include <string>
12
13#include "base/gtest_prod_util.h"
drogerbfba8a42014-12-16 21:58:1314#include "base/macros.h"
15#include "base/memory/weak_ptr.h"
John Z Wuae98b4a2018-08-27 22:32:2316#include "components/translate/core/common/translate_errors.h"
Eugene Butd3564aaea2019-08-13 15:50:4517#import "ios/web/public/web_state.h"
Eugene Butbef79e42019-09-10 17:17:1418#include "ios/web/public/web_state_observer.h"
John Z Wudfaa4292018-09-07 01:10:2619#include "services/network/public/cpp/simple_url_loader.h"
drogerbfba8a42014-12-16 21:58:1320
21@class JsTranslateManager;
22class GURL;
23
24namespace base {
25class DictionaryValue;
John Z Wudfaa4292018-09-07 01:10:2626} // namespace base
drogerbfba8a42014-12-16 21:58:1327
28namespace web {
John Z Wudfaa4292018-09-07 01:10:2629class NavigationContext;
John Z Wudfaa4292018-09-07 01:10:2630} // namespace web
drogerbfba8a42014-12-16 21:58:1331
32namespace translate {
33
34// TranslateController controls the translation of the page, by injecting the
35// translate scripts and monitoring the status.
36class 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 Wuae98b4a2018-08-27 22:32:2342 // |error_type| Indicates error code.
43 virtual void OnTranslateScriptReady(TranslateErrors::Type error_type,
drogerbfba8a42014-12-16 21:58:1344 double load_time,
45 double ready_time) = 0;
46
47 // Called when the translation is complete.
John Z Wuae98b4a2018-08-27 22:32:2348 // |error_type| Indicates error code.
49 virtual void OnTranslateComplete(TranslateErrors::Type error_type,
drogerbfba8a42014-12-16 21:58:1350 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
drogerbfba8a42014-12-16 21:58:1371 // Changes the JsTranslateManager used by this TranslateController.
72 // Only used for testing.
stkhapugin2393ab22017-01-20 15:34:4573 void SetJsTranslateManagerForTesting(JsTranslateManager* manager);
drogerbfba8a42014-12-16 21:58:1374
75 private:
76 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest,
77 OnJavascriptCommandReceived);
78 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest,
Olivier Robin7b03f402018-06-21 13:17:0479 OnIFrameJavascriptCommandReceived);
80 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest,
drogerbfba8a42014-12-16 21:58:1381 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 Wu7a1c7f12018-09-12 16:00:0986 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest, OnTranslateLoadJavascript);
John Z Wu8eb0e1492020-08-24 19:17:3887 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest,
88 OnTranslateSendRequestWithValidCommand);
89 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest,
90 OnTranslateSendRequestWithBadURL);
91 FRIEND_TEST_ALL_PREFIXES(TranslateControllerTest,
92 OnTranslateSendRequestWithBadMethod);
drogerbfba8a42014-12-16 21:58:1393
94 // Called when a JavaScript command is received.
95 bool OnJavascriptCommandReceived(const base::DictionaryValue& command,
96 const GURL& url,
Olivier Robin7b03f402018-06-21 13:17:0497 bool interacting,
Olivier Robin25206252018-09-11 09:09:4198 web::WebFrame* sender_frame);
drogerbfba8a42014-12-16 21:58:1399 // 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 Wudfaa4292018-09-07 01:10:26103 bool OnTranslateLoadJavaScript(const base::DictionaryValue& command);
John Z Wu31d0dd62018-11-02 00:59:29104 bool OnTranslateSendRequest(const base::DictionaryValue& command);
John Z Wudfaa4292018-09-07 01:10:26105
John Z Wudfaa4292018-09-07 01:10:26106 // The callback when the script is fetched or a server error occurred.
107 void OnScriptFetchComplete(std::unique_ptr<std::string> response_body);
John Z Wu31d0dd62018-11-02 00:59:29108 // 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);
drogerbfba8a42014-12-16 21:58:13114
115 // web::WebStateObserver implementation:
Sylvain Defresne3212e2a2017-10-18 21:32:49116 void WebStateDestroyed(web::WebState* web_state) override;
John Z Wudfaa4292018-09-07 01:10:26117 void DidStartNavigation(web::WebState* web_state,
118 web::NavigationContext* navigation_context) override;
drogerbfba8a42014-12-16 21:58:13119
Sylvain Defresne4051ebd2017-11-13 18:12:01120 // The WebState this instance is observing. Will be null after
121 // WebStateDestroyed has been called.
122 web::WebState* web_state_ = nullptr;
123
John Z Wu31d0dd62018-11-02 00:59:29124 // Used to fetch translate requests. There may be multiple requests in flight.
125 std::set<std::unique_ptr<network::SimpleURLLoader>> request_fetchers_;
John Z Wudfaa4292018-09-07 01:10:26126 // Used to fetch additional scripts needed for translate.
127 std::unique_ptr<network::SimpleURLLoader> script_fetcher_;
128
Yi Su77b7a812019-07-23 08:11:16129 // Subscription for JS message.
130 std::unique_ptr<web::WebState::ScriptCommandSubscription> subscription_;
131
drogerbfba8a42014-12-16 21:58:13132 Observer* observer_;
Sylvain Defresne2fc15b342020-03-02 17:29:40133 __strong JsTranslateManager* js_manager_;
drogerbfba8a42014-12-16 21:58:13134 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_