2 * communicate with java skin process
4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
7 * GiWoong Kim <giwoong.kim@samsung.com>
8 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include "maru_common.h"
37 #include "maruskin_client.h"
38 #include "maruskin_server.h"
42 #include "emul_state.h"
43 #include "maruskin_operation.h"
46 #include "maru_err_table.h"
50 MULTI_DEBUG_CHANNEL(qemu, skin_client);
53 #define SKIN_SERVER_READY_TIME 3 // second
54 #define SKIN_SERVER_SLEEP_TIME 10 // milli second
56 #define OPT_SVR_PORT "svr.port"
58 #define OPT_VM_PATH "vm.path"
59 #define OPT_NET_BASE_PORT "net.baseport"
60 #define OPT_MAX_TOUCHPOINT "max.touchpoint"
62 extern char tizen_target_path[];
65 static char** skin_argv;
67 static void* run_skin_client(void* arg)
69 char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
70 char argv[JAVA_MAX_COMMAND_LENGTH] = { 0, };
72 INFO("run skin client\n");
74 for (i = 0; i < skin_argc; ++i) {
75 strncat(argv, skin_argv[i], strlen(skin_argv[i]));
76 strncat(argv, " ", 1);
77 INFO("[skin args %d] %s\n", i, skin_argv[i]);
80 int skin_server_port = get_skin_server_port();
82 //srand( time( NULL ) );
83 int uid = 0; //rand();
84 //INFO( "generated skin uid:%d\n", uid );
86 char* vm_path = tizen_target_path;
87 //INFO( "vm_path:%s\n", vm_path );
88 char buf_skin_server_port[16];
90 char buf_tizen_base_port[16];
91 sprintf(buf_skin_server_port, "%d", skin_server_port);
92 sprintf(buf_uid, "%d", uid);
93 sprintf(buf_tizen_base_port, "%d", tizen_base_port);
96 // find java path in 64bit windows
97 JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
98 memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
100 INFO("This process is running under WOW64.\n");
101 if (!get_java_path(&JAVA_EXEFILE_PATH)) {
102 strcpy(JAVA_EXEFILE_PATH, "java");
105 strcpy(JAVA_EXEFILE_PATH, "java");
108 char* bin_dir = get_bin_path();
109 int bin_len = strlen(bin_dir);
110 char bin_dir_win[bin_len];
111 strcpy(bin_dir_win, bin_dir);
112 bin_dir_win[strlen(bin_dir_win) -1] = '\0';
114 char* bin_dir = get_bin_path();
116 INFO("bin directory : %s\n", bin_dir);
117 int maxtouchpoint = get_emul_max_touch_point();
118 int len_maxtouchpoint;
119 if(maxtouchpoint > 9) {
120 len_maxtouchpoint = 2;
122 len_maxtouchpoint = 1;
125 int len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) +
127 strlen((char*)bin_dir_win) + strlen(bin_dir) + strlen(JAR_SKINFILE) +
129 strlen(bin_dir) + strlen(bin_dir) + strlen(JAR_SKINFILE) +
131 strlen(OPT_SVR_PORT) + strlen(buf_skin_server_port) + strlen(OPT_UID) + strlen(buf_uid) +
132 strlen(OPT_VM_PATH) + strlen(vm_path) + strlen(OPT_NET_BASE_PORT) + strlen(buf_tizen_base_port) +
133 strlen(OPT_MAX_TOUCHPOINT) + len_maxtouchpoint + strlen(argv) + 46;
134 if (len > JAVA_MAX_COMMAND_LENGTH) {
135 INFO("swt command length is too long! (%d)\n", len);
136 len = JAVA_MAX_COMMAND_LENGTH;
139 snprintf(cmd, len, "%s %s %s=\"%s\" \"%s%s\" %s=\"%d\" %s=\"%d\" %s=\"%s\" %s=\"%d\" %s=%d %s",
140 JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH,
142 bin_dir_win, bin_dir, JAR_SKINFILE,
144 bin_dir, bin_dir, JAR_SKINFILE,
146 OPT_SVR_PORT, skin_server_port,
148 OPT_VM_PATH, vm_path,
149 OPT_NET_BASE_PORT, tizen_base_port,
150 OPT_MAX_TOUCHPOINT, maxtouchpoint,
153 INFO("command for swt : %s\n", cmd);
157 free(JAVA_EXEFILE_PATH);
160 //WinExec( cmd, SW_SHOW );
162 STARTUPINFO sti = { 0 };
163 PROCESS_INFORMATION pi = { 0 };
164 if (!CreateProcess(NULL,
169 NORMAL_PRIORITY_CLASS,
175 ERR("Unable to generate process! error %u\n", GetLastError());
176 maru_register_exit_msg(MARU_EXIT_UNKNOWN,
177 "CreateProcess function failed. Unable to generate process.");
181 INFO("wait for single object..\n");
182 DWORD dwRet = WaitForSingleObject(
183 pi.hProcess, // process handle
188 INFO("the child thread state was signaled!\n");
191 INFO("time-out interval elapsed,\
192 and the child thread's state is nonsignaled.\n");
195 ERR("WaitForSingleObject() failed, error %u\n", GetLastError());
199 //retrieves the termination status of the specified process
200 if (GetExitCodeProcess(pi.hProcess, &dwRet) != 0) {
201 ERR("failed to GetExitCodeProcess, error %u\n", GetLastError());
203 INFO("child return value : %d\n", dwRet);
206 /* child process is terminated with some problem.
207 So qemu process will terminate, too. immediately. */
208 shutdown_qemu_gracefully();
211 if (CloseHandle(pi.hProcess) != 0) {
212 INFO("child thread handle was closed successfully!\n");
214 ERR("failed to close child thread handle, error %u\n", GetLastError());
218 #else //ifndef CONFIG_WIN32
219 int ret = system(cmd);
222 INFO("can't execute /bin/sh!\n");
223 } else if(ret == -1) {
224 INFO("fork error!\n");
226 ret = WEXITSTATUS(ret);
227 //The high-order 8 bits are the exit code from exit().
228 //The low-order 8 bits are zero if the process exited normally.
229 INFO("child return value : %d\n", ret);
232 /* child process is terminated with some problem.
233 So qemu process will terminate, too. immediately. */
234 shutdown_qemu_gracefully();
243 int start_skin_client(int argc, char* argv[])
246 int skin_server_ready = 0;
250 if (100 * SKIN_SERVER_READY_TIME < count) {
254 if (is_ready_skin_server()) {
255 skin_server_ready = 1;
259 INFO("sleep for ready. count:%d\n", count);
261 Sleep(SKIN_SERVER_SLEEP_TIME);
263 usleep(1000 * SKIN_SERVER_SLEEP_TIME);
269 if (!skin_server_ready) {
270 ERR("skin_server is not ready.\n");
279 if (0 != pthread_create(&thread_id, NULL, run_skin_client, NULL)) {
280 ERR( "fail to create skin_client pthread.\n" );
287 int start_simple_client(char* msg)
290 char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
292 INFO("run simple client\n");
295 // find java path in 64bit windows
296 JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
297 memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
299 INFO("This process is running under WOW64.\n");
300 if (!get_java_path(&JAVA_EXEFILE_PATH)) {
301 strcpy(JAVA_EXEFILE_PATH, "java");
304 strcpy(JAVA_EXEFILE_PATH, "java");
306 char* bin_dir = get_bin_path();
307 int bin_dir_len = strlen(bin_dir);
308 char bin_dir_win[bin_dir_len];
309 strcpy(bin_dir_win, bin_dir);
310 bin_dir_win[strlen(bin_dir_win) -1] = '\0';
312 char* bin_dir = get_bin_path();
314 INFO("bin directory : %s\n", bin_dir);
317 int len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) + strlen(JAVA_LIBRARY_PATH) +
319 strlen((char*)bin_dir_win) + strlen(bin_dir) + strlen(JAR_SKINFILE) +
321 strlen(bin_dir) + strlen(bin_dir) + strlen(JAR_SKINFILE) +
323 strlen(bin_dir) + strlen(JAVA_SIMPLEMODE_OPTION) + strlen(msg) + 11;
324 if (len > JAVA_MAX_COMMAND_LENGTH) {
325 len = JAVA_MAX_COMMAND_LENGTH;
327 snprintf(cmd, len, "%s %s %s=\"%s\" %s%s %s=\"%s\"",
329 JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, bin_dir_win,
331 JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, bin_dir,
333 bin_dir, JAR_SKINFILE, JAVA_SIMPLEMODE_OPTION, msg);
334 INFO("command for swt : %s\n", cmd);
338 free(JAVA_EXEFILE_PATH);
341 ret = WinExec(cmd, SW_SHOW);
346 INFO("child return value : %d\n", ret);
352 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
353 LPFN_ISWOW64PROCESS fnIsWow64Process;
359 //IsWow64Process is not available on all supported versions of Windows.
360 //Use GetModuleHandle to get a handle to the DLL that contains the function
361 //and GetProcAddress to get a pointer to the function if available.
363 fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
364 GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
366 if(NULL != fnIsWow64Process)
368 if (!fnIsWow64Process(GetCurrentProcess(),&result))
371 INFO("Can not find 'IsWow64Process'\n");
377 int get_java_path(char** java_path)
381 //char strJavaRuntimePath[JAVA_MAX_COMMAND_LENGTH] = {0};
382 char strChoosenName[JAVA_MAX_COMMAND_LENGTH] = {0};
383 char strSubKeyName[JAVA_MAX_COMMAND_LENGTH] = {0};
384 char strJavaHome[JAVA_MAX_COMMAND_LENGTH] = {0};
386 DWORD dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH;
387 DWORD dwBufLen = JAVA_MAX_COMMAND_LENGTH;
389 RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\JavaSoft\\Java Runtime Environment", 0,
390 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | MY_KEY_WOW64_64KEY, &hKey);
391 RegEnumKeyEx(hKey, 0, (LPSTR)strSubKeyName, &dwSubKeyNameMax, NULL, NULL, NULL, NULL);
392 strcpy(strChoosenName, strSubKeyName);
395 while (ERROR_SUCCESS == RegEnumKeyEx(hKey, index, (LPSTR)strSubKeyName, &dwSubKeyNameMax,
396 NULL, NULL, NULL, NULL)) {
397 if (strcmp(strChoosenName, strSubKeyName) < 0) {
398 strcpy(strChoosenName, strSubKeyName);
403 RegOpenKeyEx(hKey, strChoosenName, 0, KEY_QUERY_VALUE | MY_KEY_WOW64_64KEY, &hKeyNew);
404 RegQueryValueEx(hKeyNew, "JavaHome", NULL, NULL, (LPBYTE)strJavaHome, &dwBufLen);
406 if (strJavaHome[0] != '\0') {
407 sprintf(*java_path, "\"%s\\bin\\java\"", strJavaHome);
408 //strcpy(*java_path, strJavaHome);
409 //strcat(*java_path, "\\bin\\java");