Apply to watch face
authorJongHeon Choi <j-h.choi@samsung.com>
Mon, 30 May 2016 01:35:58 +0000 (10:35 +0900)
committerJongHeon Choi <j-h.choi@samsung.com>
Mon, 30 May 2016 01:36:12 +0000 (10:36 +0900)
13 files changed:
common/application_data.cc
common/application_data.h
common/common.gyp
packaging/crosswalk-tizen.spec
runtime/browser/native_watch_window.cc [new file with mode: 0644]
runtime/browser/native_watch_window.h [new file with mode: 0644]
runtime/browser/runtime.cc
runtime/browser/runtime_process.cc
runtime/browser/watch_runtime.cc [new file with mode: 0644]
runtime/browser/watch_runtime.h [new file with mode: 0644]
runtime/browser/web_application.cc
runtime/browser/web_application.h
runtime/runtime.gyp

index bb02984..7c59e75 100644 (file)
@@ -37,6 +37,10 @@ const char* kResWgtPath = "res/wgt";
 #ifdef IME_FEATURE_SUPPORT
 const char* kImeCategory = "http://tizen.org/category/ime";
 #endif  // IME_FEATURE_SUPPORT
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+const char* kIdleClockCategory = "com.samsung.wmanager.WATCH_CLOCK";
+const char* kWearableClockCategory = "http://tizen.org/category/wearable_clock";
+#endif  // WATCH_FACE_FEATURE_SUPPORT
 
 static std::string GetPackageIdByAppId(const std::string& appid) {
   char* pkgid = NULL;
@@ -164,6 +168,11 @@ ApplicationData::AppType ApplicationData::GetAppType() {
         return IME;
       }
 #endif  // IME_FEATURE_SUPPORT
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+      if (*it == kIdleClockCategory || *it == kWearableClockCategory) {
+        return WATCH;
+      }
+#endif  // WATCH_FACE_FEATURE_SUPPORT
     }
   }
   return UI;
index 6032ca1..f8c2eba 100644 (file)
@@ -46,6 +46,9 @@ class ApplicationData {
 #ifdef IME_FEATURE_SUPPORT
     ,IME
 #endif  // IME_FEATURE_SUPPORT
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+    ,WATCH
+#endif  // WATCH_FACE_FEATURE_SUPPORT
   };
 
   explicit ApplicationData(const std::string& appid);
