Support translation 76/252776/7
authorJihoon Kim <jihoon48.kim@samsung.com>
Fri, 29 Jan 2021 07:21:36 +0000 (16:21 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Mon, 31 May 2021 06:59:01 +0000 (15:59 +0900)
Change-Id: I1df3c9ee8b1b1413ef517c7fbb2b8d24a351fcce
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
29 files changed:
CMakeLists.txt
data/edc/layout_nmt_keypad.edc [new file with mode: 0644]
data/layout/common/LYT_CM_POPUP.xml
data/layout/common/LYT_LANDSCAPE_NMT.xml [new file with mode: 0644]
data/layout/common/LYT_PORTRAIT_NMT.xml [new file with mode: 0644]
data/layout/common/input_mode_configure.xml
data/layout/mobile/LYT_CM_POPUP.xml
data/layout/mobile/LYT_LANDSCAPE_NMT.xml [new file with mode: 0644]
data/layout/mobile/LYT_PORTRAIT_NMT.xml [new file with mode: 0644]
data/layout/mobile/input_mode_configure.xml
data/pixmaps/default/common/icon/54x54/icon_translation.png [new file with mode: 0644]
data/pixmaps/default/common/icon/54x54/icon_translation_press.png [new file with mode: 0644]
data/pixmaps/default/common/icon/bubble/icon_translation.png [new file with mode: 0644]
data/pixmaps/default/common/icon/bubble/icon_translation_press.png [new file with mode: 0644]
data/pixmaps/default/mobile/icon/54x54/icon_translation.png [new file with mode: 0644]
data/pixmaps/default/mobile/icon/54x54/icon_translation_press.png [new file with mode: 0644]
data/pixmaps/default/mobile/icon/bubble/icon_translation.png [new file with mode: 0644]
data/pixmaps/default/mobile/icon/bubble/icon_translation_press.png [new file with mode: 0644]
ise-default.xml
lib/aarch64/libsamsung-ai-nmt.so [new file with mode: 0755]
lib/armv7l/libsamsung-ai-nmt.so [new file with mode: 0755]
lib/i586/libsamsung-ai-nmt.so [new file with mode: 0755]
packaging/ise-default.spec
src/include/ise-nmt-mode.h [new file with mode: 0644]
src/include/nmt.h [new file with mode: 0644]
src/include/samsung_ai_nmt.h [new file with mode: 0644]
src/ise-nmt-mode.cpp [new file with mode: 0644]
src/ise.cpp
src/nmt.cpp [new file with mode: 0644]

index d046d4e..45dbaae 100644 (file)
@@ -27,6 +27,8 @@ SET(ISE_SRCS
     src/autofill.cpp
     src/ise-dbus.cpp
     src/ise-sticker-mode.cpp
+    src/nmt.cpp
+    src/ise-nmt-mode.cpp
 
     src/ise-emoticon-list.cpp
     src/ise-emoticon-mode.cpp
@@ -47,6 +49,18 @@ SET(ISE_SETTING_SRCS
     src/autofill.cpp
 )
 
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+SET(SRC_LIB_DIR "${CMAKE_SOURCE_DIR}/lib/armv7l")
+ELSEIF("${ARCH}" MATCHES "^aarch64.*")
+SET(SRC_LIB_DIR "${CMAKE_SOURCE_DIR}/lib/aarch64")
+ELSEIF("${ARCH}" MATCHES "^i586.*")
+SET(SRC_LIB_DIR "${CMAKE_SOURCE_DIR}/lib/i586")
+ELSEIF("${ARCH}" MATCHES "^i686.*")
+SET(SRC_LIB_DIR "${CMAKE_SOURCE_DIR}/lib/i586")
+ENDIF()
+
 SET(ISE_PACKAGE ${PROJECT_NAME})
 SET(ISE_PKGNAME ${PACKAGE})
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
@@ -90,6 +104,9 @@ SET(PKGS_CHECK_MODULES
         capi-ui-sticker-consumer
         capi-content-mime-type
         json-glib-1.0
+        bundle
+        rpc-port
+        capi-appfw-event
         )
 
 IF (with_cbhm)
@@ -132,10 +149,15 @@ ADD_DEFINITIONS("-DLAYOUTDIR=\"${ISE_LAYOUTDIR}\"")
 ADD_DEFINITIONS(-DISE_NAME=\"/ise-default\")
 ADD_DEFINITIONS(-DSUPPORTS_EMOTICONS)
 
+LINK_DIRECTORIES(${SRC_LIB_DIR})
+
 ADD_EXECUTABLE(${PROJECT_NAME} ${ISE_SRCS})
 
 ADD_EXECUTABLE(${PROJECT_NAME}-setting ${ISE_SETTING_SRCS})
 
+INSTALL(FILES ${SRC_LIB_DIR}/libsamsung-ai-nmt.so DESTINATION ${ISE_LIBDIR})
+SET(ISE_PKGS_LDFLAGS -Llib -lsamsung-ai-nmt ${ISE_PKGS_LDFLAGS})
+
 # For edc File
 ADD_CUSTOM_TARGET(
     candidate-single.edj
@@ -203,6 +225,15 @@ ADD_CUSTOM_TARGET(
 ADD_DEPENDENCIES(${PROJECT_NAME} layout_sticker_keypad.edj)
 INSTALL(FILES ${CMAKE_BINARY_DIR}/layout_sticker_keypad.edj DESTINATION ${ISE_RESDIR}/edje)
 
+ADD_CUSTOM_TARGET(
+    layout_nmt_keypad.edj
+    COMMAND edje_cc -no-save
+        ${CMAKE_CURRENT_SOURCE_DIR}/data/edc/layout_nmt_keypad.edc
+        ${CMAKE_BINARY_DIR}/layout_nmt_keypad.edj
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/data/edc/layout_nmt_keypad.edc)
+ADD_DEPENDENCIES(${PROJECT_NAME} layout_nmt_keypad.edj)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/layout_nmt_keypad.edj DESTINATION ${ISE_RESDIR}/edje)
+
 if(${TARGET} STREQUAL "mobile")
 ADD_CUSTOM_TARGET( customised_ctxpopup.edj COMMAND edje_cc
         -id ${CMAKE_CURRENT_SOURCE_DIR}/edje/mobile
diff --git a/data/edc/layout_nmt_keypad.edc b/data/edc/layout_nmt_keypad.edc
new file mode 100644 (file)
index 0000000..c76ace0
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2021 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.
+ *
+ */
+
+#define CANDIDATE_WINDOW_HEIGHT                                                60
+
+#define NMT_AREA_WIDTH_PORT                                    480
+#define NMT_AREA_HEIGHT_PORT                                   220
+
+#define NMT_AREA_HEIGHT_OFFSET_FROM_BOTTOM_PORT                90
+#define NMT_AREA_HEIGHT_OFFSET_FROM_BOTTOM_LAND                64
+
+#define NMT_AREA_WIDTH_LAND                                    800
+#define NMT_AREA_HEIGHT_LAND                                   158
+
+#define TOP_VERTICAL_BORDER_LAND_CANDIDATE_ON          (6 + CANDIDATE_WINDOW_HEIGHT)
+#define TOP_VERTICAL_BORDER_LAND_CANDIDATE_OFF         6
+
+#define BG( COLOR ) \
+       part { name: "bg"; \
+               type: RECT; \
+               scale : 1; \
+               description { state: "default" 0.0; \
+                       rel1.relative: 0.0 0.0; \
+                       rel2.relative: 1.0 1.0; \
+                       color: COLOR; \
+                       visible: 1; \
+               }       \
+       }       \
+
+#define PAD( l, r, t, b) \
+    part { name: "pad_tl"; \
+       type: SPACER; \
+       scale: 1; \
+       description { state: "default" 0.0; \
+         align: 0.0 0.0; \
+         min: l t; \
+         fixed: 1 1; \
+         rel1 { \
+                relative: 0.0 0.0; \
+         } \
+         rel2 { \
+                relative: 0.0 0.0; \
+         } \
+       } \
+    } \
+    part { name: "pad_rb"; \
+       type: SPACER; \
+       scale: 1; \
+       description { state: "default" 0.0; \
+                 align: 1.0 1.0; \
+          min: r b; \
+         fixed: 1 1; \
+         rel1 { \
+                relative: 1.0 1.0; \
+         } \
+         rel2 { \
+                relative: 1.0 1.0; \
+         } \
+       } \
+    } \
+
+
+collections
+{
+       base_scale: 1.8;
+       group
+       {
+               name:   "nmt.main.portrait.candidate.on";
+               parts
+               {
+                       BG( 0 0 0 0)
+                       PAD( 0, 0, TOP_VERTICAL_BORDER_LAND_CANDIDATE_ON, NMT_AREA_HEIGHT_OFFSET_FROM_BOTTOM_PORT)
+                       part
+                       {
+                               name:"nmt.swallow.source_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.1 0.25; }
+                                       rel2 { relative: 0.4 0.5; }
+                               }
+                       }
+
+                       part
+                       {
+                               name:"nmt.swallow.target_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.6 0.25; }
+                                       rel2 { relative: 0.9 0.5; }
+                               }
+                       }
+               }
+       }
+
+       group
+       {
+               name:   "nmt.main.portrait.candidate.off";
+               parts
+               {
+                       BG( 0 0 0 0)
+                       PAD( 0, 0, TOP_VERTICAL_BORDER_LAND_CANDIDATE_OFF, NMT_AREA_HEIGHT_OFFSET_FROM_BOTTOM_PORT)
+                       part
+                       {
+                               name:"nmt.swallow.source_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.1 0.25; }
+                                       rel2 { relative: 0.4 0.5; }
+                               }
+                       }
+
+                       part
+                       {
+                               name:"nmt.swallow.target_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.6 0.25; }
+                                       rel2 { relative: 0.9 0.5; }
+                               }
+                       }
+               }
+       }
+
+       group
+       {
+               name:   "nmt.main.landscape.candidate.on";
+               parts
+               {
+
+                       BG( 0 0 0 0)
+                       PAD( 0, 0, TOP_VERTICAL_BORDER_LAND_CANDIDATE_ON, NMT_AREA_HEIGHT_OFFSET_FROM_BOTTOM_LAND)
+                       part
+                       {
+                               name:"nmt.swallow.source_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.1 0.1; }
+                                       rel2 { relative: 0.4 0.35; }
+                               }
+                       }
+
+                       part
+                       {
+                               name:"nmt.swallow.target_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.6 0.1; }
+                                       rel2 { relative: 0.9 0.35; }
+                               }
+                       }
+               }
+       }
+
+       group
+       {
+               name:   "nmt.main.landscape.candidate.off";
+               parts
+               {
+                       BG( 0 0 0 0)
+                       PAD( 0, 0, TOP_VERTICAL_BORDER_LAND_CANDIDATE_OFF, NMT_AREA_HEIGHT_OFFSET_FROM_BOTTOM_LAND)
+                       part
+                       {
+                               name:"nmt.swallow.source_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.1 0.1; }
+                                       rel2 { relative: 0.4 0.35; }
+                               }
+                       }
+
+                       part
+                       {
+                               name:"nmt.swallow.target_language";
+                               type: SWALLOW;
+                               scale: 1;
+                               description
+                               {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.6 0.1; }
+                                       rel2 { relative: 0.9 0.35; }
+                               }
+                       }
+               }
+       }
+}
index 713630f..126adb6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<layout width="468" height="242" style="popup" key_width="75" key_height="116" key_spacing="0" row_spacing="2" hit_left="1" hit_right="1" hit_top="1" hit_bottom="1" label_type="PUNC_POPUP" vibe_style="DEFAULT" sound_style="DEFAULT">
+<layout width="545" height="242" style="popup" key_width="75" key_height="116" key_spacing="0" row_spacing="2" hit_left="1" hit_right="1" hit_top="1" hit_bottom="1" label_type="PUNC_POPUP" vibe_style="DEFAULT" sound_style="DEFAULT">
   <image_path>
     <button_normal>nine patch/popup_bg.#.png</button_normal>
   </image_path>
