[WRTjs][VD]Apply preconnect feature 06/317206/11
authorYoungman Son <yman.son@samsung.com>
Thu, 5 Sep 2024 12:32:43 +0000 (21:32 +0900)
committerBot Blink <blinkbot@samsung.com>
Mon, 9 Sep 2024 07:49:09 +0000 (07:49 +0000)
preconnect consists of four stages.
1. URL to be accessed in advance is loaded from a file.
2. WebApp attempts to establish a server connection at its initial
   stage of execution.
3. Collect a list of servers connected.
4. Save server list to a file

Pre-connected servers have an effect of reducing the waiting time
for URL requests.
As a result, launching performance is improved.

Analysis result
https://confluence.sec.samsung.net/x/k-8cIw
https://jira.sec.samsung.net/browse/WEB-2553

Change-Id: Ic5fc8105f5fcf0df6430ea48fce28f600d572d38
Signed-off-by: Youngman Son <yman.son@samsung.com>
chrome/browser/predictors/preconnect_manager.h
wrt/BUILD.gn
wrt/filenames.gni
wrt/src/browser/net/tv/encrypted_file_url_loader.cc
wrt/src/browser/tv/native_web_runtime_delegate_tv.cc
wrt/src/browser/tv/wrt_browser_context_tv.cc
wrt/src/browser/tv/wrt_browser_context_tv.h
wrt/src/common/tv/application_data_tv.cc
wrt/src/common/tv/application_data_tv.h
wrt/src/common/tv/preconnect_manager_tv.cc [new file with mode: 0755]
wrt/src/common/tv/preconnect_manager_tv.h [new file with mode: 0755]

