Implement splash screen 65/176465/7
authormin7.choi <min7.choi@samsung.com>
Thu, 19 Apr 2018 10:30:05 +0000 (19:30 +0900)
committermin7.choi <min7.choi@samsung.com>
Thu, 26 Apr 2018 08:50:30 +0000 (17:50 +0900)
Implementation of splash screen used in tizen.
now the hide screen is only implemented in complete.
first-paint and costom will be implemented later.
Also, the window state of the splash screen will be implemented later

Change-Id: I444f1be7dd04be46d5cd8edca5e022616d9020ff
Signed-off-by: min7.choi <min7.choi@samsung.com>
atom/app/ui_runtime.cc
atom/browser/api/atom_api_pwrt.cc
atom/browser/api/atom_api_pwrt.h
atom/browser/browser.cc
atom/browser/browser.h
atom/browser/splash_screen.cc [new file with mode: 0755]
atom/browser/splash_screen.h [new file with mode: 0755]
wrt.gyp
wrt/src/web_window.js

index 959e4ac..e13e1bf 100644 (file)
@@ -29,6 +29,8 @@
 #include "tizen/common/app_db.h"
 #include "tizen/common/app_control.h"
 #include "tizen/common/constants.h"
+#include "tizen/common/application_data.h"
+#include "tizen/common/command_line.h"
 
 #include "gin/v8_initializer.h"
 
@@ -51,6 +53,17 @@ void UiRuntime::SetParam(content::ContentMainParams *params) {
 }
 
 bool UiRuntime::OnCreate() {
+  common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess();
+  std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron");
+
+  auto appdata_manager = common::ApplicationDataManager::GetInstance();
+  common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid);
+
+  if(appdata->splash_screen_info()){
+    atom::Browser* browser_model = atom::Browser::Get();
+    browser_model->SetSplashScreen();
+  }
+
   return true;
 }
 