@@ -7,7 +7,7 @@
     <rec button="pressed">nine patch/popup_bg_press_middle.#.png</rec>
   </background_image>
   <row>
-    <key button_type="uiitem" x="0" y="0" width="468" height="242">
+    <key button_type="uiitem" x="0" y="0" width="545" height="242">
       <background_image>
         <rec>nine patch/popup_stroke.#.png</rec>
       </background_image>
         <rec>@</rec>
       </label>
     </key>
+    <key button_type="uiitem" width="2">
+      <background_image>
+        <rec button="normal">nine patch/popup_line.9.png</rec>
+      </background_image>
+    </key>
+    <key hit_right="4">
+      <label>
+        <rec>-</rec>
+      </label>
+    </key>
   </row>
   <row x="0" y="120">
-    <key button_type="uiitem" width="468" height="2">
+    <key button_type="uiitem" width="545" height="2">
       <background_image>
         <rec button="normal">nine patch/popup_line.9.png</rec>
       </background_image>
         <rec button="disabled">icon/bubble/icon_sticker_dim.png</rec>
       </image_label>
     </key>
+    <key button_type="uiitem" width="2">
+      <background_image>
+        <rec button="normal">nine patch/popup_line.9.png</rec>
+      </background_image>
+    </key>
+    <key key_type="modechange" custom_id="TRANSLATION_KEY">
+      <key_value>
+        <rec>TRANSLATION_LAYOUT</rec>
+      </key_value>
+      <image_label>
+        <rec button="normal">icon/bubble/icon_translation.png</rec>
+        <rec button="pressed">icon/bubble/icon_translation_press.png</rec>
+        <rec button="disabled">icon/bubble/icon_translation_dim.png</rec>
+      </image_label>
+    </key>
   </row>
 </layout>
diff --git a/data/layout/common/LYT_LANDSCAPE_NMT.xml b/data/layout/common/LYT_LANDSCAPE_NMT.xml
new file mode 100644 (file)
index 0000000..e1dffb9
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<layout direction="landscape" width="1280" height="318" key_width="180" key_height="120" vibe_style="DEFAULT" sound_style="DEFAULT" label_type="3X4_STT" sw_background="true">
+  <background_color>
+    <r>210</r>
+    <g>213</g>
+    <b>217</b>
+    <a>255</a>
+  </background_color>
+  <background_image>
+    <rec button="normal">nine patch/btn_01.#.png</rec>
+    <rec button="pressed">nine patch/btn_press.#.png</rec>
+    <rec button="disabled">nine patch/btn_01.#.png</rec>
+  </background_image>
+  <row y="246">
+    <key button_type="selfish" key_type="modechange" x="10" width="150" height="63">
+      <label>
+        <rec>abc</rec>
+      </label>
+      <key_value>
+        <rec>CUR_LANG</rec>
+      </key_value>
+    </key>
+    <key key_type="user" custom_id="Translate" x="368" width="544" height="63">
+      <label>
+        <rec>Translate</rec>
+      </label>
+      <key_value>
+        <rec>Translate</rec>
+      </key_value>
+    </key>
+  </row>
+</layout>
diff --git a/data/layout/common/LYT_PORTRAIT_NMT.xml b/data/layout/common/LYT_PORTRAIT_NMT.xml
new file mode 100644 (file)
index 0000000..37d181a
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<layout width="720" height="442" key_width="180" key_height="120" vibe_style="DEFAULT" sound_style="DEFAULT" label_type="3X4_STT" sw_background="true">
+  <background_color>
+    <r>210</r>
+    <g>213</g>
+    <b>217</b>
+    <a>255</a>
+  </background_color>
+  <background_image>
+    <rec button="normal">nine patch/btn_01.#.png</rec>
+    <rec button="pressed">nine patch/btn_press.#.png</rec>
+    <rec button="disabled">nine patch/btn_01.#.png</rec>
+  </background_image>
+  <row y="340">
+    <key button_type="selfish" key_type="modechange" x="8" width="150" height="80">
+      <label>
+        <rec>abc</rec>
+      </label>
+      <key_value>
+        <rec>CUR_LANG</rec>
+      </key_value>
+    </key>
+    <key key_type="user" custom_id="Translate" x="185" width="350" height="80">
+      <label>
+        <rec>Translate</rec>
+      </label>
+      <key_value>
+        <rec>Translate</rec>
+      </key_value>
+    </key>
+  </row>
+</layout>
index 2235cd8..bb593af 100644 (file)
       <landscape>LYT_LANDSCAPE_STICKER.xml</landscape>
     </layouts>
   </mode>