index 2f079f4b9144b3e01749f54f553b06262e38627e..a67f95f72dc95882f97290b6410dcc1550418819 100644 (file)
@@ -224,7 +224,11 @@ class PreconnectManager {
 
   // Whether the PreconnectManager should be performing preloading operations
   // or if preloading is disabled.
+#if defined(ENABLE_WRT_JS) && BUILDFLAG(IS_TIZEN_TV)
+  virtual bool IsEnabled();
+#else
   bool IsEnabled();
+#endif
   void TryToLaunchPreresolveJobs();
   void OnPreresolveFinished(PreresolveJobId job_id, bool success);
   void OnProxyLookupFinished(PreresolveJobId job_id, bool success);
index 20a57298957af3d291dfe1c6a5ef20ae96ef809f..4094d71d4c6aba6b2a877698b20b8d61c84dbb6c 100644 (file)
@@ -400,10 +400,14 @@ static_library("wrt_lib") {
     sources += [
       "//chrome/browser/app_mode/app_mode_utils.cc",
       "//chrome/browser/app_mode/app_mode_utils.h",
+      "//chrome/browser/battery/battery_saver.cc",
+      "//chrome/browser/battery/battery_saver.h",
       "//chrome/browser/browser_features.cc",
       "//chrome/browser/browser_features.h",
       "//chrome/browser/browser_process.cc",
       "//chrome/browser/browser_process.h",
+      "//chrome/browser/data_saver/data_saver.cc",
+      "//chrome/browser/data_saver/data_saver.h",
       "//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
       "//chrome/browser/devtools/devtools_contents_resizing_strategy.h",
       "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc",
@@ -421,8 +425,22 @@ static_library("wrt_lib") {
       "//chrome/browser/net/proxy_config_monitor.h",
       "//chrome/browser/net/proxy_service_factory.cc",
       "//chrome/browser/net/proxy_service_factory.h",
+      "//chrome/browser/predictors/preconnect_manager.cc",
+      "//chrome/browser/predictors/preconnect_manager.h",
+      "//chrome/browser/predictors/proxy_lookup_client_impl.cc",
+      "//chrome/browser/predictors/proxy_lookup_client_impl.h",
+      "//chrome/browser/predictors/resolve_host_client_impl.cc",
+      "//chrome/browser/predictors/resolve_host_client_impl.h",
+      "//chrome/browser/predictors/resource_prefetch_predictor.cc",
+      "//chrome/browser/predictors/resource_prefetch_predictor.h",
+      "//chrome/browser/prefetch/pref_names.cc",
+      "//chrome/browser/prefetch/pref_names.h",
+      "//chrome/browser/preloading/preloading_prefs.cc",
+      "//chrome/browser/preloading/preloading_prefs.h",
       "//chrome/browser/process_singleton.h",
       "//chrome/browser/process_singleton_posix.cc",
+      "//chrome/browser/profiles/profile.cc",
+      "//chrome/browser/profiles/profile.h",
       "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc",
       "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h",
       "//chrome/browser/ui/exclusive_access/exclusive_access_manager.cc",
index d04f2349513c91978580699b62af7fb468baae86..f361bc995333e9291e2a678993bfea67c2158a44 100644 (file)
@@ -223,6 +223,8 @@ wrt_lib_sources_tv = [
   "src/browser/tv/wrt_xwalk_extension_browser_tv.h",
   "src/common/tv/application_data_tv.cc",
   "src/common/tv/application_data_tv.h",
+  "src/common/tv/preconnect_manager_tv.cc",
+  "src/common/tv/preconnect_manager_tv.h",
   "src/common/tv/wrt_profiler.cc",
   "src/common/tv/wrt_profiler.h",
   "src/common/tv/wrt_lib_wrapper.cc",
index 01de7ecedda015f1e83df9fd87f480242eaa3d3c..e266ac885385185c65c7f5fce1d30f66b2b298cc 100755 (executable)
@@ -269,6 +269,9 @@ WRTProxyingURL ParseEncryptedURL(const GURL& url) {
     return WRTProxyingURL(GURL(url_str));
   }
 
+  if (url.SchemeIsHTTPOrHTTPS())
+    ApplicationDataTV::GetInstance().AddPreconnectURL(url.host());
+
   if (!url.SchemeIs(url::kFileScheme) && !url.SchemeIs("app"))
     return WRTProxyingURL(GURL());
 
index 1d4e58da966a5603e9f05e547e013299a0cd2f11..bf6aa744ef6ffea1b488a00112d7a5c069c3fd94 100644 (file)
@@ -340,6 +340,7 @@ void NativeWebRuntimeDelegateTV::Finalize() {
       != POWER_ERROR_NONE)
     LOG(WARNING) << "failed to unregister state changed event callback";
   ClearTmpFolder();
+  ApplicationDataTV::GetInstance().StorePreconnectURL();
 }
 
 void NativeWebRuntimeDelegateTV::RequestQuit() {
@@ -679,6 +680,7 @@ void NativeWebRuntimeDelegateTV::PepperUpdatePluginService() {
 void NativeWebRuntimeDelegateTV::PreSetupOnWorker() {
   LOG(INFO) << "PreSetupOnWorker";
   auto& app_data = ApplicationDataTV::GetInstance();
+  app_data.LoadPreconnectURL();
   auto is_local_app = !app_data.IsHostedApp();
   auto has_splash_screen =
       app_data.launch_screen_info().HasLaunchScreenData() ||
index 52804a5c76e00b0655b71d5b87ec0e1968a2dad6..7a57191d11d891810270c9a7c2700b39a65959c3 100644 (file)
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "wrt/src/browser/tv/wrt_browser_context_tv.h"
+#include "wrt/src/common/tv/application_data_tv.h"
 
 namespace wrt {
 
@@ -11,10 +12,34 @@ WRTBrowserContextTV::WRTBrowserContextTV(
     bool in_memory,
     base::Value::Dict options)
     : WRTBrowserContext(partition_location, in_memory, std::move(options)),
-      web_cache_manager_(this) {}
+      web_cache_manager_(this) {
+  HandlePreconnectUrls();
+}
 
 void WRTBrowserContextTV::ClearWebCache() {
   web_cache_manager_.ClearCache();
 }
 
+void WRTBrowserContextTV::HandlePreconnectUrls() {
+  auto& app_data_tv = ApplicationDataTV::GetInstance();
+  auto content_src = app_data_tv.content_info().src();
+  const GURL home_url(content_src);
+  std::vector<predictors::PreconnectRequest> requests;
+  auto preconnect_url = app_data_tv.GetStoredPreconnectURL();
+  if (preconnect_url.empty())
+    return;
+
+  for (unsigned int i = 0; i < preconnect_url.size(); i++) {
+    GURL url(std::string("https://" + preconnect_url[i]));
+    auto origin = url::Origin::Create(url);
+    requests.push_back({origin, 1,
+                        net::NetworkAnonymizationKey::CreateSameSite(
+                            net::SchemefulSite(origin))});
+  }
+  LOG(INFO) << "start PreconnectUrls!";
+  preconnect_manager_ = std::make_unique<PreconnectManagerTV>(this);
+  if (preconnect_manager_)
+    preconnect_manager_->Start(home_url, requests);
+}
+
 }  // namespace wrt
index f3015fe631a6f5d06446685894f7e8817dfefe05..5a5cc91bdc6ffccf53861a63cba3e7818f5fcc23 100644 (file)
@@ -8,6 +8,7 @@
 #include "wrt/src/browser/wrt_browser_context.h"
 
 #include "tizen_src/ewk/efl_integration/browser/web_cache_efl/web_cache_manager_efl.h"
+#include "wrt/src/common/tv/preconnect_manager_tv.h"
 
 namespace wrt {
 
@@ -23,8 +24,10 @@ class WRTBrowserContextTV : public WRTBrowserContext {
 
  private:
   void ClearWebCache() override;
+  void HandlePreconnectUrls();
 
   WebCacheManagerEfl web_cache_manager_;
+  std::unique_ptr<PreconnectManagerTV> preconnect_manager_;
 };
 
 }  // namespace wrt
index 9599900b56a0d97cd67751e20cf2d24efa60f151..a8460e2b264acadf4069eb8372540cfe23cd8ca4 100755 (executable)
@@ -9,6 +9,7 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "base/strings/string_split.h"
 #include "tizen_src/ewk/efl_integration/common/content_switches_efl.h"
 #include "wrt/src/base/file_utils.h"
 #include "wrt/src/common/constants.h"
@@ -23,6 +24,7 @@ const char* kWidgetLicense = "widget.license";
 const char* kWrtPatchedTpkResPath = "/wrt";
 const char* kWrtUpgradedTpkResPath = "/upgrade/wrt";
 const char* kHomeOwnerAppsRW = "/home/owner/apps_rw/";
+const int kMaxPreconnectURL = 5;
 
 base::FilePath GetBackupConfigXml(const std::string& bath_path) {
   auto config_xml = base::FilePath(bath_path).DirName().Append("config.xml");
@@ -40,6 +42,7 @@ ApplicationDataTV::ApplicationDataTV() {
       base::FilePath(kHomeOwnerAppsRW).Append(pkg_id_).Append("data");
   if (!base::PathExists(user_data_path_))
     user_data_path_ = base::FilePath(kAlternativeDataDir).Append(app_id_);
+  preconnect_stored_path_ = user_data_path_.Append("preconnect.list");
 
   LOG(INFO) << "user_data_path_ : " << user_data_path_;
   LOG(INFO) << "backup_config_xml_ : " << backup_config_xml_;
@@ -95,6 +98,60 @@ std::string ApplicationDataTV::PointDeviceOption() {
   return setting_info().pointing_device_option();
 }
 
+void ApplicationDataTV::LoadPreconnectURL() {
+  if (!stored_preconnect_url_.empty())
+    return;
+
+  if (!base::PathExists(preconnect_stored_path_)) {
+    LOG(INFO) << "There is no file : " << preconnect_stored_path_;
+    return;
+  }
+
+  std::string content;
+  base::ReadFileToString(preconnect_stored_path_, &content);
+  if (content.empty()) {
+    LOG(INFO) << "File is empty";
+    return;
+  }
+  stored_preconnect_url_ = base::SplitString(
+      content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  LOG(INFO) << "preconnect list loaded count=" << stored_preconnect_url_.size();
+}
+
+void ApplicationDataTV::AddPreconnectURL(const std::string& url) {
+  if (url.empty() || loaded_preconnect_url_.size() >= kMaxPreconnectURL)
+    return;
+
+  if (std::find(loaded_preconnect_url_.begin(), loaded_preconnect_url_.end(),
+                url) != loaded_preconnect_url_.end()) {
+    return;
+  }
+
+  loaded_preconnect_url_.push_back(url);
+  LOG(INFO) << "push url : " << url;
+
+  if (loaded_preconnect_url_.size() == kMaxPreconnectURL)
+    StorePreconnectURL();
+}
+
+void ApplicationDataTV::StorePreconnectURL() {
+  static bool write_file = false;
+  if (write_file)
+    return;
+
+  if (stored_preconnect_url_ == loaded_preconnect_url_) {
+    LOG(INFO) << "Skip to store if without any changes";
+    write_file = true;
+    return;
+  }
+
+  auto content = base::JoinString(loaded_preconnect_url_, "\n");
+  if (base::WriteFile(preconnect_stored_path_, content) > 0) {
+    LOG(INFO) << "Stored well : " << preconnect_stored_path_;
+    write_file = true;
+  }
+}
+
 // static
 ApplicationDataTV& ApplicationDataTV::GetInstance() {
   return static_cast<ApplicationDataTV&>(ApplicationData::GetInstance());
index eddd509a18426520d762fd5fa7ca3e1c63236722..79e0a594cd50a5403c7634e3acd1311df5bbde87 100755 (executable)
@@ -28,11 +28,21 @@ class ApplicationDataTV : public ApplicationData {
     return video_splash_screen_info_;
   }
 
+  void AddPreconnectURL(const std::string& url);
+  void LoadPreconnectURL();
+  void StorePreconnectURL();
+  std::vector<std::string> GetStoredPreconnectURL() {
+    return stored_preconnect_url_;
+  }
+
  private:
   void PostParseManifestData(wgt::parse::WidgetConfigParser* parser) override;
 
   absl::optional<bool> widget_license_exist_;
   VideoSplashScreenInfo video_splash_screen_info_;
+  std::vector<std::string> stored_preconnect_url_;
+  std::vector<std::string> loaded_preconnect_url_;
+  base::FilePath preconnect_stored_path_;
 };
 
 }  // namespace wrt
diff --git a/wrt/src/common/tv/preconnect_manager_tv.cc b/wrt/src/common/tv/preconnect_manager_tv.cc
new file mode 100755 (executable)
index 0000000..50b6600
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "wrt/src/common/tv/preconnect_manager_tv.h"
+
+namespace wrt {
+
+PreconnectManagerTV::PreconnectManagerTV(
+    content::BrowserContext* browser_context)
+    : predictors::PreconnectManager(nullptr, browser_context) {}
+
+PreconnectManagerTV::~PreconnectManagerTV() = default;
+
+}  // namespace wrt
\ No newline at end of file
diff --git a/wrt/src/common/tv/preconnect_manager_tv.h b/wrt/src/common/tv/preconnect_manager_tv.h
new file mode 100755 (executable)
index 0000000..5245e2d
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_PRECONNECT_MANAGER_TV_H_
+#define COMMON_PRECONNECT_MANAGER_TV_H_
+
+#include "chrome/browser/predictors/preconnect_manager.h"
+
+namespace wrt {
+
+class PreconnectManagerTV : public predictors::PreconnectManager {
+ public:
+  PreconnectManagerTV(content::BrowserContext* browser_context);
+  ~PreconnectManagerTV() override;
+
+ private:
+  bool IsEnabled() override { return true; }
+};
+
+}  // namespace wrt
+
+#endif  // COMMON_PRECONNECT_MANAGER_TV_H_
\ No newline at end of file