[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0001.patch b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0001.patch
new file mode 100644
index 0000000..229752d
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0001.patch
@@ -0,0 +1,523 @@
+diff --git a/Makefile.am b/Makefile.am
+new file mode 100644
+index 0000000..7010370
+--- /dev/null
++++ b/Makefile.am
+@@ -0,0 +1,2 @@
++SUBDIRS = \
++ system/core/init
+diff --git a/configure.ac b/configure.ac
+new file mode 100644
+index 0000000..83b1988
+--- /dev/null
++++ b/configure.ac
+@@ -0,0 +1,8 @@
++AC_INIT([service-launcher], [1.0])
++AM_INIT_AUTOMAKE([foreign])
++AC_PROG_CXX
++AC_CONFIG_FILES([
++ Makefile
++ system/core/init/Makefile
++])
++AC_OUTPUT
+diff --git a/system/core/init/Makefile.am b/system/core/init/Makefile.am
+new file mode 100644
+index 0000000..adf9298
+--- /dev/null
++++ b/system/core/init/Makefile.am
+@@ -0,0 +1,14 @@
++bin_PROGRAMS = service-launcher
++
++service_launcher_CPPFLAGS = \
++ -I$(top_srcdir)/system/core/base/include
++
++service_launcher_CXXFLAGS = -std=c++14
++
++service_launcher_SOURCES = \
++ $(top_srcdir)/system/core/base/stringprintf.cpp \
++ init_parser.cpp \
++ parser.cpp \
++ service.cpp \
++ service-launcher.cpp \
++ util.cpp
+diff --git a/system/core/init/init_parser.cpp b/system/core/init/init_parser.cpp
+index b44ca59..cc50f73 100644
+--- a/system/core/init/init_parser.cpp
++++ b/system/core/init/init_parser.cpp
+@@ -18,7 +18,6 @@
+ #include <errno.h>
+ #include <fcntl.h>
+
+-#include "action.h"
+ #include "init_parser.h"
+ #include "log.h"
+ #include "parser.h"
+@@ -142,7 +141,9 @@ bool Parser::ParseConfig(const std::string& path) {
+ return ParseConfigFile(path);
+ }
+
++#if 0
+ void Parser::DumpState() const {
+ ServiceManager::GetInstance().DumpState();
+ ActionManager::GetInstance().DumpState();
+ }
++#endif
+diff --git a/system/core/init/init_parser.h b/system/core/init/init_parser.h
+index 5ed30ad..7310c35 100644
+--- a/system/core/init/init_parser.h
++++ b/system/core/init/init_parser.h
+@@ -18,6 +18,7 @@
+ #define _INIT_INIT_PARSER_H_
+
+ #include <map>
++#include <memory>
+ #include <string>
+ #include <vector>
+
+diff --git a/system/core/init/log.h b/system/core/init/log.h
+index c5c30af..97776ed 100644
+--- a/system/core/init/log.h
++++ b/system/core/init/log.h
+@@ -17,8 +17,6 @@
+ #ifndef _INIT_LOG_H_
+ #define _INIT_LOG_H_
+
+-#include <cutils/klog.h>
+-
+ #define ERROR(x...) init_klog_write(KLOG_ERROR_LEVEL, x)
+ #define WARNING(x...) init_klog_write(KLOG_WARNING_LEVEL, x)
+ #define NOTICE(x...) init_klog_write(KLOG_NOTICE_LEVEL, x)
+@@ -26,7 +24,6 @@
+ #define DEBUG(x...) init_klog_write(KLOG_DEBUG_LEVEL, x)
+ #define VERBOSE(x...) init_klog_write(KLOG_DEBUG_LEVEL, x)
+
+-void init_klog_write(int level, const char* fmt, ...) __printflike(2, 3);
+-int selinux_klog_callback(int level, const char* fmt, ...) __printflike(2, 3);
++#define init_klog_write(level, x...) printf(x)
+
+ #endif
+diff --git a/system/core/init/service-launcher.cpp b/system/core/init/service-launcher.cpp
+new file mode 100644
+index 0000000..9493384
+--- /dev/null
++++ b/system/core/init/service-launcher.cpp
+@@ -0,0 +1,17 @@
++#include <memory>
++
++#include "init_parser.h"
++#include "service.h"
++
++int main(int argc, char** argv) {
++
++ if (argc != 2) {
++ return 0;
++ }
++
++ Parser& parser = Parser::GetInstance();
++ parser.AddSectionParser("service",std::make_unique<ServiceParser>());
++ parser.ParseConfig(argv[1]);
++
++ return 0;
++}
+diff --git a/system/core/init/service.cpp b/system/core/init/service.cpp
+index f5b8b00..20c2c9a 100644
+--- a/system/core/init/service.cpp
++++ b/system/core/init/service.cpp
+@@ -23,22 +23,16 @@
+ #include <termios.h>
+ #include <unistd.h>
+
+-#include <selinux/selinux.h>
+-
+-#include <android-base/file.h>
+ #include <android-base/stringprintf.h>
+-#include <cutils/android_reboot.h>
+ #include <cutils/sockets.h>
+
+-#include "action.h"
+-#include "init.h"
+ #include "init_parser.h"
+ #include "log.h"
+-#include "property_service.h"
+ #include "util.h"
+
+ using android::base::StringPrintf;
+-using android::base::WriteStringToFile;
++
++#define add_environment(k, v) setenv(k, v, 1)
+
+ #define CRITICAL_CRASH_THRESHOLD 4 // if we crash >4 times ...
+ #define CRITICAL_CRASH_WINDOW (4*60) // ... in 4 minutes, goto recovery
+@@ -63,8 +57,7 @@ Service::Service(const std::string& name, const std::string& classname,
+ const std::vector<std::string>& args)
+ : name_(name), classname_(classname), flags_(0), pid_(0), time_started_(0),
+ time_crashed_(0), nr_crashed_(0), uid_(0), gid_(0), seclabel_(""),
+- ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) {
+- onrestart_.InitSingleTrigger("onrestart");
++ args_(args) {
+ }
+
+ Service::Service(const std::string& name, const std::string& classname,
+@@ -72,10 +65,10 @@ Service::Service(const std::string& name, const std::string& classname,
+ const std::string& seclabel, const std::vector<std::string>& args)
+ : name_(name), classname_(classname), flags_(flags), pid_(0), time_started_(0),
+ time_crashed_(0), nr_crashed_(0), uid_(uid), gid_(gid), supp_gids_(supp_gids),
+- seclabel_(seclabel), ioprio_class_(IoSchedClass_NONE), ioprio_pri_(0), args_(args) {
+- onrestart_.InitSingleTrigger("onrestart");
++ seclabel_(seclabel), args_(args) {
+ }
+
++#if 0
+ void Service::NotifyStateChange(const std::string& new_state) const {
+ if ((flags_ & SVC_EXEC) != 0) {
+ // 'exec' commands don't have properties tracking their state.
+@@ -151,6 +144,7 @@ bool Service::Reap() {
+ NotifyStateChange("restarting");
+ return false;
+ }
++#endif
+
+ void Service::DumpState() const {
+ INFO("service %s\n", name_.c_str());
+@@ -196,6 +190,7 @@ bool Service::HandleGroup(const std::vector<std::string>& args, std::string* err
+ }
+
+ bool Service::HandleIoprio(const std::vector<std::string>& args, std::string* err) {
++#if 0
+ ioprio_pri_ = std::stoul(args[2], 0, 8);
+
+ if (ioprio_pri_ < 0 || ioprio_pri_ > 7) {
+@@ -213,6 +208,7 @@ bool Service::HandleIoprio(const std::vector<std::string>& args, std::string* er
+ *err = "ioprio option usage: ioprio <rt|be|idle> <0-7>";
+ return false;
+ }
++#endif
+
+ return true;
+ }
+@@ -230,8 +226,10 @@ bool Service::HandleOneshot(const std::vector<std::string>& args, std::string* e
+ }
+
+ bool Service::HandleOnrestart(const std::vector<std::string>& args, std::string* err) {
++#if 0
+ std::vector<std::string> str_args(args.begin() + 1, args.end());
+ onrestart_.AddCommand(str_args, "", 0, err);
++#endif
+ return true;
+ }
+
+@@ -329,6 +327,7 @@ bool Service::Start() {
+ return false;
+ }
+
++#if 0
+ bool needs_console = (flags_ & SVC_CONSOLE);
+ if (needs_console) {
+ if (console_.empty()) {
+@@ -343,6 +342,7 @@ bool Service::Start() {
+ return false;
+ }
+ }
++#endif
+
+ struct stat sb;
+ if (stat(args_[0].c_str(), &sb) == -1) {
+@@ -352,6 +352,7 @@ bool Service::Start() {
+ return false;
+ }
+
++#if 0
+ std::string scon;
+ if (!seclabel_.empty()) {
+ scon = seclabel_;
+@@ -393,11 +394,14 @@ bool Service::Start() {
+ return false;
+ }
+ }
++#endif
+
+ NOTICE("Starting service '%s'...\n", name_.c_str());
+
++#if 0
+ pid_t pid = fork();
+ if (pid == 0) {
++#endif
+ umask(077);
+
+ for (const auto& ei : envvars_) {
+@@ -408,8 +412,7 @@ bool Service::Start() {
+ int socket_type = ((si.type == "stream" ? SOCK_STREAM :
+ (si.type == "dgram" ? SOCK_DGRAM :
+ SOCK_SEQPACKET)));
+- const char* socketcon =
+- !si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();
++ const char* socketcon = nullptr;
+
+ int s = create_socket(si.name.c_str(), socket_type, si.perm,
+ si.uid, si.gid, socketcon);
+@@ -418,6 +421,7 @@ bool Service::Start() {
+ }
+ }
+
++#if 0
+ std::string pid_str = StringPrintf("%d", getpid());
+ for (const auto& file : writepid_files_) {
+ if (!WriteStringToFile(pid_str, file)) {
+@@ -468,17 +472,19 @@ bool Service::Start() {
+ _exit(127);
+ }
+ }
++#endif
+
+ std::vector<char*> strs;
+ for (const auto& s : args_) {
+ strs.push_back(const_cast<char*>(s.c_str()));
+ }
+ strs.push_back(nullptr);
+- if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
++ if (execv(args_[0].c_str(), (char**) &strs[0]) < 0) {
+ ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
+ }
+
+ _exit(127);
++#if 0
+ }
+
+ if (pid < 0) {
+@@ -498,9 +504,11 @@ bool Service::Start() {
+ }
+
+ NotifyStateChange("running");
++#endif
+ return true;
+ }
+
++#if 0
+ bool Service::StartIfNotDisabled() {
+ if (!(flags_ & SVC_DISABLED)) {
+ return Start();
+@@ -608,6 +616,7 @@ void Service::OpenConsole() const {
+ dup2(fd, 2);
+ close(fd);
+ }
++#endif
+
+ void Service::PublishSocket(const std::string& name, int fd) const {
+ std::string key = StringPrintf(ANDROID_SOCKET_ENV_PREFIX "%s", name.c_str());
+@@ -618,6 +627,7 @@ void Service::PublishSocket(const std::string& name, int fd) const {
+ fcntl(fd, F_SETFD, 0);
+ }
+
++#if 0
+ int ServiceManager::exec_count_ = 0;
+
+ ServiceManager::ServiceManager() {
+@@ -817,6 +827,7 @@ void ServiceManager::ReapAnyOutstandingChildren() {
+ while (ReapOneProcess()) {
+ }
+ }
++#endif
+
+ bool ServiceParser::ParseSection(const std::vector<std::string>& args,
+ std::string* err) {
+@@ -844,7 +855,7 @@ bool ServiceParser::ParseLineSection(const std::vector<std::string>& args,
+
+ void ServiceParser::EndSection() {
+ if (service_) {
+- ServiceManager::GetInstance().AddService(std::move(service_));
++ service_->Start();
+ }
+ }
+
+diff --git a/system/core/init/service.h b/system/core/init/service.h
+index d6ce664..1e36d3f 100644
+--- a/system/core/init/service.h
++++ b/system/core/init/service.h
+@@ -19,13 +19,11 @@
+
+ #include <sys/types.h>
+
+-#include <cutils/iosched_policy.h>
+-
++#include <limits>
+ #include <memory>
+ #include <string>
+ #include <vector>
+
+-#include "action.h"
+ #include "init_parser.h"
+ #include "keyword_map.h"
+
+@@ -145,17 +143,12 @@ private:
+ std::vector<SocketInfo> sockets_;
+ std::vector<ServiceEnvironmentInfo> envvars_;
+
+- Action onrestart_; // Commands to execute on restart.
+-
+ std::vector<std::string> writepid_files_;
+
+ // keycodes for triggering this service via /dev/keychord
+ std::vector<int> keycodes_;
+ int keychord_id_;
+
+- IoSchedClass ioprio_class_;
+- int ioprio_pri_;
+-
+ std::vector<std::string> args_;
+ };
+
+diff --git a/system/core/init/util.cpp b/system/core/init/util.cpp
+index 750e040..85e647f 100644
+--- a/system/core/init/util.cpp
++++ b/system/core/init/util.cpp
+@@ -21,28 +21,22 @@
+ #include <fcntl.h>
+ #include <ctype.h>
+ #include <errno.h>
++#include <limits.h>
+ #include <time.h>
+ #include <ftw.h>
+ #include <pwd.h>
+-
+-#include <selinux/label.h>
+-#include <selinux/android.h>
++#include <unistd.h>
+
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
+
+-#include <android-base/file.h>
+-#include <android-base/strings.h>
+-
+ /* for ANDROID_SOCKET_* */
+ #include <cutils/sockets.h>
+ #include <android-base/stringprintf.h>
+
+-#include "init.h"
+ #include "log.h"
+-#include "property_service.h"
+ #include "util.h"
+
+ static unsigned int do_decode_uid(const char *s)
+@@ -90,6 +84,7 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid,
+ {
+ struct sockaddr_un addr;
+ int fd, ret, savederrno;
++#if 0
+ char *filecon;
+
+ if (socketcon) {
+@@ -98,6 +93,7 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid,
+ return -1;
+ }
+ }
++#endif
+
+ fd = socket(PF_UNIX, type, 0);
+ if (fd < 0) {
+@@ -105,8 +101,10 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid,
+ return -1;
+ }
+
++#if 0
+ if (socketcon)
+ setsockcreatecon(NULL);
++#endif
+
+ memset(&addr, 0 , sizeof(addr));
+ addr.sun_family = AF_UNIX;
+@@ -119,18 +117,22 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid,
+ goto out_close;
+ }
+
++#if 0
+ filecon = NULL;
+ if (sehandle) {
+ ret = selabel_lookup(sehandle, &filecon, addr.sun_path, S_IFSOCK);
+ if (ret == 0)
+ setfscreatecon(filecon);
+ }
++#endif
+
+ ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr));
+ savederrno = errno;
+
++#if 0
+ setfscreatecon(NULL);
+ freecon(filecon);
++#endif
+
+ if (ret) {
+ ERROR("Failed to bind socket '%s': %s\n", name, strerror(savederrno));
+@@ -142,11 +144,13 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid,
+ ERROR("Failed to lchown socket '%s': %s\n", addr.sun_path, strerror(errno));
+ goto out_unlink;
+ }
++#if 0
+ ret = fchmodat(AT_FDCWD, addr.sun_path, perm, AT_SYMLINK_NOFOLLOW);
+ if (ret) {
+ ERROR("Failed to fchmodat socket '%s': %s\n", addr.sun_path, strerror(errno));
+ goto out_unlink;
+ }
++#endif
+
+ INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n",
+ addr.sun_path, perm, uid, gid);
+@@ -180,11 +184,17 @@ bool read_file(const char* path, std::string* content) {
+ return false;
+ }
+
+- bool okay = android::base::ReadFdToString(fd, content);
++ char buf[BUFSIZ];
++ ssize_t n;
++ while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
++ content->append(buf, n);
++ }
++ bool okay = n == 0;
+ close(fd);
+ return okay;
+ }
+
++#if 0
+ int write_file(const char* path, const char* content) {
+ int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0600));
+ if (fd == -1) {
+@@ -276,6 +286,7 @@ time_t gettime() {
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return now.tv_sec;
+ }
++#endif
+
+ uint64_t gettime_ns() {
+ timespec now;
+@@ -283,6 +294,7 @@ uint64_t gettime_ns() {
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
+ }
+
++#if 0
+ int mkdir_recursive(const char *pathname, mode_t mode)
+ {
+ char buf[128];
+@@ -465,6 +477,7 @@ std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) {
+ android::base::StringAppendF(&hex, "%02x", bytes[i]);
+ return hex;
+ }
++#endif
+
+ /*
+ * Returns true is pathname is a directory
+@@ -477,6 +490,7 @@ bool is_dir(const char* pathname) {
+ return S_ISDIR(info.st_mode);
+ }
+
++#if 0
+ bool expand_props(const std::string& src, std::string* dst) {
+ const char* src_ptr = src.c_str();
+
+@@ -546,3 +560,4 @@ bool expand_props(const std::string& src, std::string* dst) {
+
+ return true;
+ }
++#endif
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0002.patch b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0002.patch
new file mode 100644
index 0000000..8562290
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0002.patch
@@ -0,0 +1,48 @@
+diff --git a/system/core/init/service.cpp b/system/core/init/service.cpp
+index 20c2c9a..ac4070c 100644
+--- a/system/core/init/service.cpp
++++ b/system/core/init/service.cpp
+@@ -280,20 +280,20 @@ private:
+ Service::OptionHandlerMap::Map& Service::OptionHandlerMap::map() const {
+ constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
+ static const Map option_handlers = {
+- {"class", {1, 1, &Service::HandleClass}},
+- {"console", {0, 1, &Service::HandleConsole}},
+- {"critical", {0, 0, &Service::HandleCritical}},
+- {"disabled", {0, 0, &Service::HandleDisabled}},
+- {"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup}},
+- {"ioprio", {2, 2, &Service::HandleIoprio}},
+- {"keycodes", {1, kMax, &Service::HandleKeycodes}},
+- {"oneshot", {0, 0, &Service::HandleOneshot}},
+- {"onrestart", {1, kMax, &Service::HandleOnrestart}},
+- {"seclabel", {1, 1, &Service::HandleSeclabel}},
+- {"setenv", {2, 2, &Service::HandleSetenv}},
+- {"socket", {3, 6, &Service::HandleSocket}},
+- {"user", {1, 1, &Service::HandleUser}},
+- {"writepid", {1, kMax, &Service::HandleWritepid}},
++ {"class", std::make_tuple(1, 1, &Service::HandleClass)},
++ {"console", std::make_tuple(0, 1, &Service::HandleConsole)},
++ {"critical", std::make_tuple(0, 0, &Service::HandleCritical)},
++ {"disabled", std::make_tuple(0, 0, &Service::HandleDisabled)},
++ {"group", std::make_tuple(1, NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup)},
++ {"ioprio", std::make_tuple(2, 2, &Service::HandleIoprio)},
++ {"keycodes", std::make_tuple(1, kMax, &Service::HandleKeycodes)},
++ {"oneshot", std::make_tuple(0, 0, &Service::HandleOneshot)},
++ {"onrestart", std::make_tuple(1, kMax, &Service::HandleOnrestart)},
++ {"seclabel", std::make_tuple(1, 1, &Service::HandleSeclabel)},
++ {"setenv", std::make_tuple(2, 2, &Service::HandleSetenv)},
++ {"socket", std::make_tuple(3, 6, &Service::HandleSocket)},
++ {"user", std::make_tuple(1, 1, &Service::HandleUser)},
++ {"writepid", std::make_tuple(1, kMax, &Service::HandleWritepid)},
+ };
+ return option_handlers;
+ }
+@@ -407,7 +407,7 @@ bool Service::Start() {
+ for (const auto& ei : envvars_) {
+ add_environment(ei.name.c_str(), ei.value.c_str());
+ }
+-
++ mkdir("/dev/socket", 0755);
+ for (const auto& si : sockets_) {
+ int socket_type = ((si.type == "stream" ? SOCK_STREAM :
+ (si.type == "dgram" ? SOCK_DGRAM :
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0003.patch b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0003.patch
new file mode 100644
index 0000000..33d30be
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/0003.patch
@@ -0,0 +1,25 @@
+diff --git a/system/core/init/service-launcher.cpp b/system/core/init/service-launcher.cpp
+index 9493384..c0ce7f2 100644
+--- a/system/core/init/service-launcher.cpp
++++ b/system/core/init/service-launcher.cpp
+@@ -1,4 +1,6 @@
+ #include <memory>
++#include <string.h>
++#include <stdlib.h>
+
+ #include "init_parser.h"
+ #include "service.h"
+@@ -12,6 +14,12 @@ int main(int argc, char** argv) {
+ Parser& parser = Parser::GetInstance();
+ parser.AddSectionParser("service",std::make_unique<ServiceParser>());
+ parser.ParseConfig(argv[1]);
+-
++
++ char serv_name[20] = {0};
++ strncpy(serv_name, argv[1] + strlen("init."), strlen(argv[1]) - strlen("init.") - strlen(".rc"));
++
++ char cmd[40] = "sncfg prop_set ctl.stop ";
++ strcat(cmd, serv_name);
++ system(cmd);
+ return 0;
+ }
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/add_log_for_service_launcher.patch b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/add_log_for_service_launcher.patch
new file mode 100644
index 0000000..24ed527
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/add_log_for_service_launcher.patch
@@ -0,0 +1,37 @@
+diff --git a/system/core/init/service-launcher.cpp b/system/core/init/service-launcher.cpp
+index c0ce7f2..2445b0a 100644
+--- a/system/core/init/service-launcher.cpp
++++ b/system/core/init/service-launcher.cpp
+@@ -14,10 +14,12 @@ int main(int argc, char** argv) {
+ Parser& parser = Parser::GetInstance();
+ parser.AddSectionParser("service",std::make_unique<ServiceParser>());
+ parser.ParseConfig(argv[1]);
+-
++
+ char serv_name[20] = {0};
+ strncpy(serv_name, argv[1] + strlen("init."), strlen(argv[1]) - strlen("init.") - strlen(".rc"));
+-
++
++ fprintf(stderr, "service_launcher serv_name[%s]\n", serv_name);
++
+ char cmd[40] = "sncfg prop_set ctl.stop ";
+ strcat(cmd, serv_name);
+ system(cmd);
+diff --git a/system/core/init/service.cpp b/system/core/init/service.cpp
+index ac4070c..e13b4fb 100644
+--- a/system/core/init/service.cpp
++++ b/system/core/init/service.cpp
+@@ -479,10 +479,12 @@ bool Service::Start() {
+ strs.push_back(const_cast<char*>(s.c_str()));
+ }
+ strs.push_back(nullptr);
++ fprintf(stderr, "service_launcher start execve('%s')\n", args_[0].c_str());
+ if (execv(args_[0].c_str(), (char**) &strs[0]) < 0) {
+ ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
++ fprintf(stderr, "service_launcher cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
+ }
+-
++ fprintf(stderr, "service_launcher start sucess\n");
+ _exit(127);
+ #if 0
+ }
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/mark-rc-name-limitation.patch b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/mark-rc-name-limitation.patch
new file mode 100644
index 0000000..8f4fb01
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/mark-rc-name-limitation.patch
@@ -0,0 +1,24 @@
+diff --git a/system/core/init/service.cpp b/system/core/init/service.cpp
+index ac4070c..a040632 100644
+--- a/system/core/init/service.cpp
++++ b/system/core/init/service.cpp
+@@ -860,13 +860,16 @@ void ServiceParser::EndSection() {
+ }
+
+ bool ServiceParser::IsValidName(const std::string& name) const {
+- if (name.size() > 16) {
++ if (name.size() > 92) {
+ return false;
+ }
+- for (const auto& c : name) {
++
++ /*
++ for (const auto& c : name) {
+ if (!isalnum(c) && (c != '_') && (c != '-')) {
+ return false;
+ }
+- }
++ }
++ */
+ return true;
+ }
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/service_launcher.patch b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/service_launcher.patch
new file mode 100644
index 0000000..5a317a4
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/files/service_launcher.patch
@@ -0,0 +1,12 @@
+diff --git a/system/core/init/service.h b/system/core/init/service.h
+index 1e36d3f..4fdf3ea 100644
+--- a/system/core/init/service.h
++++ b/system/core/init/service.h
+@@ -23,6 +23,7 @@
+ #include <memory>
+ #include <string>
+ #include <vector>
++#include <functional>
+
+ #include "init_parser.h"
+ #include "keyword_map.h"
diff --git a/meta/meta-mediatek-ivt/recipes-platform/service-launcher/service-launcher.bb b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/service-launcher.bb
new file mode 100644
index 0000000..4dcff80
--- /dev/null
+++ b/meta/meta-mediatek-ivt/recipes-platform/service-launcher/service-launcher.bb
@@ -0,0 +1,23 @@
+DESCRIPTION = "Android service launcher"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = " \
+ file://system/core/NOTICE;md5=c1a3ff0b97f199c7ebcfdd4d3fed238e \
+ "
+
+SRC_URI = " \
+ git://android.googlesource.com/platform/system/core;protocol=https;name=platform/system/core;destsuffix=platform/system/core/ \
+ file://0001.patch \
+ file://0002.patch \
+ file://0003.patch \
+ file://mark-rc-name-limitation.patch \
+ file://add_log_for_service_launcher.patch \
+ file://service_launcher.patch \
+ "
+
+SRCREV_platform/system/core = "c6160d2a0ef648ccb3d217c589c60b5c00b80387"
+
+S = "${WORKDIR}/platform"
+
+DEPENDS = "platform-libs"
+
+inherit autotools