+  <mode name="TRANSLATION_LAYOUT">
+    <layouts>
+      <portrait>LYT_PORTRAIT_NMT.xml</portrait>
+      <landscape>LYT_LANDSCAPE_NMT.xml</landscape>
+    </layouts>
+  </mode>
 </input_mode_table>
index 35c6d2b..178d613 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<layout width="468" height="242" style="popup" key_width="75" key_height="116" key_spacing="0" row_spacing="2" hit_left="1" hit_right="1" hit_top="1" hit_bottom="1" label_type="PUNC_POPUP" vibe_style="DEFAULT" sound_style="DEFAULT">
+<layout width="545" height="242" style="popup" key_width="75" key_height="116" key_spacing="0" row_spacing="2" hit_left="1" hit_right="1" hit_top="1" hit_bottom="1" label_type="PUNC_POPUP" vibe_style="DEFAULT" sound_style="DEFAULT">
   <image_path>
     <button_normal>nine patch/popup_bg.#.png</button_normal>
   </image_path>
@@ -7,7 +7,7 @@
     <rec button="pressed">nine patch/popup_bg_press_middle.#.png</rec>
   </background_image>
   <row>
-    <key button_type="uiitem" x="0" y="0" width="468" height="242">
+    <key button_type="uiitem" x="0" y="0" width="545" height="242">
       <background_image>
         <rec>nine patch/popup_stroke.#.png</rec>
       </background_image>
         <rec>@</rec>
       </label>
     </key>
+    <key button_type="uiitem" width="2">
+      <background_image>
+        <rec button="normal">nine patch/popup_line.9.png</rec>
+      </background_image>
+    </key>
+    <key hit_right="4">
+      <label>
+        <rec>-</rec>
+      </label>
+    </key>
   </row>
   <row x="0" y="120">
-    <key button_type="uiitem" width="468" height="2">
+    <key button_type="uiitem" width="545" height="2">
       <background_image>
         <rec button="normal">nine patch/popup_line.9.png</rec>
       </background_image>
         <rec button="disabled">icon/bubble/icon_sticker_dim.png</rec>
       </image_label>
     </key>
+    <key button_type="uiitem" width="2">
+      <background_image>
+        <rec button="normal">nine patch/popup_line.9.png</rec>
+      </background_image>
+    </key>
+    <key key_type="modechange" custom_id="TRANSLATION_KEY">
+      <key_value>
+        <rec>TRANSLATION_LAYOUT</rec>
+      </key_value>
+      <image_label>
+        <rec button="normal">icon/bubble/icon_translation.png</rec>
+        <rec button="pressed">icon/bubble/icon_translation_press.png</rec>
+        <rec button="disabled">icon/bubble/icon_translation_dim.png</rec>
+      </image_label>
+    </key>
   </row>
 </layout>
diff --git a/data/layout/mobile/LYT_LANDSCAPE_NMT.xml b/data/layout/mobile/LYT_LANDSCAPE_NMT.xml
new file mode 100644 (file)
index 0000000..39d91c8
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<layout direction="landscape" width="1280" height="318" key_width="180" key_height="120" vibe_style="DEFAULT" sound_style="DEFAULT" label_type="3X4_STT" sw_background="true">
+  <background_color>
+    <r>210</r>
+    <g>213</g>
+    <b>217</b>
+    <a>255</a>
+  </background_color>
+  <background_image>
+    <rec button="normal">nine patch/btn_01.#.png</rec>
+    <rec button="pressed">nine patch/btn_press.#.png</rec>
+    <rec button="disabled">nine patch/btn_01.#.png</rec>
+  </background_image>
+  <row y="246">
+    <key button_type="selfish" key_type="modechange" x="8" width="150" height="80">
+      <label>
+        <rec>abc</rec>
+      </label>
+      <key_value>
+        <rec>CUR_LANG</rec>
+      </key_value>
+    </key>
+    <key key_type="user" custom_id="Translate" x="185" width="350" height="80">
+      <label>
+        <rec>Translate</rec>
+      </label>
+      <key_value>
+        <rec>Translate</rec>
+      </key_value>
+    </key>
+  </row>
+</layout>
diff --git a/data/layout/mobile/LYT_PORTRAIT_NMT.xml b/data/layout/mobile/LYT_PORTRAIT_NMT.xml
new file mode 100644 (file)
index 0000000..37d181a
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<layout width="720" height="442" key_width="180" key_height="120" vibe_style="DEFAULT" sound_style="DEFAULT" label_type="3X4_STT" sw_background="true">
+  <background_color>
+    <r>210</r>
+    <g>213</g>
+    <b>217</b>
+    <a>255</a>
+  </background_color>
+  <background_image>
+    <rec button="normal">nine patch/btn_01.#.png</rec>
+    <rec button="pressed">nine patch/btn_press.#.png</rec>
+    <rec button="disabled">nine patch/btn_01.#.png</rec>
+  </background_image>
+  <row y="340">
+    <key button_type="selfish" key_type="modechange" x="8" width="150" height="80">
+      <label>
+        <rec>abc</rec>
+      </label>
+      <key_value>
+        <rec>CUR_LANG</rec>
+      </key_value>
+    </key>
+    <key key_type="user" custom_id="Translate" x="185" width="350" height="80">
+      <label>
+        <rec>Translate</rec>
+      </label>
+      <key_value>
+        <rec>Translate</rec>
+      </key_value>
+    </key>
+  </row>
+</layout>
index 2235cd8..bb593af 100644 (file)
       <landscape>LYT_LANDSCAPE_STICKER.xml</landscape>
     </layouts>
   </mode>
+  <mode name="TRANSLATION_LAYOUT">
+    <layouts>
+      <portrait>LYT_PORTRAIT_NMT.xml</portrait>
+      <landscape>LYT_LANDSCAPE_NMT.xml</landscape>
+    </layouts>
+  </mode>
 </input_mode_table>
diff --git a/data/pixmaps/default/common/icon/54x54/icon_translation.png b/data/pixmaps/default/common/icon/54x54/icon_translation.png
new file mode 100644 (file)
index 0000000..d4beb50
Binary files /dev/null and b/data/pixmaps/default/common/icon/54x54/icon_translation.png differ
diff --git a/data/pixmaps/default/common/icon/54x54/icon_translation_press.png b/data/pixmaps/default/common/icon/54x54/icon_translation_press.png
new file mode 100644 (file)
index 0000000..54b8c5a
Binary files /dev/null and b/data/pixmaps/default/common/icon/54x54/icon_translation_press.png differ
diff --git a/data/pixmaps/default/common/icon/bubble/icon_translation.png b/data/pixmaps/default/common/icon/bubble/icon_translation.png
new file mode 100644 (file)
index 0000000..d4beb50
Binary files /dev/null and b/data/pixmaps/default/common/icon/bubble/icon_translation.png differ
diff --git a/data/pixmaps/default/common/icon/bubble/icon_translation_press.png b/data/pixmaps/default/common/icon/bubble/icon_translation_press.png
new file mode 100644 (file)
index 0000000..54b8c5a
Binary files /dev/null and b/data/pixmaps/default/common/icon/bubble/icon_translation_press.png differ
diff --git a/data/pixmaps/default/mobile/icon/54x54/icon_translation.png b/data/pixmaps/default/mobile/icon/54x54/icon_translation.png
new file mode 100644 (file)
index 0000000..d4beb50
Binary files /dev/null and b/data/pixmaps/default/mobile/icon/54x54/icon_translation.png differ
diff --git a/data/pixmaps/default/mobile/icon/54x54/icon_translation_press.png b/data/pixmaps/default/mobile/icon/54x54/icon_translation_press.png
new file mode 100644 (file)
index 0000000..54b8c5a
Binary files /dev/null and b/data/pixmaps/default/mobile/icon/54x54/icon_translation_press.png differ
diff --git a/data/pixmaps/default/mobile/icon/bubble/icon_translation.png b/data/pixmaps/default/mobile/icon/bubble/icon_translation.png
new file mode 100644 (file)
index 0000000..d4beb50
Binary files /dev/null and b/data/pixmaps/default/mobile/icon/bubble/icon_translation.png differ
diff --git a/data/pixmaps/default/mobile/icon/bubble/icon_translation_press.png b/data/pixmaps/default/mobile/icon/bubble/icon_translation_press.png
new file mode 100644 (file)
index 0000000..54b8c5a
Binary files /dev/null and b/data/pixmaps/default/mobile/icon/bubble/icon_translation_press.png differ
index 5483e16..a9b6d4b 100644 (file)
     <privilege>http://tizen.org/privilege/externalstorage</privilege>
     <privilege>http://tizen.org/privilege/mediastorage</privilege>
     <privilege>http://tizen.org/privilege/keymanager</privilege>