@@ -72,7 +85,7 @@ void UiRuntime::OnResume() {
 }
 
 void UiRuntime::OnAppControl(app_control_h app_control) {
-    LOG(ERROR) << "OnAppControl()";
+  LOG(ERROR) << "OnAppControl()";
   std::unique_ptr<common::AppControl>
       appcontrol(new common::AppControl(app_control));
   common::AppDB* appdb = common::AppDB::GetInstance();
@@ -102,6 +115,7 @@ int UiRuntime::Exec() {
   ops.create = [](void* data) -> bool {
     LOG(ERROR) << "Create Tizen App.";
     UiRuntime *runtime = (UiRuntime*)data;
+    runtime->OnCreate();
     content::ContentMain(*runtime->_params);
     return true;
   };
index 30213c5..aa7b785 100644 (file)
@@ -56,6 +56,12 @@ bool PWRT::isElectronLaunch() {
   return Browser::Get()->is_electron_launch();
 }
 
+void PWRT::HideSplashScreen(int reason) {
+  LOG(ERROR) << "PWRT::HideSplashScreen";
+  atom::Browser *browser_model = atom::Browser::Get();
+  browser_model->HideSplashScreen(reason);
+}
+
 void PWRT::Log(const std::string& message) {
   std::string output = "[JS LOG] " + message;
   dlog_print(DLOG_ERROR, "WRT", output.c_str());
@@ -78,6 +84,7 @@ void PWRT::BuildPrototype(
     .SetMethod("getPath", &PWRT::GetPath)
     .SetMethod("isTizenWebApp", &PWRT::isTizenWebApp)
     .SetMethod("isElectronLaunch", &PWRT::isElectronLaunch)
+    .SetMethod("hideSplashScreen", &PWRT::HideSplashScreen)
     .SetMethod("log", &PWRT::Log);
 }
 
index 8b67cc2..ab25f34 100644 (file)
@@ -20,6 +20,7 @@ class PWRT : public mate::TrackableObject<PWRT> {
   std::string GetPath();
   bool isTizenWebApp();
   bool isElectronLaunch();
+  void HideSplashScreen(int reason);
   void Log(const std::string& message);
 
  protected:
index 771cbee..3ebba72 100644 (file)
 #include "base/run_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "brightray/browser/brightray_paths.h"
+
+#if defined(OS_TIZEN)
 #include "tizen/common/command_line.h"
+#include "tizen/common/application_data.h"
+#include <Elementary.h>
+#include "wgt_manifest_handlers/launch_screen_handler.h"
+#endif  // defined(OS_TIZEN)
+
 namespace atom {
 
 Browser::Browser()
@@ -277,4 +284,34 @@ void Browser::Launch(std::unique_ptr<common::AppControl> appcontrol) {
 //To do:Implementation of relaunching of app
 }
 
+#if defined(OS_TIZEN)
+void Browser::SetSplashScreen() {
+  common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess();
+  std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron");
+
+  auto appdata_manager = common::ApplicationDataManager::GetInstance();
+  common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid);
+
+  Evas_Object* window_ = elm_win_util_standard_add("", "");
+
+  splash_screen_.reset(
+      new SplashScreen(
+        window_, appdata->splash_screen_info(), appdata->application_path()));
+}
+
+void Browser::HideSplashScreen(int reason) {
+  common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess();
+  std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/electron");
+
+  auto appdata_manager = common::ApplicationDataManager::GetInstance();
+  common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid);
+
+  if(appdata->splash_screen_info() == NULL) {
+    return;
+  }
+
+  splash_screen_->HideSplashScreen(reason);
+}
+#endif  // defined(OS_TIZEN)
+
 }  // namespace atom
index dfc4831..362bfaf 100644 (file)
 #include "tizen/common/application_data.h"
 #include "tizen/common/resource_manager.h"
 #include "tizen/common/locale_manager.h"
+#if defined(OS_TIZEN)
+#include "atom/browser/splash_screen.h"
+#endif  // defined(OS_TIZEN)
+
 
 #if defined(OS_WIN)
 #include "base/files/file_path.h"
@@ -48,6 +52,10 @@ class Browser : public WindowListObserver {
 
   std::unique_ptr<common::ResourceManager> resource_manager_;
   std::unique_ptr<common::LocaleManager> locale_manager_;
+#if defined(OS_TIZEN)
+  std::unique_ptr<SplashScreen> splash_screen_;
+#endif  // defined(OS_TIZEN)
+
 
   void Initialize();
   // Try to close all windows and quit the application.
@@ -117,6 +125,10 @@ class Browser : public WindowListObserver {
   void Show();
   void AppControl(std::unique_ptr<common::AppControl> appcontrol);
   void Launch(std::unique_ptr<common::AppControl> appcontrol);
+#if defined(OS_TIZEN)
+  void SetSplashScreen();
+  void HideSplashScreen(int reason);
+#endif  // defined(OS_TIZEN)
 
 #if defined(OS_MACOSX)
   // Hide the application.
diff --git a/atom/browser/splash_screen.cc b/atom/browser/splash_screen.cc
new file mode 100755 (executable)
index 0000000..d6c1751
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "atom/browser/splash_screen.h"
+
+#include <algorithm>
+#include <map>
+#include <string>
+
+#include <Evas_Legacy.h>
+
+#include "tizen/common/logger.h"
+
+//using ScreenOrientation = runtime::NativeWindow::ScreenOrientation;
+
+namespace {
+
+enum class BorderOption { REPEAT = 1, STRETCH, ROUND };
+
+// To do : The orientation will be implemented later.
+
+/*wgt::parse::ScreenOrientation ChooseOrientation(
+    const std::map<wgt::parse::ScreenOrientation,
+    wgt::parse::LaunchScreenData>& splash_map,
+    ScreenOrientation screen_orientation) {
+  auto orientation_pair = splash_map.end();
+
+  if (screen_orientation ==
+      runtime::NativeWindow::ScreenOrientation::PORTRAIT_PRIMARY ||
+      screen_orientation ==
+      runtime::NativeWindow::ScreenOrientation::PORTRAIT_SECONDARY) {
+    orientation_pair =
+         splash_map.find(wgt::parse::ScreenOrientation::PORTRAIT);
+  } else {
+    orientation_pair =
+        splash_map.find(wgt::parse::ScreenOrientation::LANDSCAPE);
+  }
+  if (orientation_pair == splash_map.end())
+        orientation_pair = splash_map.find(wgt::parse::ScreenOrientation::AUTO);
+
+  if (orientation_pair != splash_map.end()) return orientation_pair->first;
+  return wgt::parse::ScreenOrientation::NONE;
+}*/
+
+bool ParseImageBorder(const std::vector<std::string>& borders,
+                      std::vector<int>* border_values,
+                      std::vector<BorderOption>* border_options) {
+  std::map<std::string, BorderOption> scaling_string;
+  scaling_string["repeat"] = BorderOption::REPEAT;
+  scaling_string["stretch"] = BorderOption::STRETCH;
+  scaling_string["round"] = BorderOption::ROUND;
+
+  for (const auto& border : borders) {
+    std::string::size_type px_index = border.find("px");
+    if (px_index != std::string::npos) {
+      std::string border_value(border.begin(), border.begin() + px_index);
+      border_values->push_back(std::atoi(border_value.c_str()));
+    }
+    for (const auto& border_string_val : scaling_string) {
+      std::string::size_type index = border.find(border_string_val.first);
+      if (index != std::string::npos) {
+        border_options->push_back(border_string_val.second);
+      }
+    }
+  }
+
+  LOGGER(DEBUG) << "Image border values:";
+  for (const auto& border_value : *border_values) {
+    LOGGER(DEBUG) << border_value;
+  }
+  LOGGER(DEBUG) << "Image border scaling values:";
+  for (const auto& border_option : *border_options) {
+    LOGGER(DEBUG) << static_cast<int>(border_option);
+  }
+
+  return !border_values->empty() && !border_options->empty();
+}
+
+}  // namespace
+
+namespace atom {
+
+SplashScreen::SplashScreen(
+    Evas_Object* window,
+    //runtime::NativeWindow* window,
+    std::shared_ptr<const wgt::parse::LaunchScreenInfo> ss_info,
+    const std::string& app_path)
+    : ss_info_(ss_info),
+      window_(window),
+      image_(nullptr),
+      background_(nullptr),
+      background_image_(nullptr),
+      is_active_(false) {
+  if (ss_info == nullptr) return;
+
+  auto splash_map = ss_info->launch_screen_data();
+  /*auto used_orientation =
+      ChooseOrientation(splash_map, window->orientation());
+  if (used_orientation == wgt::parse::ScreenOrientation::NONE) return; */
+
+  auto dimensions = GetDimensions(window);
+
+ // To do : The orientation will be implemented later.
+  SetBackground(splash_map[wgt::parse::ScreenOrientation::AUTO], window,
+                     dimensions, app_path);
+  SetImage(splash_map[wgt::parse::ScreenOrientation::AUTO], window,
+                     dimensions, app_path);
+  is_active_ = true;
+}
+
+void SplashScreen::HideSplashScreen(int reason) {
+
+  if (!is_active_) return;
+  if (reason == HideReason::RENDERED &&
+      ss_info_->ready_when() != wgt::parse::ReadyWhen::FIRSTPAINT) {
+    return;
+  }
+  if (reason == HideReason::LOADFINISHED &&
+      ss_info_->ready_when() != wgt::parse::ReadyWhen::COMPLETE) {
+    return;
+  }
+  if (reason == HideReason::CUSTOM &&
+      ss_info_->ready_when() != wgt::parse::ReadyWhen::CUSTOM) {
+    return;
+  }
+
+  evas_object_hide(background_);
+  evas_object_hide(image_);
+  evas_object_hide(window_);
+  evas_object_del(background_);
+  evas_object_del(image_);
+  evas_object_hide(window_);
+  background_ = nullptr;
+  image_ = nullptr;
+  window_ = nullptr;
+  is_active_ = false;
+}
+
+std::pair<int, int> SplashScreen::GetDimensions(Evas_Object* window) {
+  int w, h;
+  elm_win_screen_size_get(window, NULL, NULL, &w, &h);
+  evas_object_resize(background_, w, h);
+  return std::make_pair(w, h);
+}
+
+void SplashScreen::SetBackground(
+    const wgt::parse::LaunchScreenData& splash_data, Evas_Object* parent,
+    const SplashScreenBound& bound, const std::string& app_path) {
+  background_ = elm_bg_add(parent);
+  if (!background_) return;
+  evas_object_resize(background_, bound.first, bound.second);
+
+  if (splash_data.background_color != nullptr) {
+    elm_bg_color_set(background_,
+                     splash_data.background_color->red,
+                     splash_data.background_color->green,
+                     splash_data.background_color->blue);
+  }
+
+  std::vector<int> border_values;
+  std::vector<BorderOption> border_options;
+
+  if (!splash_data.background_images.empty() &&
+      ParseImageBorder(
+          splash_data.image_border, &border_values, &border_options)) {
+    const std::string& background_image_path =
+        splash_data.background_images.front().first;
+
+    background_image_ = elm_image_add(background_);
+    evas_object_image_file_set(background_image_,
+                               (app_path + background_image_path).c_str(),
+                               NULL);
+    elm_image_aspect_fixed_set(background_image_, 0);
+    evas_object_image_border_center_fill_set(background_image_,
+                                             EVAS_BORDER_FILL_DEFAULT);
+
+    evas_object_resize(background_image_, bound.first, bound.second);
+
+    int border_l, border_r, border_t, border_b;
+    switch (border_values.size()) {
+      case 1:
+        border_l = border_r = border_t = border_b = -border_values[0];
+        break;
+      case 2:
+        border_t = border_b =  border_values[0];
+        border_l = border_r =  border_values[1];
+        break;
+      case 4:
+        border_t = border_values[0];
+        border_r = border_values[1];
+        border_b = border_values[2];
+        border_l = border_values[3];
+        break;
+      default:
+        border_l = border_r = border_t = border_b = 0;
+    }
+    evas_object_image_border_set(background_image_,
+                                 border_l,
+                                 border_r,
+                                 border_t,
+                                 border_b);
+    // TODO(a.szulakiewi): add scaling of horizontal and vertical borders
+  }
+
+  evas_object_show(background_);
+  evas_object_show(background_image_);
+  evas_object_show(parent);
+}
+
+void SplashScreen::SetImage(
+    const wgt::parse::LaunchScreenData& splash_data, Evas_Object* parent,
+    const SplashScreenBound& bound, const std::string& app_path) {
+  if (!background_) return;
+  image_ = elm_image_add(background_);
+  if (!image_) return;
+
+  if (splash_data.images.empty()) return;
+
+  const std::string& image_path = splash_data.images.front().first;
+  elm_image_file_set(image_, (app_path + image_path).c_str(), NULL);
+  evas_object_resize(image_, bound.first, bound.second);
+  evas_object_show(image_);
+  evas_object_show(parent);
+}
+}  // namespace atom
diff --git a/atom/browser/splash_screen.h b/atom/browser/splash_screen.h
new file mode 100755 (executable)
index 0000000..593ff06
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef XWALK_RUNTIME_BROWSER_SPLASH_SCREEN_H_
+#define XWALK_RUNTIME_BROWSER_SPLASH_SCREEN_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+#include <string>
+#include <vector>
+
+#include <Elementary.h>
+#include "wgt_manifest_handlers/launch_screen_handler.h"
+
+enum HideReason { RENDERED, LOADFINISHED, CUSTOM };
+
+namespace atom {
+
+enum class ScreenOrientation {
+  PORTRAIT_PRIMARY = 0,
+  PORTRAIT_SECONDARY = 1,
+  LANDSCAPE_PRIMARY = 2,
+  LANDSCAPE_SECONDARY = 3,
+  NATURAL = 4,
+  ANY = 5
+};
+
+class SplashScreen {
+ public:
+  typedef std::pair<int, int> SplashScreenBound;
+
+  SplashScreen(Evas_Object* window,
+               std::shared_ptr<const wgt::parse::LaunchScreenInfo> ss_info,
+               const std::string& app_path);
+  void HideSplashScreen(int reason);
+
+ private:
+  std::pair<int, int> GetDimensions(Evas_Object* window);
+  void SetBackground(const wgt::parse::LaunchScreenData& splash_data,
+                     Evas_Object* parent, const SplashScreenBound& bound,
+                     const std::string& app_path);
+
+  void SetImage(const wgt::parse::LaunchScreenData& splash_data,
+                Evas_Object* parent, const SplashScreenBound& bound,
+                const std::string& app_path);
+
+  std::shared_ptr<const wgt::parse::LaunchScreenInfo> ss_info_;
+  Evas_Object* window_;
+  Evas_Object* image_;
+  Evas_Object* background_;
+  Evas_Object* background_image_;
+  bool is_active_;
+};
+}  // namespace atom
+#endif  // XWALK_RUNTIME_BROWSER_SPLASH_SCREEN_H_
diff --git a/wrt.gyp b/wrt.gyp
index 54377cf..d8528b0 100644 (file)
--- a/wrt.gyp
+++ b/wrt.gyp
@@ -27,6 +27,8 @@
         'tizen/src/wrt_main.h',
         'tizen/loader/prelauncher.h',
         'tizen/loader/prelauncher.cc',
+        'atom/browser/splash_screen.h',
+        'atom/browser/splash_screen.cc',
       ],
       'include_dirs': [
         'tizen/src',
index 5258234..06b1f31 100644 (file)
@@ -1,5 +1,5 @@
 'use strict';
-const {BrowserWindow, app} = require('electron');
+const {BrowserWindow, app, pwrt} = require('electron');
 const IPC_MESSAGE = require('./ipc_message');
 const WAS_EVENT = require('./was_event');
 const events = require('./events');
@@ -121,6 +121,8 @@ class WebWindow {
         });
         this.mainWindow.webContents.on('did-finish-load', function() {
             webwindow_debug('WebWindow : webContents did-finish-load');
+            pwrt.hideSplashScreen(1);
+
             if(!options.show){
                 webwindow_debug('WebWindow : browserWindow show options is ',options.show);
                 self.show();