Apply to Web IME
authorJongHeon Choi <j-h.choi@samsung.com>
Wed, 25 May 2016 05:15:10 +0000 (14:15 +0900)
committerJongHeon Choi <j-h.choi@samsung.com>
Mon, 30 May 2016 01:11:33 +0000 (10:11 +0900)
17 files changed:
common/application_data.cc
common/application_data.h
common/common.gyp
packaging/crosswalk-tizen.spec
runtime/browser/ime_application.cc [new file with mode: 0644]
runtime/browser/ime_application.h [new file with mode: 0644]
runtime/browser/ime_runtime.cc [new file with mode: 0644]
runtime/browser/ime_runtime.h [new file with mode: 0644]
runtime/browser/native_ime_window.cc [new file with mode: 0644]
runtime/browser/native_ime_window.h [new file with mode: 0644]
runtime/browser/runtime.cc
runtime/browser/runtime.h
runtime/browser/runtime_process.cc
runtime/browser/ui_runtime.cc [new file with mode: 0755]
runtime/browser/ui_runtime.h [new file with mode: 0644]
runtime/browser/web_application.cc
runtime/runtime.gyp

index c5058af..bb02984 100644 (file)
@@ -34,6 +34,10 @@ const char* kPathSeparator = "/";
 const char* kConfigXml = "config.xml";
 const char* kResWgtPath = "res/wgt";
 
+#ifdef IME_FEATURE_SUPPORT
+const char* kImeCategory = "http://tizen.org/category/ime";
+#endif  // IME_FEATURE_SUPPORT
+
 static std::string GetPackageIdByAppId(const std::string& appid) {
   char* pkgid = NULL;
   package_manager_get_package_id_by_app_id(appid.c_str(), &pkgid);
@@ -149,6 +153,22 @@ std::shared_ptr<const wgt::parse::CSPInfo>
 }
 
 
+ApplicationData::AppType ApplicationData::GetAppType() {
+  if (category_info_list_) {
+    auto category_list = category_info_list_->categories;
+    auto it = category_list.begin();
+    auto end = category_list.end();
+    for (; it != end; ++it) {
+#ifdef IME_FEATURE_SUPPORT
+      if (*it == kImeCategory) {
+        return IME;
+      }
+#endif  // IME_FEATURE_SUPPORT
+    }
+  }
+  return UI;
+}
+
 bool ApplicationData::LoadManifestData() {
   SCOPE_PROFILE();
   std::string config_xml_path(application_path_ + kConfigXml);
@@ -239,6 +259,8 @@ bool ApplicationData::LoadManifestData() {
     setting_info_.reset(new wgt::parse::SettingInfo);
   }
 
+  app_type_ = GetAppType();
+
   return true;
 }
 