+    <privilege>http://tizen.org/privilege/datasharing</privilege>
 </privileges>
 </manifest>
diff --git a/lib/aarch64/libsamsung-ai-nmt.so b/lib/aarch64/libsamsung-ai-nmt.so
new file mode 100755 (executable)
index 0000000..fec8200
Binary files /dev/null and b/lib/aarch64/libsamsung-ai-nmt.so differ
diff --git a/lib/armv7l/libsamsung-ai-nmt.so b/lib/armv7l/libsamsung-ai-nmt.so
new file mode 100755 (executable)
index 0000000..6d36ffb
Binary files /dev/null and b/lib/armv7l/libsamsung-ai-nmt.so differ
diff --git a/lib/i586/libsamsung-ai-nmt.so b/lib/i586/libsamsung-ai-nmt.so
new file mode 100755 (executable)
index 0000000..04398db
Binary files /dev/null and b/lib/i586/libsamsung-ai-nmt.so differ
index 237daea..9e39b4c 100644 (file)
@@ -32,6 +32,9 @@ BuildRequires:  pkgconfig(pkgmgr-info)
 BuildRequires:  pkgconfig(capi-ui-sticker-consumer)
 BuildRequires:  pkgconfig(capi-content-mime-type)
 BuildRequires:  pkgconfig(json-glib-1.0)
+BuildRequires:  pkgconfig(bundle)
+BuildRequires:  pkgconfig(rpc-port)
+BuildRequires:  pkgconfig(capi-appfw-event)
 Requires:       ise-engine-glm
 Requires:       ise-engine-default
 
@@ -164,6 +167,8 @@ export CFLAGS_BASE="${CFLAGS} -DTIZEN_DEBUG_ENABLE -fvisibility=hidden"
 export CXXFLAGS_BASE="${CXXFLAGS} -DTIZEN_DEBUG_ENABLE -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden"
 export FFLAGS+=" -DTIZEN_DEBUG_ENABLE"
 
+export LD_LIBRARY_PATH=%{TZ_SYS_RO_APP}/ise-default/lib
+
 rm -rf CMakeFiles
 rm -rf CMakeCache.txt
 
@@ -360,6 +365,7 @@ popd
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
 %{TZ_SYS_RO_PACKAGES}/%{name}.xml
