Launch SDL HMIs via xwalk-launcher.
[profile/ivi/smartdevicelink.git] / SDL_Core / src / appMain / appMain.cpp
1 /**
2  * \file appMain.cpp
3  * \brief SmartDeviceLink main application sources
4  * Copyright (c) 2013, Ford Motor Company
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * Redistributions of source code must retain the above copyright notice, this
11  * list of conditions and the following disclaimer.
12  *
13  * Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * Neither the name of the Ford Motor Company nor the names of its contributors
19  * may be used to endorse or promote products derived from this software
20  * without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <sys/stat.h>
36 #include <signal.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <getopt.h>
40 #include <cstdio>
41 #include <cstdlib>
42 #include <vector>
43 #include <string>
44 #include <iostream>  // cpplint: Streams are highly discouraged.
45 #include <fstream>   // cpplint: Streams are highly discouraged.
46
47 // ----------------------------------------------------------------------------
48
49 #include "./appMain.h"
50 #include "./life_cycle.h"
51
52 #include "utils/macro.h"
53 #include "utils/logger.h"
54 #include "utils/signals.h"
55 #include "config_profile/profile.h"
56
57 // ----------------------------------------------------------------------------
58 // Third-Party includes
59 #include "networking.h"  // cpplint: Include the directory when naming .h files
60
61 // ----------------------------------------------------------------------------
62
63 #ifndef SDL_LOG4CXX_PROPERTIES_FILE
64 #define SDL_LOG4CXX_PROPERTIES_FILE "log4cxx.properties"
65 #endif
66
67 #ifndef SDL_HMI_LINK_FILE
68 #define SDL_HMI_LINK_FILE "hmi_link"
69 #endif
70
71 #ifndef SDL_HMI_BROWSER_PATH
72 #define SDL_HMI_BROWSER_PATH "/usr/bin/chromium-browser"
73 #define SDL_HMI_BROWSER_ARG0 "chromium-browser"
74 #define SDL_HMI_BROWSER_ARG1 "--auth-schemes=basic,digest,ntlm"
75 #endif
76
77 namespace {
78
79 const char kBrowser[] = SDL_HMI_BROWSER_PATH;
80 const char kBrowserName[] = SDL_HMI_BROWSER_ARG0;
81 const char kBrowserParams[] = SDL_HMI_BROWSER_ARG1;
82
83 /**
84  * Initialize HTML based HMI.
85  * @return true if success otherwise false.
86  */
87 bool InitHmi() {
88 log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
89                               log4cxx::Logger::getLogger("appMain"));
90
91 pid_t pid_hmi = 0;
92 struct stat sb;
93 if (stat(SDL_HMI_LINK_FILE, &sb) == -1) {
94   LOG4CXX_INFO(logger, "File with HMI link doesn't exist!");
95   return false;
96 }
97
98 std::ifstream file_str;
99 file_str.open(SDL_HMI_LINK_FILE);
100
101 if (!file_str.is_open()) {
102   LOG4CXX_INFO(logger, "File with HMI link was not opened!");
103   return false;
104 }
105
106 file_str.seekg(0, std::ios::end);
107 int length = file_str.tellg();
108 file_str.seekg(0, std::ios::beg);
109
110 char* raw_data = new char[length + 1];
111 if (!raw_data) {
112   LOG4CXX_INFO(logger, "Memory allocation failed.");
113   return false;
114 }
115
116 memset(raw_data, 0, length + 1);
117 file_str.getline(raw_data, length + 1);
118 std::string hmi_link = std::string(raw_data, strlen(raw_data));
119 delete[] raw_data;
120
121 LOG4CXX_INFO(logger,
122              "Input string:" << hmi_link << " length = " << hmi_link.size());
123 file_str.close();
124
125 if (stat(hmi_link.c_str(), &sb) == -1) {
126   LOG4CXX_INFO(logger, "HMI index.html doesn't exist!");
127 }
128 // Create a child process.
129 pid_hmi = fork();
130
131 switch (pid_hmi) {
132   case -1: {  // Error
133     LOG4CXX_INFO(logger, "fork() failed!");
134     return false;
135   }
136   case 0: {  // Child process
137     int fd_dev0 = open("/dev/null", O_RDWR, S_IWRITE);
138     if (0 > fd_dev0) {
139       LOG4CXX_WARN(logger, "Open dev0 failed!");
140       return false;
141     }
142     // close input/output file descriptors.
143     close(STDIN_FILENO);
144     close(STDOUT_FILENO);
145     close(STDERR_FILENO);
146
147     // move input/output to /dev/null.
148     dup2(fd_dev0, STDIN_FILENO);
149     dup2(fd_dev0, STDOUT_FILENO);
150     dup2(fd_dev0, STDERR_FILENO);
151
152     // Execute the program.
153     execlp(kBrowser, kBrowserName, kBrowserParams, hmi_link.c_str(),
154            reinterpret_cast<char*>(0));
155     LOG4CXX_WARN(logger, "execl() failed! Install chromium-browser!");
156
157     return true;
158   }
159   default: { /* Parent process */
160     LOG4CXX_INFO(logger, "Process created with pid " << pid_hmi);
161     return true;
162   }
163 }
164 }
165 }
166
167 /**
168  * \brief Entry point of the program.
169  * \param argc number of argument
170  * \param argv array of arguments
171  * \return EXIT_SUCCESS or EXIT_FAILURE
172  */
173 int main(int argc, char** argv) {
174   // --------------------------------------------------------------------------
175   // Logger initialization
176
177   log4cxx::LoggerPtr logger = log4cxx::LoggerPtr(
178                                 log4cxx::Logger::getLogger("appMain"));
179   log4cxx::PropertyConfigurator::configure(SDL_LOG4CXX_PROPERTIES_FILE);
180
181   LOG4CXX_INFO(logger, " Application started!");
182
183   // Initialize gstreamer. Needed to activate debug from the command line.
184   gst_init(&argc, &argv);
185
186   // --------------------------------------------------------------------------
187   // Components initialization
188
189   profile::Profile::instance()->config_file_name("smartDeviceLink.ini");
190
191   main_namespace::LifeCycle::instance()->StartComponents();
192
193   // --------------------------------------------------------------------------
194   // Third-Party components initialization.
195
196   if (!main_namespace::LifeCycle::instance()->InitMessageBroker()) {
197     exit(EXIT_FAILURE);
198   }
199   LOG4CXX_INFO(logger, "InitMessageBroker successful");
200
201   if (!InitHmi()) {
202     exit(EXIT_FAILURE);
203   }
204   LOG4CXX_INFO(logger, "InitHmi successful");
205   // --------------------------------------------------------------------------
206
207   utils::SubscribeToTerminateSignal(
208     &main_namespace::LifeCycle::StopComponents);
209
210   while (true) {
211     sleep(100500);
212   }
213 }
214