index 925e756..0c90584 100644 (file)
@@ -54,6 +54,8 @@
       'conditions': [
         ['tizen_feature_web_ime_support == 1', {
           'defines': ['IME_FEATURE_SUPPORT'],
+        ['tizen_feature_watch_face_support == 1', {
+          'defines': ['WATCH_FACE_FEATURE_SUPPORT'],
         }],
       ],
       'direct_dependent_settings': {
index d338a4f..42f2fc3 100755 (executable)
@@ -47,22 +47,30 @@ BuildRequires: pkgconfig(jsoncpp)
 %if "%{?profile}" == "mobile"
 %define tizen_feature_rotary_event_support     0
 %define tizen_feature_web_ime_support          0
+%define tizen_feature_watch_face_support       0
 %endif
 
 %if "%{?profile}" == "wearable"
 %define tizen_feature_rotary_event_support     1
 %define tizen_feature_web_ime_support          1
+%define tizen_feature_watch_face_support       1
 %endif
 
 %if "%{?profile}" == "tv"
 %define tizen_feature_rotary_event_support     0
 %define tizen_feature_web_ime_support          1
+%define tizen_feature_watch_face_support       0
 %endif
 
 %if 0%{?tizen_feature_web_ime_support}
 BuildRequires: pkgconfig(capi-ui-inputmethod)
 %endif
 
+%if 0%{?tizen_feature_watch_face_support}
+BuildRequires: pkgconfig(capi-appfw-watch-application)
+BuildRequires: pkgconfig(appcore-watch)
+%endif
+
 
 Requires: /usr/bin/systemctl
 
@@ -89,6 +97,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}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_watch_face_support=%{?tizen_feature_watch_face_support}"
 
 # Extension Path
 GYP_OPTIONS="$GYP_OPTIONS -Dextension_path=%{extension_path}"
diff --git a/runtime/browser/native_watch_window.cc b/runtime/browser/native_watch_window.cc
new file mode 100644 (file)
index 0000000..17b83e3
--- /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.
+ */
+
+#include "runtime/browser/native_watch_window.h"
+#include "common/logger.h"
+
+#include <watch_app_efl.h>
+#include <Elementary.h>
+
+namespace runtime {
+
+NativeWatchWindow::NativeWatchWindow() {
+}
+
+NativeWatchWindow::~NativeWatchWindow() {
+}
+
+Evas_Object* NativeWatchWindow::CreateWindowInternal() {
+  Evas_Object* window = NULL;
+  elm_config_accel_preference_set("opengl");
+  watch_app_get_elm_win(&window);
+  elm_win_alpha_set(window, EINA_TRUE);
+  evas_object_render_op_set(window, EVAS_RENDER_COPY);
+  evas_object_show(window);
+  return window;
+}
+
+
+}  // namespace runtime
diff --git a/runtime/browser/native_watch_window.h b/runtime/browser/native_watch_window.h
new file mode 100644 (file)
index 0000000..967efd1
--- /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_WATCH_WINDOW_H_
+#define XWALK_RUNTIME_BROWSER_NATIVE_WATCH_WINDOW_H_
+
+#include "runtime/browser/native_window.h"
+
+namespace runtime {
+
+class NativeWatchWindow: public NativeWindow {
+ public:
+  NativeWatchWindow();
+  virtual ~NativeWatchWindow();
+ protected:
+  Evas_Object* CreateWindowInternal();  // override
+};
+
+}  // namespace runtime
+
+#endif  // XWALK_RUNTIME_BROWSER_NATIVE_WATCH_WINDOW_H_
index 292d32c..051ffe0 100755 (executable)
@@ -26,6 +26,9 @@
 #ifdef IME_FEATURE_SUPPORT
 #include "runtime/browser/ime_runtime.h"
 #endif  // IME_FEATURE_SUPPORT
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+#include "runtime/browser/watch_runtime.h"
+#endif  // WATCH_FACE_FEATURE_SUPPORT
 
 namespace runtime {
 
@@ -42,6 +45,11 @@ std::unique_ptr<Runtime> Runtime::MakeRuntime(
     return std::unique_ptr<Runtime>(new ImeRuntime(app_data));
   }
 #endif  // IME_FEATURE_SUPPORT
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+  else if (app_data->app_type() == common::ApplicationData::WATCH) {
+    return std::unique_ptr<Runtime>(new WatchRuntime(app_data));
+  }
+#endif  // WATCH_FACE_FEATURE_SUPPORT
   else {
     return std::unique_ptr<Runtime>(new UiRuntime(app_data));
   }
index d5b143c..bd1e201 100755 (executable)
 
 #include <Elementary.h>
 
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+#include <bundle_internal.h>
+#include <Ecore_Wayland.h>
+#endif  // WATCH_FACE_FEATURE_SUPPORT
+
 #include "common/application_data.h"
 #include "common/command_line.h"
 #include "common/logger.h"
 
 bool g_prelaunch = false;
 
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+static int setWatchEnv(int argc, char **argv) {
+  bundle *kb = NULL;
+  char *wayland_display = NULL;
+  char *xdg_runtime_dir = NULL;
+  char *width_str = NULL;
+  char *height_str = NULL;
+
+  if (argc <= 0 || argv == NULL) {
+    errno = EINVAL;
+    LOGGER(ERROR) << "argument are invalid";
+    return -1;
+  }
+
+  kb = bundle_import_from_argv(argc, argv);
+  if (kb) {
+    bundle_get_str(kb, "XDG_RUNTIME_DIR", &xdg_runtime_dir);
+    bundle_get_str(kb, "WAYLAND_DISPLAY", &wayland_display);
+    bundle_get_str(kb, "WATCH_WIDTH", &width_str);
+    bundle_get_str(kb, "WATCH_HEIGHT", &height_str);
+
+    if (xdg_runtime_dir) {
+      LOGGER(DEBUG) << "senenv: " << xdg_runtime_dir;
+      setenv("XDG_RUNTIME_DIR", xdg_runtime_dir, 1);
+    } else {
+      LOGGER(ERROR) << "failed to get xdgruntimedir";
+    }
+
+    if (wayland_display) {
+      LOGGER(DEBUG) << "setenv: " << wayland_display;
+      setenv("WAYLAND_DISPLAY", wayland_display, 1);
+    } else {
+      LOGGER(ERROR) << "failed to get waylanddisplay";
+    }
+    bundle_free(kb);
+  } else {
+    LOGGER(ERROR) << "failed to get launch argv";
+  }
+  return 0;
+}
+#endif  // WATCH_FACE_FEATURE_SUPPORT
+
 int real_main(int argc, char* argv[]) {
   STEP_PROFILE_START("Start -> Launch Completed");
   STEP_PROFILE_START("Start -> OnCreate");
@@ -45,6 +92,12 @@ int real_main(int argc, char* argv[]) {
     return false;
   }
 
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+  if (appdata->app_type() == common::ApplicationData::WATCH) {
+    setWatchEnv(argc, argv);
+  }
+#endif  // WATCH_FACE_FEATURE_SUPPORT
+
   // Default behavior, run as runtime.
   LOGGER(INFO) << "Runtime process has been created.";
   if (!g_prelaunch) {
@@ -60,6 +113,13 @@ int real_main(int argc, char* argv[]) {
     const int chromium_arg_cnt =
         sizeof(chromium_arg_options) / sizeof(chromium_arg_options[0]);
     ewk_set_arguments(chromium_arg_cnt, chromium_arg_options);
+#ifdef WATCH_FACE_FEATURE_SUPPORT
+  } else {
+    if (appdata->app_type() == common::ApplicationData::WATCH) {
+      ecore_wl_shutdown();
+      ecore_wl_init(NULL);
+    }
+#endif  // WATCH_FACE_FEATURE_SUPPORT
   }
 
   int ret = 0;
diff --git a/runtime/browser/watch_runtime.cc b/runtime/browser/watch_runtime.cc
new file mode 100644 (file)
index 0000000..26294b5
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * 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 <watch_app.h>
+#include <appcore-watch.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_watch_window.h"
+#include "runtime/browser/preload_manager.h"
+#include "runtime/browser/runtime.h"
+#include "runtime/browser/watch_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 NativeWatchWindow();
+  window->Initialize();
+
+  return window;
+}
+
+}  // namespace
+
+WatchRuntime::WatchRuntime(common::ApplicationData* app_data)
+    : application_(NULL),
+      native_window_(NULL),
+      app_data_(app_data) {
+}
+
+WatchRuntime::~WatchRuntime() {
+  if (application_) {
+    delete application_;
+  }
+  if (native_window_) {
+    delete native_window_;
+  }
+}
+
+bool WatchRuntime::OnCreate() {
+  STEP_PROFILE_END("watch_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([](){ watch_app_exit(); });
+
+  setlocale(LC_ALL, "");
+  bindtextdomain(kTextDomainRuntime, kTextLocalePath);
+
+  return true;
+}
+
+void WatchRuntime::OnTerminate() {
+}
+
+void WatchRuntime::OnPause() {
+  if (application_->launched()) {
+    application_->Suspend();
+  }
+}
+
+void WatchRuntime::OnResume() {
+  if (application_->launched()) {
+    application_->Resume();
+  }
+}
+
+void WatchRuntime::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 WatchRuntime::OnLanguageChanged(const std::string& language) {
+  if (application_) {
+    application_->OnLanguageChanged();
+    elm_language_set(language.c_str());
+  }
+}
+
+void WatchRuntime::OnLowMemory() {
+  if (application_) {
+    application_->OnLowMemory();
+  }
+}
+
+void WatchRuntime::OnTimeTick(watch_time_h watch_time) {
+  //do not fire tick event for normal clock for web app
+#if 0
+  time_t time;
+  int ret = watch_time_get_utc_timestamp(watch_time, &time);
+  if (!ret) {
+    LOGGER(DEBUG) << "time : " << time;
+    application_->OnTimeTick(time);
+  } else {
+    LOGGER(DEBUG) << "Fail to get utc time. skip send time tick event";
+  }
+#endif
+}
+
+void WatchRuntime::OnAmbientTick(watch_time_h watch_time) {
+  time_t time;
+  int ret = watch_time_get_utc_timestamp(watch_time, &time);
+  if (!ret) {
+    LOGGER(DEBUG) << "time : " << time;
+    application_->OnAmbientTick(time);
+  } else {
+    LOGGER(ERROR) << "Fail to get utc time. skip send ambient tick event";
+  }
+}
+
+void WatchRuntime::OnAmbientChanged(bool ambient_mode) {
+  application_->OnAmbientChanged(ambient_mode);
+}
+
+int WatchRuntime::Exec(int argc, char* argv[]) {
+  watch_app_lifecycle_callback_s ops =
+    {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+  // onCreate
+  ops.create = [](int width, int height, void *data) -> bool {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return false;
+    }
+    return runtime->OnCreate();
+  };
+
+  // onTerminate
+  ops.terminate = [](void* data) -> void {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    runtime->OnTerminate();
+  };
+
+  // onPause
+  ops.pause = [](void* data) -> void {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    runtime->OnPause();
+  };
+
+  // onResume
+  ops.resume = [](void* data) -> void {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(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 {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    runtime->OnAppControl(app_control);
+  };
+
+  // onTimeTick
+  ops.time_tick = [](watch_time_h watch_time, void* data) -> void {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    runtime->OnTimeTick(watch_time);
+  };
+
+  // onAmbientTick
+  ops.ambient_tick = [](watch_time_h watch_time, void* data) -> void {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    runtime->OnAmbientTick(watch_time);
+  };
+
+  // onAmbientChanged
+  ops.ambient_changed = [](bool ambient_mode, void* data) -> void {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(data);
+    if (!runtime) {
+      LOGGER(ERROR) << "Runtime has not been created.";
+      return;
+    }
+    // To render web application on ambient mode
+    if (ambient_mode) {
+      runtime->OnResume();
+    } else {
+      runtime->OnPause();
+    }
+    runtime->OnAmbientChanged(ambient_mode);
+  };
+
+  // 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);
+      WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(user_data);
+      runtime->OnLanguageChanged(language);
+    }
+  };
+
+  auto low_memory = [](app_event_info_h /*event_info*/, void* user_data) {
+    WatchRuntime* runtime = reinterpret_cast<WatchRuntime*>(user_data);
+    runtime->OnLowMemory();
+  };
+
+  app_event_handler_h ev_handle;
+  watch_app_add_event_handler(&ev_handle,
+                           APP_EVENT_LANGUAGE_CHANGED,
+                           language_changed,
+                           this);
+  watch_app_add_event_handler(&ev_handle,
+                           APP_EVENT_LOW_MEMORY,
+                           low_memory,
+                           this);
+  STEP_PROFILE_START("watch_app_main -> OnCreate");
+
+  return watch_app_main(argc, argv, &ops, this);
+}
+
+}  // namespace runtime
diff --git a/runtime/browser/watch_runtime.h b/runtime/browser/watch_runtime.h
new file mode 100644 (file)
index 0000000..8838c0d
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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_WATCH_RUNTIME_H_
+#define XWALK_RUNTIME_BROWSER_WATCH_RUNTIME_H_
+
+#include <app.h>
+#include <watch_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 WatchRuntime : public Runtime {
+ public:
+  WatchRuntime(common::ApplicationData* app_data);
+  virtual ~WatchRuntime();
+
+  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();
+  virtual void OnTimeTick(watch_time_h watch_time);
+  virtual void OnAmbientTick(watch_time_h watch_time);
+  virtual void OnAmbientChanged(bool ambient_mode);
+
+ private:
+  WebApplication* application_;
+  NativeWindow* native_window_;
+  common::ApplicationData* app_data_;
+};
+
+}  // namespace runtime
+
+#endif  // XWALK_RUNTIME_BROWSER_WATCH_RUNTIME_H_
index d7dd30e..dd3afac 100644 (file)
@@ -91,6 +91,15 @@ const char* kMenuKeyEventScript =
     "for (var i=0; i < window.frames.length; i++)\n"
     "{ window.frames[i].document.dispatchEvent(__event); }"
     "})()";
+const char* kAmbientTickEventScript =
+    "(function(){"
+    "var __event = document.createEvent(\"CustomEvent\");\n"
+    "__event.initCustomEvent(\"timetick\", true, true);\n"
+    "document.dispatchEvent(__event);\n"
+    "\n"
+    "for (var i=0; i < window.frames.length; i++)\n"
+    "{ window.frames[i].document.dispatchEvent(__event); }"
+    "})()";
 const char* kFullscreenPrivilege = "http://tizen.org/privilege/fullscreen";
 const char* kFullscreenFeature = "fullscreen";
 const char* kNotificationPrivilege = "http://tizen.org/privilege/notification";
@@ -734,6 +743,40 @@ void WebApplication::OnRotaryEvent(WebView* /*view*/,
 }
 #endif  // ROTARY_EVENT_FEATURE_SUPPORT
 
+void WebApplication::OnTimeTick(long time) {
+#if 0
+  LOGGER(DEBUG) << "TimeTick";
+  if (view_stack_.size() > 0 && view_stack_.front() != NULL)
+    view_stack_.front()->EvalJavascript(kAmbientTickEventScript);
+#endif
+}
+
+void WebApplication::OnAmbientTick(long time) {
+  LOGGER(DEBUG) << "AmbientTick";
+  if (view_stack_.size() > 0 && view_stack_.front() != NULL)
+    view_stack_.front()->EvalJavascript(kAmbientTickEventScript);
+}
+
+void WebApplication::OnAmbientChanged(bool ambient_mode) {
+  LOGGER(DEBUG) << "AmbientChanged";
+  std::stringstream script;
+  script
+    << "(function(){"
+    << "var __event = document.createEvent(\"CustomEvent\");\n"
+    << "var __detail = {};\n"
+    << "__event.initCustomEvent(\"ambientmodechanged\",true,true,__detail);\n"
+    << "__event.detail.ambientMode = "
+    << (ambient_mode ? "true" : "false") << ";\n"
+    << "document.dispatchEvent(__event);\n"
+    << "\n"
+    << "for (var i=0; i < window.frames.length; i++)\n"
+    << "{ window.frames[i].document.dispatchEvent(__event); }"
+    << "})()";
+  std::string kAmbientChangedEventScript = script.str();
+  if (view_stack_.size() > 0 && view_stack_.front() != NULL)
+    view_stack_.front()->EvalJavascript(kAmbientChangedEventScript.c_str());
+}
+
 bool WebApplication::OnContextMenuDisabled(WebView* /*view*/) {
   return !(app_data_->setting_info() != NULL
                ? app_data_->setting_info()->context_menu_enabled()
index 87519e3..d0af1aa 100755 (executable)
@@ -69,6 +69,9 @@ class WebApplication : public WebView::EventListener {
   virtual void OnRendered(WebView* view);
   virtual void OnLanguageChanged();
   virtual void OnLowMemory();
+  virtual void OnTimeTick(long time);
+  virtual void OnAmbientTick(long time);
+  virtual void OnAmbientChanged(bool ambient_mode);
   virtual bool OnContextMenuDisabled(WebView* view);
   virtual bool OnDidNavigation(WebView* view, const std::string& url);
   virtual void OnNotificationPermissionRequest(
index 74545d5..7d1883e 100755 (executable)
             ],
           },
         }],
+        ['tizen_feature_watch_face_support == 1', {
+          'defines': ['WATCH_FACE_FEATURE_SUPPORT'],
+          'sources': [
+            'browser/watch_runtime.h',
+            'browser/watch_runtime.cc',
+            'browser/native_watch_window.h',
+            'browser/native_watch_window.cc',
+          ],
+          'variables': {
+            'packages': [
+              'capi-appfw-watch-application',
+              'appcore-watch',
+            ],
+          },
+        }],
       ],
     }, # end of target 'xwalk_runtime'
     {