+%{TZ_SYS_RO_APP}/ise-default/lib/*
 %license LICENSE
 
 # This is for old profile-based OBS project optimizations.
@@ -568,4 +574,4 @@ fi
 %files -n ise-default-config
 %manifest ise-default-config/ise-default-config.manifest
 %{_sysconfdir}/ise/conf/*
-%license LICENSE
\ No newline at end of file
+%license LICENSE
diff --git a/src/include/ise-nmt-mode.h b/src/include/ise-nmt-mode.h
new file mode 100644 (file)
index 0000000..2c8c6f8
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021 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 _ISE_NMT_MODE_H_
+#define _ISE_NMT_MODE_H_
+
+#include <Evas.h>
+
+void ise_nmt_show_layout(int screen_degree, bool is_candidate_on, Evas_Object *main_window);
+void ise_nmt_destroy_layout();
+bool ise_nmt_is_show();
+void ise_nmt_translate();
+
+#endif /* _ISE_NMT_MODE_H_ */
diff --git a/src/include/nmt.h b/src/include/nmt.h
new file mode 100644 (file)
index 0000000..f58b17f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 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 ISE_NMT_H_
+#define ISE_NMT_H_
+
+bool nmt_init();
+void nmt_shutdown();
+
+void nmt_translate(const char *source_language, const char *target_language);
+
+#endif /* ISE_NMT_H_ */
diff --git a/src/include/samsung_ai_nmt.h b/src/include/samsung_ai_nmt.h
new file mode 100644 (file)
index 0000000..ad0ead3
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2020 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 __SAMSUNG_EXPERIENCE_SERVICE_SAMSUNG_AI_NMT_H__
+#define __SAMSUNG_EXPERIENCE_SERVICE_SAMSUNG_AI_NMT_H__
+
+/**
+ * @file samsung_ai_nmt.h
+ * @brief This file contains Samsung AI Neural Machine Translation APIs and related enumeration.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <tizen.h>
+
+/**
+ * @addtogroup CAPI_SAMSUNG_AI_NMT_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for Samsung AI NMT function error.
+ * @since_ses 7
+ */
+typedef enum {
+       SAMSUNG_AI_NMT_ERROR_NONE = TIZEN_ERROR_NONE,                           /**< Successful */
+       SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED,         /**< Not supported */
+       SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+       SAMSUNG_AI_NMT_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+       SAMSUNG_AI_NMT_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY,         /**< Out of memory */
+       SAMSUNG_AI_NMT_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT,                 /**< No answer from Samsung AI NMT service */
+       SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE = TIZEN_ERROR_UNKNOWN - 1,     /**< Service unavailable */
+       SAMSUNG_AI_NMT_ERROR_NOT_CONNECTED = TIZEN_ERROR_UNKNOWN - 2,           /**< Not connected */
+       SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED = TIZEN_ERROR_UNKNOWN - 3,        /**< Operation failed */
+       SAMSUNG_AI_NMT_ERROR_OVER_MAX_INPUT_LENGTH = TIZEN_ERROR_UNKNOWN - 4,   /**< Over max input length */
+       SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED_SOURCE_LANGUAGE = TIZEN_ERROR_UNKNOWN - 5, /**< Not supported source language */
+       SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED_TARGET_LANGUAGE = TIZEN_ERROR_UNKNOWN - 6, /**< Not supported target language */
+       SAMSUNG_AI_NMT_ERROR_ONGOING_CONNECT = TIZEN_ERROR_UNKNOWN - 7,               /**< Ongoing connect (Since API level 9) */
+} samsung_ai_nmt_error_e;
+
+/**
+ * @brief Enumeration of connection status.
+ * @since_ses 7
+ */
+typedef enum {
+       SAMSUNG_AI_NMT_CONNECTION_STATUS_CONNECTED = 0,   /**< Connected */
+       SAMSUNG_AI_NMT_CONNECTION_STATUS_DISCONNECTED,    /**< Disconnected */
+       SAMSUNG_AI_NMT_CONNECTION_STATUS_REJECTED,        /**< Rejected */
+       SAMSUNG_AI_NMT_CONNECTION_STATUS_RECONNECTED,     /**< Reconnected (Since API level 9) */
+} samsung_ai_nmt_connection_status_e;
+
+/**
+ * @brief The Samsung AI NMT handle.
+ * @since_ses 7
+ */
+typedef struct samsung_ai_nmt_s *samsung_ai_nmt_h;
+
+/**
+ * @brief Called when the connection status is changed.
+ * @details The following error codes can be received: \n
+        #SAMSUNG_AI_NMT_ERROR_NONE:                        Success \n
+        #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE:         Service unavailable \n
+ * @since_ses 7
+ * @remarks The @a nmt_h should not be freed and can be used only in the callback.\n
+ *          The @a nmt_h is the same object for which the callback was set.\n
+ * @param[in] nmt_h The Samsung AI NMT handle
+ * @param[in] result The connection result
+ * @param[in] status The connection status
+ * @param[in] user_data The user data passed from the callback function
+ * @see samsung_ai_nmt_create()
+ */
+typedef void (*samsung_ai_nmt_connection_status_changed_cb)(samsung_ai_nmt_h nmt_h, samsung_ai_nmt_error_e result, samsung_ai_nmt_connection_status_e status, void* user_data);
+
+/**
+ * @brief Called when the NMT agent sends the translation result.
+ * @details The following error codes can be received: \n
+        #SAMSUNG_AI_NMT_ERROR_NONE:                            Success \n
+        #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED_SOURCE_LANGUAGE:   Not supported source language \n
+        #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED_TARGET_LANGUAGE:   Not supported target language \n
+        #SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED:                Operation failed \n
+ * @since_ses 7
+ * @remarks The @a nmt_h should not be freed and can be used only in the callback.\n
+ *          The @a nmt_h is the same object for which the callback was set.\n
+ *          The @a translated_text must be released with @c free() by caller.\n *
+ * @param[in] nmt_h           The Samsung AI NMT handle
+ * @param[in] request_id      The request ID
+ * @param[in] result          The translation result
+ * @param[in] translated_text The translated text
+ * @param[in] user_data       The user data passed from the callback function
+ * @see samsung_ai_nmt_set_translate_result_cb()
+ * @see samsung_ai_nmt_unset_translate_result_cb()
+ */
+typedef void (*samsung_ai_nmt_translate_result_cb)(samsung_ai_nmt_h nmt_h, unsigned int request_id, samsung_ai_nmt_error_e result, char *translated_text, void *user_data);
+
+/**
+ * @brief Called to retrieve the available languages.
+ * @since_ses 7
+ * @remarks The @a nmt_h should not be freed and can be used only in the callback.
+ *          The @a language can be used only in the callback. To use outside, make a copy.
+ *
+ * @param[in] nmt_h      The Samsung AI NMT handle
+ * @param[in] language   The available language (ISO 639-1 format such as "en")
+ * @param[in] user_data  The user data passed from the callback function
+ * @see samsung_ai_nmt_foreach_available_source_languages()
+ */
+typedef bool (*samsung_ai_nmt_available_language_cb)(samsung_ai_nmt_h nmt_h, const char* language, void* user_data);
+
+/**
+ * @brief Creates a handle for Samsung AI NMT and Connects to Samsung AI NMT service.
+ * @since_ses 7
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/appmanager.launch \n
+ *            %http://tizen.org/privilege/datasharing
+ * @remarks If the function succeeds, the @a nmt_h handle must be released with samsung_ai_nmt_destroy().
+ *
+ * @param[out] nmt_h     The Samsung AI NMT handle
+ * @param[in] callback   The connection status changed callback function
+ * @param[in] user_data  The user data passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                 No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED        Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_PERMISSION_DENIED    Permission denied
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE  Service unavailable
+ * @retval #SAMSUNG_AI_NMT_ERROR_OUT_OF_MEMORY        Out of memory
+ * @see samsung_ai_nmt_destroy()
+ */
+int samsung_ai_nmt_create(samsung_ai_nmt_h* nmt_h, samsung_ai_nmt_connection_status_changed_cb callback, void* user_data);
+
+/**
+ * @brief Destroys an Samsung AI NMT handle.
+ * @since_ses 7
+ * @param[in] nmt_h   The Samsung AI NMT handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                 No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED        Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE  Service unavailable
+ * @see s_ai_mt_create()
+ */
+int samsung_ai_nmt_destroy(samsung_ai_nmt_h nmt_h);
+
+/**
+ * @brief Requests a translation from the Samsung AI NMT.
+ * @since_ses 7
+ *
+ * @remarks The translatable length of @a text can be retrieved by using #samsung_ai_nmt_get_max_translatable_text_length function.
+ *
+ * @param[in] nmt_h            The Samsung AI NMT handle
+ * @param[in] text             The text to translate
+ * @param[in] source_language  The source language (ISO 639-1 format such as "en")
+ * @param[in] target_language  The target language (ISO 639-1 format such as "ko")
+ * @param[out] request_id      The request ID
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                  No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED         Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE   Service unavailable
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_CONNECTED         Not connected
+ * @retval #SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #SAMSUNG_AI_NMT_ERROR_OVER_MAX_INPUT_LENGTH Over max input length
+ * @retval #SAMSUNG_AI_NMT_ERROR_ONGOING_CONNECT       Ongoing connect
+ * @pre samsung_ai_nmt_set_translate_result_cb() should be called to receive the translated result.
+ */
+int samsung_ai_nmt_translate(samsung_ai_nmt_h nmt_h, const char *text, const char *source_language, const char *target_language, unsigned int *request_id);
+
+/**
+ * @brief Retrieves all available source languages of Samsung AI NMT service using callback function.
+ * @since_ses 7
+ *
+ * @param[in] nmt_h      The Samsung AI NMT handle
+ * @param[in] callback   The available source language callback function
+ * @param[in] user_data  The user data passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED       Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE Service unavailable
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_CONNECTED       Not connected
+ * @retval #SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED    Operation failed
+ * @retval #SAMSUNG_AI_NMT_ERROR_ONGOING_CONNECT     Ongoing connect
+ * @post This function invokes samsung_ai_nmt_available_language_cb() repeatedly for getting languages.
+ * @see samsung_ai_nmt_available_language_cb()
+ */
+int samsung_ai_nmt_foreach_available_source_languages(samsung_ai_nmt_h nmt_h, samsung_ai_nmt_available_language_cb callback, void* user_data);
+
+/**
+ * @brief Retrieves all available target languages given the @a source_language of Samsung AI NMT service using callback function.
+ * @since_ses 7
+ *
+ * @param[in] nmt_h      The Samsung AI NMT handle
+ * @param[in] source_language  The source language (ISO 639-1 format such as "en")
+ * @param[in] callback   The available target language callback function
+ * @param[in] user_data  The user data passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED       Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE Service unavailable
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_CONNECTED       Not connected
+ * @retval #SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED    Operation failed
+ * @retval #SAMSUNG_AI_NMT_ERROR_ONGOING_CONNECT     Ongoing connect
+ * @post This function invokes samsung_ai_nmt_available_language_cb() repeatedly for getting languages.
+ * @see samsung_ai_nmt_available_language_cb()
+ */
+int samsung_ai_nmt_foreach_available_target_languages(samsung_ai_nmt_h nmt_h, const char *source_language, samsung_ai_nmt_available_language_cb callback, void* user_data);
+
+/**
+ * @brief Detects given @a text language.
+ * @since_ses 9
+ *
+ * @remarks The @a language must be released with @c free() by caller.\n
+ *
+ * @param[in] nmt_h            The Samsung AI NMT handle
+ * @param[in] text             The text to translate
+ * @param[out] language        The detected language
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED       Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE Service unavailable
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_CONNECTED       Not connected
+ * @retval #SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED    Operation failed
+ * @retval #SAMSUNG_AI_NMT_ERROR_ONGOING_CONNECT     Ongoing connect
+ */
+int samsung_ai_nmt_detect_language(samsung_ai_nmt_h nmt_h, const char *text, char **language);
+
+/**
+ * @brief Retrieves the maximum length of text that can be translated. Attempt to translate longer text will fail.
+ * @since_ses 10
+ *
+ * @param[in] nmt_h            The Samsung AI NMT handle
+ * @param[out] length          The translatable max length
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED       Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE Service unavailable
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_CONNECTED       Not connected
+ * @retval #SAMSUNG_AI_NMT_ERROR_OPERATION_FAILED    Operation failed
+ * @retval #SAMSUNG_AI_NMT_ERROR_ONGOING_CONNECT     Ongoing connect
+ */
+int samsung_ai_nmt_get_max_translatable_text_length(samsung_ai_nmt_h nmt_h, int *length);
+
+/**
+ * @brief  Sets a callback function to be invoked when the NMT agent sends the translated result.
+ * @since_ses 7
+ *
+ * @param[in] nmt_h      The Samsung AI NMT handle
+ * @param[in] callback   The callback function to register
+ * @param[in] user_data  The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED       Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE Service unavailable
+ * @see samsung_ai_nmt_unset_translate_result_cb()
+ */
+int samsung_ai_nmt_set_translate_result_cb(samsung_ai_nmt_h nmt_h, samsung_ai_nmt_translate_result_cb callback, void *user_data);
+
+/**
+ * @brief  Unsets a callback function to be invoked when the NMT agent sends the translated result.
+ * @since_ses 7
+ *
+ * @param[in] nmt_h      The Samsung AI NMT handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #SAMSUNG_AI_NMT_ERROR_NONE                No error
+ * @retval #SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED       Not supported
+ * @retval #SAMSUNG_AI_NMT_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval #SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE Service unavailable
+ * @see samsung_ai_nmt_set_translate_result_cb()
+ */
+int samsung_ai_nmt_unset_translate_result_cb(samsung_ai_nmt_h nmt_h);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SAMSUNG_EXPERIENCE_SERVICE_SAMSUNG_AI_NMT_H__ */
diff --git a/src/ise-nmt-mode.cpp b/src/ise-nmt-mode.cpp
new file mode 100644 (file)
index 0000000..76df939
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2021 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 "ise-nmt-mode.h"
+#include "config.h"
+#include "candidate-factory.h"
+#include "ise.h"
+#include "nmt.h"
+#include <samsung_ai_nmt.h>
+#include <inputmethod.h>
+#include <sclutils.h>
+#include <sclfeedback.h>
+#include <vector>
+#include <string>
+
+#undef LOG_TAG
+#define LOG_TAG "ISE_DEFAULT"
+
+using namespace std;
+
+#define EVAS_CANDIDATE_LAYER    32000
+
+#define ISE_HEIGHT_PORT         442
+#define ISE_HEIGHT_LAND         318
+
+#define NMT_LAYOUT_LEFT_MARGIN 88
+#define IND_NUM 20
+
+#define NMT_EDJ_FILE_PATH RESDIR"/edje/layout_nmt_keypad.edj"
+
+#define NMT_EDJ_GROUP_PORT_CANDIDATE_ON "nmt.main.portrait.candidate.on"
+#define NMT_EDJ_GROUP_LAND_CANDIDATE_ON "nmt.main.landscape.candidate.on"
+
+#define NMT_EDJ_GROUP_PORT_CANDIDATE_OFF "nmt.main.portrait.candidate.off"
+#define NMT_EDJ_GROUP_LAND_CANDIDATE_OFF "nmt.main.landscape.candidate.off"
+
+static Evas_Object *layout = NULL;
+
+static Evas_Object *source_language_hover = NULL, *target_language_hover = NULL;
+
+static bool is_nmt_mode = false;
+
+const char *source_language_list[] = { "English", "Korean", "German", "Russian", "Spanish", "French", "Italian", "Portuguese", "Chinese" };
+const char *target_language_list[] = { "Korean", "English", "German", "Russian", "Spanish", "French", "Italian", "Portuguese", "Chinese" };
+
+struct _language_item {
+    const char *language;
+    const char *code;
+};
+
+static struct _language_item _lang_its[] = {
+    { "Korean",     "ko" },
+    { "English",    "en" },
+    { "German",     "de" },
+    { "Russian",    "ru" },
+    { "Spanish",    "es" },
+    { "French",     "fr" },
+    { "Italian",    "it" },
+    { "Portuguese", "pt" },
+    { "Chinese",    "zh" },
+    { NULL,         NULL }
+};
+
+static string get_language_code(const char *language)
+{
+    string language_code;
+    int idx = 0;
+
+    if (!language)
+        return language_code;
+
+    while (_lang_its[idx].language != NULL) {
+        if (strncmp(_lang_its[idx].language, language, strlen(language)) == 0) {
+            language_code = string(_lang_its[idx].code);
+            break;
+        }
+        idx++;
+    }
+
+    return language_code;
+}
+
+static void
+hoversel_selected_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
+                    void *event_info)
+{
+    const char *txt = elm_object_item_text_get((Elm_Widget_Item *)event_info);
+
+    dlog_print(DLOG_INFO, LOG_TAG, "'selected' callback is called. (selected item : %s)", txt);
+
+    elm_object_text_set(obj, txt ? txt : "");
+}
+
+static Evas_Object *
+create_language_hover(Evas_Object *parent, const char *text)
+{
+    Evas_Object *hoversel = elm_hoversel_add(parent);
+    elm_hoversel_hover_parent_set(hoversel, parent);
+    elm_object_text_set(hoversel, text);
+
+    evas_object_size_hint_align_set(hoversel, 0.5, 0.5);
+    evas_object_size_hint_weight_set(hoversel, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_show(hoversel);
+
+    evas_object_smart_callback_add(hoversel, "selected", hoversel_selected_cb, NULL);
+
+    return hoversel;
+}
+
+void ise_nmt_show_layout(int screen_degree, bool is_candidate_on, Evas_Object *main_window)
+{
+    CSCLUI *ui = get_ui();
+    if (!ui)
+        return;
+
+    CONFIG_VALUES *config_values = get_config_values();
+    if (!config_values)
+        return;
+
+    ise_nmt_destroy_layout();
+
+    layout = elm_layout_add((Evas_Object *)main_window);
+    evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+    int y = 0;
+    Candidate *candidate = get_candidate();
+    if (candidate && candidate->get_visible())
+        y = candidate->get_height();
+
+    read_ise_config_values();
+    if (config_values->floating_mode)
+        evas_object_move(layout, 0, y + FLOATING_TITLE_BAR_HEIGHT);
+    else
+        evas_object_move(layout, 0, y);
+
+    bool landscape_device = get_landscape_device(screen_degree);
+    if (is_candidate_on) {
+        if (screen_degree == 0 || screen_degree == 180) {
+            elm_layout_file_set(layout, NMT_EDJ_FILE_PATH,
+                                landscape_device ?
+                                NMT_EDJ_GROUP_LAND_CANDIDATE_ON :
+                                NMT_EDJ_GROUP_PORT_CANDIDATE_ON);
+        }
+        else {
+            elm_layout_file_set(layout, NMT_EDJ_FILE_PATH,
+                                landscape_device ?
+                                NMT_EDJ_GROUP_PORT_CANDIDATE_ON :
+                                NMT_EDJ_GROUP_LAND_CANDIDATE_ON);
+        }
+    } else {
+        sclint width = 0;
+        sclint height = 0;
+        ui->get_screen_resolution(&width, &height);
+        LOGD("screen width:%d, height:%d\n", width, height);
+
+        if (screen_degree == 0 || screen_degree == 180) {
+            elm_layout_file_set(layout, NMT_EDJ_FILE_PATH,
+                                landscape_device ?
+                                NMT_EDJ_GROUP_LAND_CANDIDATE_OFF :
+                                NMT_EDJ_GROUP_PORT_CANDIDATE_OFF);
+
+            if (config_values->floating_mode)
+                evas_object_resize(layout, width * FLOATING_SCALE_RATE, ui->get_scaled_y(ISE_HEIGHT_PORT));
+            else
+                evas_object_resize(layout, width, ui->get_scaled_y(landscape_device ? ISE_HEIGHT_LAND : ISE_HEIGHT_PORT));
+        } else {
+            elm_layout_file_set(layout, NMT_EDJ_FILE_PATH,
+                                landscape_device ?
+                                NMT_EDJ_GROUP_PORT_CANDIDATE_OFF :
+                                NMT_EDJ_GROUP_LAND_CANDIDATE_OFF);
+
+            if (config_values->floating_mode)
+                evas_object_resize(layout, width * FLOATING_SCALE_RATE, ui->get_scaled_y(ISE_HEIGHT_LAND) * FLOATING_SCALE_RATE);
+            else {
+                evas_object_resize(layout, width, ui->get_scaled_y(landscape_device ? ISE_HEIGHT_PORT : ISE_HEIGHT_LAND));
+            }
+        }
+
+        if (screen_degree == 0 || screen_degree == 180) {
+            if (landscape_device) {
+                evas_object_resize(layout, width - ui->get_scaled_y(NMT_LAYOUT_LEFT_MARGIN*2), ui->get_scaled_y(ISE_HEIGHT_LAND));
+                evas_object_move(layout, ui->get_scaled_y(NMT_LAYOUT_LEFT_MARGIN), y);
+            }
+        } else {
+            if (config_values->floating_mode) {
+                evas_object_resize(layout, (width - ui->get_scaled_y(NMT_LAYOUT_LEFT_MARGIN*2)) * FLOATING_SCALE_RATE, (ui->get_scaled_y(ISE_HEIGHT_LAND)) * FLOATING_SCALE_RATE);
+                evas_object_move(layout, ui->get_scaled_y(NMT_LAYOUT_LEFT_MARGIN), y + FLOATING_TITLE_BAR_HEIGHT);
+            } else {
+                evas_object_resize(layout, width - ui->get_scaled_y(NMT_LAYOUT_LEFT_MARGIN*2), ui->get_scaled_y(landscape_device ? ISE_HEIGHT_PORT : ISE_HEIGHT_LAND));
+                evas_object_move(layout, ui->get_scaled_y(NMT_LAYOUT_LEFT_MARGIN), y);
+            }
+        }
+    }
+
+    /* Add Source language hoversel */
+    source_language_hover = create_language_hover(layout, source_language_list[0]);
+
+    for (unsigned int i=0; i < sizeof(source_language_list)/sizeof(source_language_list[0]); i++) {
+        elm_hoversel_item_add(source_language_hover, source_language_list[i], NULL, ELM_ICON_NONE, NULL, NULL);
+    }
+
+    /* Add target language hoversel */
+    target_language_hover = create_language_hover(layout, target_language_list[0]);
+    for (unsigned int i=0; i < sizeof(target_language_list)/sizeof(target_language_list[0]); i++) {
+        elm_hoversel_item_add(target_language_hover, target_language_list[i], NULL, ELM_ICON_NONE, NULL, NULL);
+    }
+
+    elm_object_part_content_set(layout, "nmt.swallow.source_language", source_language_hover);
+
+    elm_object_part_content_set(layout, "nmt.swallow.target_language", target_language_hover);
+
+    evas_object_layer_set(layout, EVAS_CANDIDATE_LAYER-1);
+    evas_object_show(layout);
+
+    is_nmt_mode = true;
+}
+
+void ise_nmt_destroy_layout()
+{
+    is_nmt_mode = false;
+
+    if (source_language_hover) {
+        evas_object_del(source_language_hover);
+        source_language_hover = NULL;
+    }
+
+    if (target_language_hover) {
+        evas_object_del(target_language_hover);
+        target_language_hover = NULL;
+    }
+
+    if (layout) {
+        evas_object_del(layout);
+        layout = NULL;
+    }
+}
+
+bool ise_nmt_is_show()
+{
+    return is_nmt_mode;
+}
+
+void ise_nmt_translate()
+{
+    const char *source_language = elm_object_text_get(source_language_hover);
+    const char *target_language = elm_object_text_get(target_language_hover);
+    string nmt_formatted_source_language;
+    string nmt_formatted_target_language;
+
+    dlog_print(DLOG_INFO, LOG_TAG, "@@@ Source language: %s \t Target language: %s ", source_language, target_language);
+
+    nmt_formatted_source_language = get_language_code(source_language);
+
+    nmt_formatted_target_language = get_language_code(target_language);
+
+    nmt_translate(nmt_formatted_source_language.c_str(), nmt_formatted_target_language.c_str());
+}
\ No newline at end of file
index 85b331b..82bf9ed 100644 (file)
@@ -49,6 +49,8 @@
 #include "ise-floating-mode.h"
 #include "ise-dbus.h"
 #include "ise-sticker-mode.h"
+#include "ise-nmt-mode.h"
+#include "nmt.h"
 
 #define EDJ_FILE                        RESDIR"/edje/" PROFILE_NAME"/customised_ctxpopup.edj"
 
@@ -206,7 +208,7 @@ static CandidateEventListener g_candidate_event_listener;
 #define MVK_space 0x020
 #define MVK_Done 0xff0d
 
-#define CM_KEY_LIST_SIZE         6
+#define CM_KEY_LIST_SIZE         7
 #define MULTITAP_TIMEOUT         3.0
 #define USER_KEYSTRING_OPTION    "OPTION"
 #define USER_KEYSTRING_EMOTICON  "EMOTICON_LAYOUT"
@@ -214,11 +216,12 @@ static CandidateEventListener g_candidate_event_listener;
 #define USER_KEYSTRING_VOICE     "STT_3X4"
 #define USER_KEYSTRING_FLOATING  "FLOATING"
 #define USER_KEYSTRING_STICKER   "STICKER_LAYOUT"
+#define USER_KEYSTRING_TRANSLATION "TRANSLATION_LAYOUT"
 
 #define USER_VOICE_LANGUAGE     "LANGUAGE"
 
 static sclboolean           _cm_popup_opened = FALSE;
-static const char          *_cm_key_list[CM_KEY_LIST_SIZE] = {USER_KEYSTRING_OPTION, USER_KEYSTRING_EMOTICON, USER_KEYSTRING_CLIPBOARD, USER_KEYSTRING_VOICE, USER_KEYSTRING_FLOATING, USER_KEYSTRING_STICKER};
+static const char          *_cm_key_list[CM_KEY_LIST_SIZE] = {USER_KEYSTRING_OPTION, USER_KEYSTRING_EMOTICON, USER_KEYSTRING_CLIPBOARD, USER_KEYSTRING_VOICE, USER_KEYSTRING_FLOATING, USER_KEYSTRING_TRANSLATION, USER_KEYSTRING_STICKER};
 static scluint              _current_cm_key_id = 0;
 static Evas_Object* _guide_popup_setting = NULL;
 static Evas_Object* _guide_popup_space = NULL;
@@ -416,6 +419,12 @@ static void ise_set_cm_private_key(scluint cm_key_id)
             const_cast<sclchar*>("icon/54x54/icon_floating_keypad_press.png"),
             const_cast<sclchar*>("icon/54x54/icon_floating_keypad_dim.png")};
         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_FLOATING), TRUE);
