[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