index ebe9e4a..6032ca1 100644 (file)
@@ -41,6 +41,13 @@ namespace common {
 
 class ApplicationData {
  public:
+  enum AppType {
+    UI = 0
+#ifdef IME_FEATURE_SUPPORT
+    ,IME
+#endif  // IME_FEATURE_SUPPORT
+  };
+
   explicit ApplicationData(const std::string& appid);
   ~ApplicationData();
 
@@ -76,6 +83,7 @@ class ApplicationData {
   const std::string application_path() const { return application_path_; }
   const std::string pkg_id() const { return pkg_id_; }
   const std::string app_id() const { return app_id_; }
+  ApplicationData::AppType app_type() { return app_type_; }
 
  private:
   std::shared_ptr<const wgt::parse::AppControlInfoList>
@@ -104,10 +112,12 @@ class ApplicationData {
     csp_info_;
   std::shared_ptr<const wgt::parse::CSPInfo>
     csp_report_info_;
+  ApplicationData::AppType GetAppType();
 
   std::string application_path_;
   std::string pkg_id_;
   std::string app_id_;
+  ApplicationData::AppType app_type_;
 };
 
 
index ac3327c..925e756 100644 (file)
           'ttrace',
         ],
       },
+      'conditions': [
+        ['tizen_feature_web_ime_support == 1', {
+          'defines': ['IME_FEATURE_SUPPORT'],
+        }],
+      ],
       'direct_dependent_settings': {
         'libraries': [
           '-lxwalk_tizen_common',
index 5324e3e..d338a4f 100755 (executable)
@@ -46,14 +46,21 @@ BuildRequires: pkgconfig(jsoncpp)
 
 %if "%{?profile}" == "mobile"
 %define tizen_feature_rotary_event_support     0
+%define tizen_feature_web_ime_support          0
 %endif
 
 %if "%{?profile}" == "wearable"
 %define tizen_feature_rotary_event_support     1
+%define tizen_feature_web_ime_support          1
 %endif
 
 %if "%{?profile}" == "tv"
 %define tizen_feature_rotary_event_support     0
+%define tizen_feature_web_ime_support          1
+%endif
+
+%if 0%{?tizen_feature_web_ime_support}
+BuildRequires: pkgconfig(capi-ui-inputmethod)
 %endif
 
 
@@ -81,6 +88,7 @@ GYP_OPTIONS="$GYP_OPTIONS -Dbuild_type=Release"
 
 # Feature flags
 GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_rotary_event_support=%{?tizen_feature_rotary_event_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_web_ime_support=%{?tizen_feature_web_ime_support}"
 
 # Extension Path
 GYP_OPTIONS="$GYP_OPTIONS -Dextension_path=%{extension_path}"
diff --git a/runtime/browser/ime_application.cc b/runtime/browser/ime_application.cc
new file mode 100644 (file)
index 0000000..4d3a8ed
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 <memory>
+
+#include "common/application_data.h"
+#include "common/logger.h"
+#include "runtime/browser/native_window.h"
+#include "runtime/browser/web_view.h"
+#include "runtime/browser/ime_application.h"
+
+namespace runtime {
+
+ImeApplication::ImeApplication(
+    NativeWindow* window, common::ApplicationData* app_data)
+    : WebApplication(window, app_data) {
+}
+
+ImeApplication::~ImeApplication() {
+}
+
+// override
+void ImeApplication::OnLoadFinished(WebView* view) {
+  this->WebApplication::OnLoadFinished(view);
+
+  LOGGER(DEBUG) << "LoadFinished";
+  const char* kImeActivateFunctionCallScript =
+      "(function(){WebHelperClient.impl.activate();})()";
+  view->EvalJavascript(kImeActivateFunctionCallScript);
+}
+
+}  // namespace runtime
diff --git a/runtime/browser/ime_application.h b/runtime/browser/ime_application.h
new file mode 100644 (file)
index 0000000..05ad041
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_IME_APPLICATION_H_
+#define XWALK_RUNTIME_BROWSER_IME_APPLICATION_H_
+
+#include <functional>
+#include <list>
+#include <memory>
+#include <string>
+
+#include "runtime/browser/web_view.h"
+#include "runtime/browser/native_window.h"
+#include "runtime/browser/web_application.h"
+
+namespace runtime {
+
+class ImeApplication : public WebApplication {
+ public:
+  ImeApplication(
+    NativeWindow* window, common::ApplicationData* app_data);
+  virtual ~ImeApplication();
+ protected:
+  virtual void OnLoadFinished(WebView* view);  // override
+};
+
+}  // namespace runtime
+
+#endif  // XWALK_RUNTIME_BROWSER_IME_APPLICATION_H_
diff --git a/runtime/browser/ime_runtime.cc b/runtime/browser/ime_runtime.cc
new file mode 100644 (file)
index 0000000..e588314
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * 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 <ewk_chromium.h>
+#include <Elementary.h>
+#include <inputmethod.h>
+
+#include <memory>
+#include <string>
+
+#include "common/application_data.h"
+#include "common/app_control.h"
+#include "common/app_db.h"
+#include "common/command_line.h"
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "runtime/common/constants.h"
+#include "runtime/browser/native_ime_window.h"
+#include "runtime/browser/preload_manager.h"
+#include "runtime/browser/runtime.h"
+#include "runtime/browser/ime_runtime.h"
+
+namespace runtime {
+
+namespace {
+
+static NativeWindow* CreateNativeWindow() {
+  SCOPE_PROFILE();
+  NativeWindow* window = NULL;
+  auto cached = PreloadManager::GetInstance()->GetCachedNativeWindow();
+  if (cached != nullptr) {
+    delete cached;
+  }
+  window = new NativeImeWindow();
+  window->Initialize();
+
+  return window;
+}
+
+}  // namespace
+
+ImeRuntime::ImeRuntime(common::ApplicationData* app_data)
+    : application_(NULL),
+      native_window_(NULL),
+      app_data_(app_data) {
+}
+
+ImeRuntime::~ImeRuntime() {
+  if (application_) {
+    delete application_;
+  }
+  if (native_window_) {
+    delete native_window_;
+  }
+}
+
+static Evas_Object *enter_key_btn = NULL;
+
+static void set_return_key_type(Ecore_IMF_Input_Panel_Return_Key_Type type)
+{
+  switch (type) {
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE:
+    elm_object_text_set(enter_key_btn, "Done");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO:
+    elm_object_text_set(enter_key_btn, "Go");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN:
+    elm_object_text_set(enter_key_btn, "Join");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN:
+    elm_object_text_set(enter_key_btn, "Login");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT:
+    elm_object_text_set(enter_key_btn, "Next");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH:
+    elm_object_text_set(enter_key_btn, "Search");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND:
+    elm_object_text_set(enter_key_btn, "Send");
+    break;
+  case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN:
+    elm_object_text_set(enter_key_btn, "Sign in");
+    break;
+  default:
+    elm_object_text_set(enter_key_btn, "Enter");
+    break;
+  }
+}
+
+void ImeRuntime::OnAppControl() {
+  std::unique_ptr<common::AppControl>
+      appcontrol(new common::AppControl());
+  appcontrol->set_operation("http://tizen.org/appcontrol/operation/default");
+  common::AppDB* appdb = common::AppDB::GetInstance();
+  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeBundle,
+             appcontrol->encoded_bundle());
+  if (application_->launched()) {
+    application_->AppControl(std::move(appcontrol));
+  } else {
+    application_->Launch(std::move(appcontrol));
+  }
+}
+
+void ImeRuntime::OnCreate() {
+  STEP_PROFILE_END("ime_app_main -> OnCreate");
+  STEP_PROFILE_END("Start -> OnCreate");
+  STEP_PROFILE_START("OnCreate -> URL Set");
+
+  common::CommandLine* cmd = common::CommandLine::ForCurrentProcess();
+  std::string appid = cmd->GetAppIdFromCommandLine(kRuntimeExecName);
+
+  // Init AppDB for Runtime
+  common::AppDB* appdb = common::AppDB::GetInstance();
+  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeName, "xwalk-tizen");
+  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeAppID, appid);
+  appdb->Remove(kAppDBRuntimeSection, kAppDBRuntimeBundle);
+
+  // Init ImeApplication
+  native_window_ = CreateNativeWindow();
+  STEP_PROFILE_START("ImeApplication Create");
+  application_ = new ImeApplication(native_window_, app_data_);
+  STEP_PROFILE_END("ImeApplication Create");
+
+  setlocale(LC_ALL, "");
+  bindtextdomain(kTextDomainRuntime, kTextLocalePath);
+
+  LOGGER(DEBUG) << "ime_app_create";
+  int w, h;
+
+  Evas_Object *ime_window = native_window_->evas_object();
+  if (!ime_window) {
+    LOGGER(DEBUG) << "Can't get main window: " << get_last_result();
+    return;
+  }
+  elm_win_screen_size_get(ime_window, NULL, NULL, &w, &h);
+  LOGGER(DEBUG) << "w : " << w << ", h : " << h;
+  if (w <= 0)
+    w = 720;
+  if (h <= 0)
+    h = 1280;
+  ime_set_size(w, h*2/5, h, w*3/5);
+
+  OnAppControl();
+}
+
+void ImeRuntime::OnTerminate() {
+  LOGGER(DEBUG) << "ime_app_terminate";
+}
+
+void ImeRuntime::OnShow(int context_id, ime_context_h context) {
+  Ecore_IMF_Input_Panel_Layout layout;
+  ime_layout_variation_e layout_variation;
+  int cursor_pos;
+  Ecore_IMF_Autocapital_Type autocapital_type;
+  Ecore_IMF_Input_Panel_Return_Key_Type return_key_type;
+  bool return_key_state, prediction_mode, password_mode;
+
+  LOGGER(DEBUG) << "ime_app_show";
+
+  if (ime_context_get_layout(
+        context, &layout) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "layout: " << layout;
+  if (ime_context_get_layout_variation(
+        context, &layout_variation) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "layout variation: " << layout_variation;
+  if (ime_context_get_cursor_position(
+        context, &cursor_pos) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "cursor position: " << cursor_pos;
+  if (ime_context_get_autocapital_type(
+        context, &autocapital_type) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "autocapital_type: " << autocapital_type;
+  if (ime_context_get_return_key_type(
+        context, &return_key_type) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "return_key_type: " << return_key_type;
+  if (ime_context_get_return_key_state(
+        context, &return_key_state) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "return_key_state: " << return_key_state;
+  if (ime_context_get_prediction_mode(
+        context, &prediction_mode) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "prediction_mode: " << prediction_mode;
+  if (ime_context_get_password_mode(
+        context, &password_mode) == IME_ERROR_NONE)
+    LOGGER(DEBUG) << "password_mode: " << password_mode;
+
+  set_return_key_type(return_key_type);
+}
+
+void ImeRuntime::OnHide(int context_id) {
+  LOGGER(DEBUG) << "ime_app_hide";
+}
+
+static void ime_app_focus_in_cb(int ic, void *user_data)
+{
+  LOGGER(DEBUG) << "focus in: " << ic;
+}
+
+static void ime_app_focus_out_cb(int ic, void *user_data)
+{
+  LOGGER(DEBUG) << "focus out: " << ic;
+}
+
+static void ime_app_cursor_position_updated_cb(
+    int cursor_pos, void *user_data)
+{
+  LOGGER(DEBUG) << "cursor position: " << cursor_pos;
+}
+
+static void ime_app_return_key_type_set_cb(
+    Ecore_IMF_Input_Panel_Return_Key_Type type, void *user_data)
+{
+  LOGGER(DEBUG) << "Return key type: " << type;
+
+  set_return_key_type(type);
+}
+
+static void ime_app_return_key_state_set_cb(
+    bool disabled, void *user_data)
+{
+  LOGGER(DEBUG) << "Return key disabled: " << disabled;
+}
+
+static void ime_app_layout_set_cb(
+    Ecore_IMF_Input_Panel_Layout layout, void *user_data)
+{
+  LOGGER(DEBUG) << "layout: " << layout;
+}
+
+static bool ime_app_process_key_event_cb(
+    ime_key_code_e keycode, ime_key_mask_e keymask,
+    ime_device_info_h dev_info, void *user_data)
+{
+  LOGGER(DEBUG) << "keycode = " << keycode << ", keymask = " << keymask;
+
+  if ((keymask & IME_KEY_MASK_CONTROL) || (keymask & IME_KEY_MASK_ALT) ||
+      (keymask & IME_KEY_MASK_META) || (keymask & IME_KEY_MASK_WIN) ||
+      (keymask & IME_KEY_MASK_HYPER))
+    return false;
+
+  return false;
+}
+
+static void ime_app_display_language_changed_cb(
+    const char *language, void *user_data)
+{
+  LOGGER(DEBUG) << "language: " << language;
+}
+
+int ImeRuntime::Exec(int argc, char* argv[]) {
+  ime_callback_s ops = {NULL, NULL, NULL, NULL};
+
+  // onCreate
+  ops.create = [](void* data) -> void {
+    runtime::ImeRuntime* ime_runtime =
+        reinterpret_cast<runtime::ImeRuntime*>(data);
+    if (!ime_runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    ime_runtime->OnCreate();
+  };
+
+  // onTerminate
+  ops.terminate = [](void* data) -> void {
+    runtime::ImeRuntime* ime_runtime =
+        reinterpret_cast<runtime::ImeRuntime*>(data);
+    if (!ime_runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    ime_runtime->OnTerminate();
+  };
+
+  // onShow
+  ops.show = [](int context_id, ime_context_h context, void *data) -> void {
+    runtime::ImeRuntime* ime_runtime =
+        reinterpret_cast<runtime::ImeRuntime*>(data);
+    if (!ime_runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    ime_runtime->OnShow(context_id, context);
+  };
+
+  // onHide
+  ops.hide = [](int context_id, void *data) -> void {
+    runtime::ImeRuntime* ime_runtime =
+        reinterpret_cast<runtime::ImeRuntime*>(data);
+    if (!ime_runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    ime_runtime->OnHide(context_id);
+  };
+
+  STEP_PROFILE_START("ime_app_main -> OnCreate");
+
+  // Set the necessary callback functions
+  ime_event_set_focus_in_cb(ime_app_focus_in_cb, this);
+  ime_event_set_focus_out_cb(ime_app_focus_out_cb, this);
+  ime_event_set_cursor_position_updated_cb(
+    ime_app_cursor_position_updated_cb, this);
+  ime_event_set_layout_set_cb(
+    ime_app_layout_set_cb, this);
+  ime_event_set_return_key_type_set_cb(
+    ime_app_return_key_type_set_cb, this);
+  ime_event_set_return_key_state_set_cb(
+    ime_app_return_key_state_set_cb, this);
+  ime_event_set_process_key_event_cb(
+    ime_app_process_key_event_cb, this);
+  ime_event_set_display_language_changed_cb(
+    ime_app_display_language_changed_cb, this);
+
+  return ime_run(&ops, this);
+}
+
+
+// ime_app_main() function is the main entry point of IME application
+// but in case of Web App. ime_app_main() is not a entry point.
+// To avoid build fail, add empty function.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__attribute__ ((visibility("default")))
+void ime_app_main(int argc, char **argv) {
+  LOGGER(DEBUG) << "ime_app_main";
+}
+#ifdef __cplusplus
+}
+#endif
+
+
+}  // namespace runtime
diff --git a/runtime/browser/ime_runtime.h b/runtime/browser/ime_runtime.h
new file mode 100644 (file)
index 0000000..1284a3d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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_IME_RUNTIME_H_
+#define XWALK_RUNTIME_BROWSER_IME_RUNTIME_H_
+
+#include <app.h>
+#include <inputmethod.h>
+#include <string>
+
+#include "common/application_data.h"
+#include "runtime/browser/runtime.h"
+#include "runtime/browser/native_window.h"
+#include "runtime/browser/ime_application.h"
+
+namespace runtime {
+
+class ImeRuntime : public Runtime {
+ public:
+  ImeRuntime(common::ApplicationData* app_data);
+  virtual ~ImeRuntime();
+
+  virtual int Exec(int argc, char* argv[]);
+
+ protected:
+  virtual void OnCreate();
+  virtual void OnTerminate();
+  virtual void OnShow(int context_id, ime_context_h context);
+  virtual void OnHide(int context_id);
+  virtual void OnAppControl();
+
+ private:
+  WebApplication* application_;
+  NativeWindow* native_window_;
+  common::ApplicationData* app_data_;
+};
+
+}  // namespace runtime
+
+#endif  // XWALK_RUNTIME_BROWSER_IME_RUNTIME_H_
diff --git a/runtime/browser/native_ime_window.cc b/runtime/browser/native_ime_window.cc
new file mode 100644 (file)
index 0000000..c337d61
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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 "runtime/browser/native_ime_window.h"
+#include "common/logger.h"
+
+#include <inputmethod.h>
+#include <Elementary.h>
+
+namespace runtime {
+
+NativeImeWindow::NativeImeWindow() {
+}
+
+NativeImeWindow::~NativeImeWindow() {
+}
+
+Evas_Object* NativeImeWindow::CreateWindowInternal() {
+  elm_config_accel_preference_set("opengl");
+  return ime_get_main_window();
+}
+
+
+}  // namespace runtime
diff --git a/runtime/browser/native_ime_window.h b/runtime/browser/native_ime_window.h
new file mode 100644 (file)
index 0000000..b355899
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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_NATIVE_IME_WINDOW_H_
+#define XWALK_RUNTIME_BROWSER_NATIVE_IME_WINDOW_H_
+
+#include "runtime/browser/native_window.h"
+
+namespace runtime {
+
+class NativeImeWindow: public NativeWindow {
+ public:
+  NativeImeWindow();
+  virtual ~NativeImeWindow();
+ protected:
+  Evas_Object* CreateWindowInternal();  // override
+};
+
+}  // namespace runtime
+
+#endif  // XWALK_RUNTIME_BROWSER_NATIVE_IME_WINDOW_H_
index d99bf47..292d32c 100755 (executable)
  *    limitations under the License.
  */
 
-#include "runtime/browser/runtime.h"
-
-#include <ewk_chromium.h>
+#include <app.h>
 #include <memory>
 #include <string>
 
 #include "common/application_data.h"
-#include "common/app_control.h"
-#include "common/app_db.h"
 #include "common/command_line.h"
-#include "common/logger.h"
-#include "common/profiler.h"
-#include "runtime/browser/native_app_window.h"
 #include "runtime/common/constants.h"
-#include "runtime/browser/preload_manager.h"
+#include "runtime/browser/runtime.h"
+#include "runtime/browser/ui_runtime.h"
+#ifdef IME_FEATURE_SUPPORT
+#include "runtime/browser/ime_runtime.h"
+#endif  // IME_FEATURE_SUPPORT
 
 namespace runtime {
 
-namespace {
-
-static NativeWindow* CreateNativeWindow() {
-  SCOPE_PROFILE();
-  // TODO(wy80.choi) : consider other type of native window.
-  auto cached = PreloadManager::GetInstance()->GetCachedNativeWindow();
-  NativeWindow* window = cached != nullptr ? cached : new NativeAppWindow();
-  window->Initialize();
-  return window;
-}
-
-}  // namespace
-
-Runtime::Runtime()
-    : application_(NULL),
-      native_window_(NULL) {
-}
-
 Runtime::~Runtime() {
-  if (application_) {
-    delete application_;
-  }
-  if (native_window_) {
-    delete native_window_;
-  }
-}
-
-bool Runtime::OnCreate() {
-  STEP_PROFILE_END("ui_app_main -> OnCreate");
-  STEP_PROFILE_END("Start -> OnCreate");
-  STEP_PROFILE_START("OnCreate -> URL Set");
-
-  common::CommandLine* cmd = common::CommandLine::ForCurrentProcess();
-  std::string appid = cmd->GetAppIdFromCommandLine(kRuntimeExecName);
-
-  // Load Manifest
-  auto appdata_manager = common::ApplicationDataManager::GetInstance();
-  common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid);
-  if (!appdata->LoadManifestData()) {
-    return false;
-  }
-
-  // Init AppDB for Runtime
-  common::AppDB* appdb = common::AppDB::GetInstance();
-  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeName, "xwalk-tizen");
-  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeAppID, appid);
-  appdb->Remove(kAppDBRuntimeSection, kAppDBRuntimeBundle);
-
-  // Init WebApplication
-  native_window_ = CreateNativeWindow();
-  STEP_PROFILE_START("WebApplication Create");
-  application_ = new WebApplication(native_window_, appdata);
-  STEP_PROFILE_END("WebApplication Create");
-  application_->set_terminator([](){ ui_app_exit(); });
-
-  setlocale(LC_ALL, "");
-  bindtextdomain(kTextDomainRuntime, kTextLocalePath);
-
-  return true;
 }
 
-void Runtime::OnTerminate() {
-}
-
-void Runtime::OnPause() {
-  if (application_->launched()) {
-    application_->Suspend();
-  }
-}
-
-void Runtime::OnResume() {
-  if (application_->launched()) {
-    application_->Resume();
+std::unique_ptr<Runtime> Runtime::MakeRuntime(
+    common::ApplicationData* app_data) {
+  if (app_data->app_type() == common::ApplicationData::UI) {
+    return std::unique_ptr<Runtime>(new UiRuntime(app_data));
   }
-}
-
-void Runtime::OnAppControl(app_control_h app_control) {
-  SCOPE_PROFILE();
-  std::unique_ptr<common::AppControl>
-      appcontrol(new common::AppControl(app_control));
-  common::AppDB* appdb = common::AppDB::GetInstance();
-  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeBundle,
-             appcontrol->encoded_bundle());
-  if (application_->launched()) {
-    application_->AppControl(std::move(appcontrol));
-  } else {
-    application_->Launch(std::move(appcontrol));
-  }
-}
-
-void Runtime::OnLanguageChanged(const std::string& language) {
-  if (application_) {
-    application_->OnLanguageChanged();
-    elm_language_set(language.c_str());
+#ifdef IME_FEATURE_SUPPORT
+  else if (app_data->app_type() == common::ApplicationData::IME) {
+    return std::unique_ptr<Runtime>(new ImeRuntime(app_data));
   }
-}
-
-void Runtime::OnLowMemory() {
-  if (application_) {
-    application_->OnLowMemory();
+#endif  // IME_FEATURE_SUPPORT
+  else {
+    return std::unique_ptr<Runtime>(new UiRuntime(app_data));
   }
 }
 
-int Runtime::Exec(int argc, char* argv[]) {
-  ui_app_lifecycle_callback_s ops = {NULL, NULL, NULL, NULL, NULL};
-
-  // onCreate
-  ops.create = [](void* data) -> bool {
-    Runtime* runtime = reinterpret_cast<Runtime*>(data);
-    if (!runtime) {
-      LOGGER(ERROR) << "Runtime has not been created.";
-      return false;
-    }
-    return runtime->OnCreate();
-  };
-
-  // onTerminate
-  ops.terminate = [](void* data) -> void {
-    Runtime* runtime = reinterpret_cast<Runtime*>(data);
-    if (!runtime) {
-      LOGGER(ERROR) << "Runtime has not been created.";
-      return;
-    }
-    runtime->OnTerminate();
-  };
-
-  // onPause
-  ops.pause = [](void* data) -> void {
-    Runtime* runtime = reinterpret_cast<Runtime*>(data);
-    if (!runtime) {
-      LOGGER(ERROR) << "Runtime has not been created.";
-      return;
-    }
-    runtime->OnPause();
-  };
-
-  // onResume
-  ops.resume = [](void* data) -> void {
-    Runtime* runtime = reinterpret_cast<Runtime*>(data);
-    if (!runtime) {
-      LOGGER(ERROR) << "Runtime has not been created.";
-      return;
-    }
-    runtime->OnResume();
-  };
-
-  // onAppControl
-  ops.app_control = [](app_control_h app_control, void* data) -> void {
-    Runtime* runtime = reinterpret_cast<Runtime*>(data);
-    if (!runtime) {
-      LOGGER(ERROR) << "Runtime has not been created.";
-      return;
-    }
-    runtime->OnAppControl(app_control);
-  };
-
-  // language changed callback
-  auto language_changed = [](app_event_info_h event_info, void* user_data) {
-    char* str;
-    if (app_event_get_language(event_info, &str) == 0 && str != NULL) {
-      std::string language = std::string(str);
-      std::free(str);
-      Runtime* runtime = reinterpret_cast<Runtime*>(user_data);
-      runtime->OnLanguageChanged(language);
-    }
-  };
-  auto low_memory = [](app_event_info_h /*event_info*/, void* user_data) {
-    Runtime* runtime = reinterpret_cast<Runtime*>(user_data);
-    runtime->OnLowMemory();
-  };
-  app_event_handler_h ev_handle;
-  ui_app_add_event_handler(&ev_handle,
-                           APP_EVENT_LANGUAGE_CHANGED,
-                           language_changed,
-                           this);
-  ui_app_add_event_handler(&ev_handle,
-                           APP_EVENT_LOW_MEMORY,
-                           low_memory,
-                           this);
-  STEP_PROFILE_START("ui_app_main -> OnCreate");
-
-  return ui_app_main(argc, argv, &ops, this);
-}
 
 }  // namespace runtime
index 9be8495..db4ef00 100644 (file)
 #define XWALK_RUNTIME_BROWSER_RUNTIME_H_
 
 #include <app.h>
+#include <memory>
 #include <string>
 
-#include "runtime/browser/native_window.h"
-#include "runtime/browser/web_application.h"
+#include "common/application_data.h"
 
 namespace runtime {
 
 class Runtime {
  public:
-  Runtime();
-  virtual ~Runtime();
-
-  virtual int Exec(int argc, char* argv[]);
-
- protected:
-  virtual bool OnCreate();
-  virtual void OnTerminate();
-  virtual void OnPause();
-  virtual void OnResume();
-  virtual void OnAppControl(app_control_h app_control);
-  virtual void OnLanguageChanged(const std::string& language);
-  virtual void OnLowMemory();
-
- private:
-  WebApplication* application_;
-  NativeWindow* native_window_;
+  virtual ~Runtime() = 0;
+
+  virtual int Exec(int argc, char* argv[]) = 0;
+
+  static std::unique_ptr<Runtime> MakeRuntime(
+    common::ApplicationData* app_data);
 };
 
 }  // namespace runtime
index c499533..d5b143c 100755 (executable)
 
 #include <Elementary.h>
 
+#include "common/application_data.h"
 #include "common/command_line.h"
 #include "common/logger.h"
 #include "common/profiler.h"
 #include "runtime/browser/runtime.h"
+#include "runtime/common/constants.h"
 #include "runtime/browser/prelauncher.h"
 #include "runtime/browser/preload_manager.h"
 
@@ -33,6 +35,16 @@ int real_main(int argc, char* argv[]) {
   // Parse commandline.
   common::CommandLine::Init(argc, argv);
 
+  common::CommandLine* cmd = common::CommandLine::ForCurrentProcess();
+  std::string appid = cmd->GetAppIdFromCommandLine(runtime::kRuntimeExecName);
+
+  // Load Manifest
+  auto appdata_manager = common::ApplicationDataManager::GetInstance();
+  common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid);
+  if (!appdata->LoadManifestData()) {
+    return false;
+  }
+
   // Default behavior, run as runtime.
   LOGGER(INFO) << "Runtime process has been created.";
   if (!g_prelaunch) {
@@ -53,8 +65,10 @@ int real_main(int argc, char* argv[]) {
   int ret = 0;
   // Runtime's destructor should be called before ewk_shutdown()
   {
-    runtime::Runtime runtime;
-    ret = runtime.Exec(argc, argv);
+    std::unique_ptr<runtime::Runtime> runtime =
+        runtime::Runtime::MakeRuntime(appdata);
+    ret = runtime->Exec(argc, argv);
+    runtime.reset();
   }
   ewk_shutdown();
   exit(ret);
diff --git a/runtime/browser/ui_runtime.cc b/runtime/browser/ui_runtime.cc
new file mode 100755 (executable)
index 0000000..f2f46c1
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * 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 <ewk_chromium.h>
+#include <memory>
+#include <string>
+
+#include "common/application_data.h"
+#include "common/app_control.h"
+#include "common/app_db.h"
+#include "common/command_line.h"
+#include "common/logger.h"
+#include "common/profiler.h"
+#include "runtime/common/constants.h"
+#include "runtime/browser/native_app_window.h"
+#include "runtime/browser/preload_manager.h"
+#include "runtime/browser/runtime.h"
+#include "runtime/browser/ui_runtime.h"
+
+namespace runtime {
+
+namespace {
+
+static NativeWindow* CreateNativeWindow() {
+  SCOPE_PROFILE();
+  // TODO(wy80.choi) : consider other type of native window.
+  auto cached = PreloadManager::GetInstance()->GetCachedNativeWindow();
+  NativeWindow* window = cached != nullptr ? cached : new NativeAppWindow();
+  window->Initialize();
+  return window;
+}
+
+}  // namespace
+
+UiRuntime::UiRuntime(common::ApplicationData* app_data)
+    : application_(NULL),
+      native_window_(NULL),
+      app_data_(app_data) {
+}
+
+UiRuntime::~UiRuntime() {
+  if (application_) {
+    delete application_;
+  }
+  if (native_window_) {
+    delete native_window_;
+  }
+}
+
+bool UiRuntime::OnCreate() {
+  STEP_PROFILE_END("ui_app_main -> OnCreate");
+  STEP_PROFILE_END("Start -> OnCreate");
+  STEP_PROFILE_START("OnCreate -> URL Set");
+
+  common::CommandLine* cmd = common::CommandLine::ForCurrentProcess();
+  std::string appid = cmd->GetAppIdFromCommandLine(kRuntimeExecName);
+
+  // Init AppDB for Runtime
+  common::AppDB* appdb = common::AppDB::GetInstance();
+  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeName, "xwalk-tizen");
+  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeAppID, appid);
+  appdb->Remove(kAppDBRuntimeSection, kAppDBRuntimeBundle);
+
+  // Init WebApplication
+  native_window_ = CreateNativeWindow();
+  STEP_PROFILE_START("WebApplication Create");
+  application_ = new WebApplication(native_window_, app_data_);
+  STEP_PROFILE_END("WebApplication Create");
+  application_->set_terminator([](){ ui_app_exit(); });
+
+  setlocale(LC_ALL, "");
+  bindtextdomain(kTextDomainRuntime, kTextLocalePath);
+
+  return true;
+}
+
+void UiRuntime::OnTerminate() {
+}
+
+void UiRuntime::OnPause() {
+  if (application_->launched()) {
+    application_->Suspend();
+  }
+}
+
+void UiRuntime::OnResume() {
+  if (application_->launched()) {
+    application_->Resume();
+  }
+}
+
+void UiRuntime::OnAppControl(app_control_h app_control) {
+  SCOPE_PROFILE();
+  std::unique_ptr<common::AppControl>
+      appcontrol(new common::AppControl(app_control));
+  common::AppDB* appdb = common::AppDB::GetInstance();
+  appdb->Set(kAppDBRuntimeSection, kAppDBRuntimeBundle,
+             appcontrol->encoded_bundle());
+  if (application_->launched()) {
+    application_->AppControl(std::move(appcontrol));
+  } else {
+    application_->Launch(std::move(appcontrol));
+  }
+}
+
+void UiRuntime::OnLanguageChanged(const std::string& language) {
+  if (application_) {
+    application_->OnLanguageChanged();
+    elm_language_set(language.c_str());
+  }
+}
+
+void UiRuntime::OnLowMemory() {
+  if (application_) {
+    application_->OnLowMemory();
+  }
+}
+
+int UiRuntime::Exec(int argc, char* argv[]) {
+  ui_app_lifecycle_callback_s ops = {NULL, NULL, NULL, NULL, NULL};
+
+  // onCreate
+  ops.create = [](void* data) -> bool {
+    UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(data);
+    if (!ui_runtime) {
+      LOGGER(ERROR) << "UiRuntime has not been created.";
+      return false;
+    }
+    return ui_runtime->OnCreate();
+  };
+
+  // onTerminate
+  ops.terminate = [](void* data) -> void {
+    UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(data);
+    if (!ui_runtime) {
+      LOGGER(ERROR) << "UiRuntime has not been created.";
+      return;
+    }
+    ui_runtime->OnTerminate();
+  };
+
+  // onPause
+  ops.pause = [](void* data) -> void {
+    UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(data);
+    if (!ui_runtime) {
+      LOGGER(ERROR) << "UiRuntime has not been created.";
+      return;
+    }
+    ui_runtime->OnPause();
+  };
+
+  // onResume
+  ops.resume = [](void* data) -> void {
+    UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(data);
+    if (!ui_runtime) {
+      LOGGER(ERROR) << "UiRuntime has not been created.";
+      return;
+    }
+    ui_runtime->OnResume();
+  };
+
+  // onAppControl
+  ops.app_control = [](app_control_h app_control, void* data) -> void {
+    UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(data);
+    if (!ui_runtime) {
+      LOGGER(ERROR) << "UiRuntime has not been created.";
+      return;
+    }
+    ui_runtime->OnAppControl(app_control);
+  };
+
+  // language changed callback
+  auto language_changed = [](app_event_info_h event_info, void* user_data) {
+    char* str;
+    if (app_event_get_language(event_info, &str) == 0 && str != NULL) {
+      std::string language = std::string(str);
+      std::free(str);
+      UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(user_data);
+      ui_runtime->OnLanguageChanged(language);
+    }
+  };
+  auto low_memory = [](app_event_info_h /*event_info*/, void* user_data) {
+    UiRuntime* ui_runtime = reinterpret_cast<UiRuntime*>(user_data);
+    ui_runtime->OnLowMemory();
+  };
+  app_event_handler_h ev_handle;
+  ui_app_add_event_handler(&ev_handle,
+                           APP_EVENT_LANGUAGE_CHANGED,
+                           language_changed,
+                           this);
+  ui_app_add_event_handler(&ev_handle,
+                           APP_EVENT_LOW_MEMORY,
+                           low_memory,
+                           this);
+  STEP_PROFILE_START("ui_app_main -> OnCreate");
+
+  return ui_app_main(argc, argv, &ops, this);
+}
+
+}  // namespace runtime
diff --git a/runtime/browser/ui_runtime.h b/runtime/browser/ui_runtime.h
new file mode 100644 (file)
index 0000000..83ed31e
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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_UI_RUNTIME_H_
+#define XWALK_RUNTIME_BROWSER_UI_RUNTIME_H_
+
+#include <app.h>
+#include <string>
+
+#include "common/application_data.h"
+#include "runtime/browser/runtime.h"
+#include "runtime/browser/native_window.h"
+#include "runtime/browser/web_application.h"
+
+namespace runtime {
+
+class UiRuntime : public Runtime {
+ public:
+  UiRuntime(common::ApplicationData* app_data);
+  virtual ~UiRuntime();
+
+  virtual int Exec(int argc, char* argv[]);
+
+ protected:
+  virtual bool OnCreate();
+  virtual void OnTerminate();
+  virtual void OnPause();
+  virtual void OnResume();
+  virtual void OnAppControl(app_control_h app_control);
+  virtual void OnLanguageChanged(const std::string& language);
+  virtual void OnLowMemory();
+
+ private:
+  WebApplication* application_;
+  NativeWindow* native_window_;
+  common::ApplicationData* app_data_;
+};
+
+}  // namespace runtime
+
+#endif  // XWALK_RUNTIME_BROWSER_UI_RUNTIME_H_
index 9f836ea..bfddee7 100644 (file)
@@ -220,7 +220,7 @@ WebApplication::WebApplication(
   std::unique_ptr<char, decltype(std::free)*> path{app_get_data_path(),
                                                    std::free};
   app_data_path_ = path.get();
-  LOGGER(ERROR) << "path is " << path.get();
+  LOGGER(DEBUG) << "path is " << path.get();
   splash_screen_.reset(new SplashScreen(
       window_, app_data_->splash_screen_info(), app_data_->application_path()));
   resource_manager_.reset(
@@ -376,7 +376,6 @@ void WebApplication::Launch(std::unique_ptr<common::AppControl> appcontrol) {
   view->LoadUrl(res->uri(), res->mime());
   view_stack_.push_front(view);
 
-
   if (appcontrol->data(AUL_K_DEBUG) == "1") {
     debug_mode_ = true;
     LaunchInspector(appcontrol.get());
index e93e9e7..74545d5 100755 (executable)
@@ -17,6 +17,8 @@
         'browser/runtime_process.cc',
         'browser/runtime.h',
         'browser/runtime.cc',
+        'browser/ui_runtime.h',
+        'browser/ui_runtime.cc',
         'browser/native_window.h',
         'browser/native_window.cc',
         'browser/native_app_window.h',
         ],
       },
       'conditions': [
+        ['profile == "mobile"', {
+          'defines': ['PROFILE_MOBILE'],
+        }],
         ['profile == "wearable"', {
           'defines': ['PROFILE_WEARABLE'],
         }],
+        ['profile == "tv"', {
+          'defines': ['PROFILE_TV'],
+        }],
         ['tizen_feature_rotary_event_support == 1', {
           'defines': ['ROTARY_EVENT_FEATURE_SUPPORT'],
         }],
+        ['tizen_feature_web_ime_support == 1', {
+          'defines': ['IME_FEATURE_SUPPORT'],
+          'sources': [
+            'browser/ime_runtime.h',
+            'browser/ime_runtime.cc',
+            'browser/ime_application.h',
+            'browser/ime_application.cc',
+            'browser/native_ime_window.h',
+            'browser/native_ime_window.cc',
+          ],
+          'variables': {
+            'packages': [
+              'capi-ui-inputmethod',
+            ],
+          },
+        }],
       ],
     }, # end of target 'xwalk_runtime'
     {