+    } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_TRANSLATION) == 0) {
+        sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
+            const_cast<sclchar*>("icon/54x54/icon_translation_nor.png"),
+            const_cast<sclchar*>("icon/54x54/icon_translation_press.png"),
+            const_cast<sclchar*>("icon/54x54/icon_translation_dim.png")};
+        ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_TRANSLATION), TRUE);
     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_STICKER) == 0) {
         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
             const_cast<sclchar*>("icon/54x54/icon_sticker_nor.png"),
@@ -689,6 +698,11 @@ on_input_mode_changed(const sclchar *key_value, sclulong key_event, sclint key_t
         if (ise_emoticon_is_show()) {
             ise_emoticon_destroy_layout();
         }
+
+        if (ise_nmt_is_show()) {
+            ise_nmt_destroy_layout();
+        }
+
         if (key_value) {
             if (!strcmp(key_value, USER_KEYSTRING_EMOTICON)) {
                 ise_emoticon_init_list();
@@ -703,6 +717,11 @@ on_input_mode_changed(const sclchar *key_value, sclulong key_event, sclint key_t
                 SCLRotation rotation = ui->get_rotation();
                 ise_emoticon_show_layout(ise_emoticon_get_current_group(), ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
             }
+            else if (!strcmp(key_value, USER_KEYSTRING_TRANSLATION)) {
+                LOGD("");
+                SCLRotation rotation = ui->get_rotation();
+                ise_nmt_show_layout(ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
+            }
         }
     }
 
@@ -1304,6 +1323,12 @@ SCLEventReturnType CUIEventCallback::on_event_key_clicked(SclUIEventDesc event_d
             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_STICKER) == 0) {
                 SCLRotation rotation = ui->get_rotation();
                 ise_sticker_show_layout(STICKER_GROUP_RECENTLY_USED, ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
+            } else if (strcmp(event_desc.key_value, USER_KEYSTRING_TRANSLATION) == 0) {
+                if (ise_sticker_is_show())
+                    ise_sticker_destroy_layout();
+
+                SCLRotation rotation = ui->get_rotation();
+                ise_nmt_show_layout(ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
             } else if (on_input_mode_changed(event_desc.key_value, event_desc.key_event, event_desc.key_type)) {
                 ret = SCL_EVENT_DONE;
             }
@@ -1311,7 +1336,8 @@ SCLEventReturnType CUIEventCallback::on_event_key_clicked(SclUIEventDesc event_d
                 if (strcmp(event_desc.key_value, USER_KEYSTRING_EMOTICON) == 0 ||
                     strcmp(event_desc.key_value, USER_KEYSTRING_VOICE) == 0 ||
                     strcmp(event_desc.key_value, USER_KEYSTRING_FLOATING) == 0 ||
-                    strcmp(event_desc.key_value, USER_KEYSTRING_STICKER) == 0) {
+                    strcmp(event_desc.key_value, USER_KEYSTRING_STICKER) == 0 ||
+                    strcmp(event_desc.key_value, USER_KEYSTRING_TRANSLATION) == 0) {
                     scluint id = ise_get_cm_key_id(event_desc.key_value);
                     if (id != _current_cm_key_id) {
                         _current_cm_key_id = id;
@@ -1362,6 +1388,8 @@ SCLEventReturnType CUIEventCallback::on_event_key_clicked(SclUIEventDesc event_d
                 ise_send_event(IME_KEY_Return, KEY_MASK_NULL);
                 ime_request_hide();
 #endif
+            } else if (strcmp(event_desc.key_value, "Translate") == 0) {
+                ise_nmt_translate();
             }  else {
                 const sclchar *input_mode = ui->get_input_mode();
                 if ((NULL != input_mode) && (!strcmp(input_mode, "EMOTICON_LAYOUT"))) {
@@ -1716,6 +1744,9 @@ ise_show(int ic)
 
                 if (ise_sticker_is_show())
                     ise_sticker_destroy_layout();
+
+                if (ise_nmt_is_show())
+                    ise_nmt_destroy_layout();
             }
         }
 
@@ -2708,6 +2739,8 @@ static void ime_app_create_cb(void *user_data)
         elm_app_base_scale_set(atof(elm_scale));
 
     clipboard_init();
+
+    nmt_init();
 }
 
 static void ime_app_exit_cb(void *user_data)
@@ -2719,6 +2752,8 @@ static void ime_app_exit_cb(void *user_data)
         LOGE("Failed to finalize dbus");
 
     clipboard_shutdown();
+
+    nmt_shutdown();
 }
 
 static void show_autofill_data()
diff --git a/src/nmt.cpp b/src/nmt.cpp
new file mode 100644 (file)
index 0000000..ea25266
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2021 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 <scltypes.h>
+#include <dlog.h>
+#include <samsung_ai_nmt.h>
+#include <inputmethod.h>
+#include <Ecore.h>
+#include "ise.h"
+
+#include "nmt.h"
+
+#undef LOG_TAG
+#define LOG_TAG "ISE_DEFAULT"
+
+static samsung_ai_nmt_h g_nmt_h;
+static bool g_selected_text_exist = false;
+
+static void _nmt_connection_status_changed_cb(samsung_ai_nmt_h nmt_h, samsung_ai_nmt_error_e result,
+                                              samsung_ai_nmt_connection_status_e status, void *user_data)
+{
+    switch (result) {
+        case SAMSUNG_AI_NMT_ERROR_NONE:
+            if (status == SAMSUNG_AI_NMT_CONNECTION_STATUS_CONNECTED)
+                LOGI("NMT connected");
+            else if (status == SAMSUNG_AI_NMT_CONNECTION_STATUS_DISCONNECTED)
+                LOGI("NMT disconnected");
+            else
+            {
+                LOGI("connection status : %d", status);
+            }
+            break;
+        case SAMSUNG_AI_NMT_ERROR_SERVICE_UNAVAILABLE:
+            LOGW("Service unavailable");
+            break;
+        case SAMSUNG_AI_NMT_ERROR_PERMISSION_DENIED:
+            if (status == SAMSUNG_AI_NMT_CONNECTION_STATUS_REJECTED)
+                LOGW("NMT rejected");
+
+            break;
+        default:
+            break;
+    }
+}
+
+static void _nmt_translate_result_cb(samsung_ai_nmt_h nmt_h, unsigned int request_id, samsung_ai_nmt_error_e result_code,
+                                     char *translated_text, void *user_data)
+{
+    SECURE_LOGI("request id : %u, result code : %x, translated text : '%s', user data : %p",
+                request_id, result_code, translated_text, user_data);
+
+    switch (result_code)
+    {
+    case SAMSUNG_AI_NMT_ERROR_NONE:
+        LOGI("Success");
+        break;
+    case SAMSUNG_AI_NMT_ERROR_OVER_MAX_INPUT_LENGTH:
+        LOGE("Text is too long");
+        break;
+    case SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED_SOURCE_LANGUAGE:
+        LOGE("Not supported source language");
+        break;
+    case SAMSUNG_AI_NMT_ERROR_NOT_SUPPORTED_TARGET_LANGUAGE:
+        LOGE("Not supported target language");
+        break;
+    default:
+        LOGE("Unknown error : %x", result_code);
+        break;
+    }
+
+    if (!g_selected_text_exist) {
+        ime_delete_surrounding_text((INT_MAX / 2) * -1, INT_MAX);
+    }
+
+    g_selected_text_exist = false;
+
+    if (translated_text) {
+        ime_commit_string(translated_text);
+
+        free(translated_text);
+        translated_text = NULL;
+    }
+}
+
+bool nmt_init()
+{
+    int ret = samsung_ai_nmt_create(&g_nmt_h, _nmt_connection_status_changed_cb, NULL);
+    if (ret != SAMSUNG_AI_NMT_ERROR_NONE) {
+        LOGE("Failed to initialize");
+        return false;
+    }
+
+    ret = samsung_ai_nmt_set_translate_result_cb(g_nmt_h, _nmt_translate_result_cb, NULL);
+    if (ret != SAMSUNG_AI_NMT_ERROR_NONE) {
+        LOGW("Failed to set translate result callback. error : %d", ret);
+        return false;
+    }
+
+    return true;
+}
+
+void nmt_shutdown()
+{
+    int ret = IME_ERROR_NONE;
+    if (g_nmt_h) {
+        ret = samsung_ai_nmt_destroy(g_nmt_h);
+        if (ret != SAMSUNG_AI_NMT_ERROR_NONE) {
+            LOGW("Failed to disconnect. error : %d", ret);
+        }
+
+        g_nmt_h = NULL;
+    }
+}
+
+void nmt_translate(const char *source_language, const char *target_language)
+{
+    int ret = IME_ERROR_NONE;
+    char *text = NULL;
+    unsigned int request_id = 0;
+    int cursor_pos;
+    g_selected_text_exist = false;
+
+    ret = ime_get_selected_text(&text);
+    if (ret == IME_ERROR_NONE && text && strlen(text) > 0) {
+        SECURE_LOGD("selected text : %s", text);
+        g_selected_text_exist = true;
+    }
+    else {
+        if (text) {
+            free(text);
+            text = NULL;
+        }
+
+        ret = ime_get_surrounding_text(-1, -1, &text, &cursor_pos);
+        if (ret == IME_ERROR_NONE) {
+            LOGD("Succeeded to get surrounding text");
+            SECURE_LOGD("surrounding text : '%s'", text);
+        }
+        else
+            LOGW("Failed to get surrounding text");
+    }
+
+    if (ret == IME_ERROR_NONE && text && strlen(text) > 0) {
+        if (samsung_ai_nmt_translate(g_nmt_h, text, source_language, target_language, &request_id) != 0)
+            SECURE_LOGE("Failed to request translate. text(%s), source lang(%s), target lang(%s)", text, source_language, target_language);
+        else
+            SECURE_LOGI("Succeed to request translate. text(%s), source lang(%s), target lang(%s), request id(%u)", text, source_language, target_language, request_id);
+    }
+
+    if (text)
+        free(text);
+
+    text = NULL;
+}