static Result<void>do_class_start(const BuiltinArguments& args){// Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.if(android::base::GetBoolProperty("persist.init.dont_start_class."+ args[1],false))return{};// Starting a class does not start services which are explicitly disabled.// They must be started individually.for(constauto& service :ServiceList::GetInstance()){if(service->classnames().count(args[1])){if(auto result = service->StartIfNotDisabled();!result.ok()){LOG(ERROR)<<"Could not start service '"<< service->name()<<"' as part of class '"<< args[1]<<"': "<< result.error();}}}return{};}
/system/core/init/service.cpp
Result<void>Service::StartIfNotDisabled(){if(!(flags_ & SVC_DISABLED)){returnStart();}else{
flags_ |= SVC_DISABLED_START;}return{};}
Result<void>Service::Start(){...
pid_t pid =-1;if(namespace_flags_){
pid =clone(nullptr,nullptr, namespace_flags_ | SIGCHLD,nullptr);}else{
pid =fork();}if(pid ==0){...if(!ExpandArgsAndExecv(args_, sigstop_)){PLOG(ERROR)<<"cannot execve('"<< args_[0]<<"').See the 'Debugging init' section of init's README.md for tips";}_exit(127);}if(pid <0){
pid_ =0;returnErrnoError()<<"Failed to fork";}...return{};}
service 就是 zygote ExpandArgsAndExecv 传递的参数就是“/system/bin/app_process64”
cc_binary {
name: "app_process",
srcs: ["app_main.cpp"],
multilib: {
lib32: {
version_script: ":art_sigchain_version_script32.txt",
suffix: "32",
},
lib64: {
version_script: ":art_sigchain_version_script64.txt",
suffix: "64",
},
},
ldflags: ["-Wl,--export-dynamic"],
shared_libs: ["libandroid_runtime",
"libbinder",
"libcutils",
"libdl",
"libhidlbase",
"liblog",
"libnativeloader",
"libutils",
// This is a list of libraries that need to be included in order to avoid
// bad apps. This prevents a library from having a mismatch when resolving
// new/delete from an app shared library.
// See b/21032018 formore details.
"libwilhelm",
],
whole_static_libs: ["libsigchain"],
compile_multilib: "both",
cflags: ["-Wall",
"-Werror",
"-Wunused",
"-Wunreachable-code",
],
// If SANITIZE_LITE is revived this will need:
//product_variables: {
// sanitize_lite: {
// // In SANITIZE_LITE mode, we create the sanitized binary in a separate location (but reuse
// // the same module). Using the same module also works around an issue with make: binaries
// // that depend on sanitized libraries will be relinked, even if they set LOCAL_SANITIZE := never.
// //
// // Also pull in the asanwrapper helper.
// relative_install_path: "asan",
// required: ["asanwrapper"],
// },
//},
// Create a symlink from app_process to app_process32 or 64
// depending on the target configuration.
symlink_preferred_arch: true,
}
/frameworks/base/cmds/app_process/app_main.cpp
intmain(int argc,char*const argv[]){......if(zygote){// 启动zygote
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);}elseif(className){
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);}else{fprintf(stderr,"Error: no class name or --zygote supplied.\n");app_usage();LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");}}
属性服务
voidStartPropertyService(int* epoll_socket){InitPropertySet("ro.property_service.version","2");int sockets[2];if(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC,0, sockets)!=0){PLOG(FATAL)<<"Failed to socketpair() between property_service and init";}*epoll_socket = from_init_socket = sockets[0];
init_socket = sockets[1];StartSendingMessages();if(auto result =CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,false,0666,0,0,{});
result.ok()){
property_set_fd =*result;}else{LOG(FATAL)<<"start_property_service socket creation failed: "<< result.error();}// 监听socket 属性服务,最多同时被8个视图使用listen(property_set_fd,8);// 创建属性服务线程auto new_thread = std::thread{PropertyServiceThread};
property_service_thread.swap(new_thread);}staticvoidPropertyServiceThread(){
Epoll epoll;if(auto result = epoll.Open();!result.ok()){LOG(FATAL)<< result.error();}// 监听property_set_fd,当socket有请求的时候调用handle_property_set_fd 来处理if(auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd);!result.ok()){LOG(FATAL)<< result.error();}if(auto result = epoll.RegisterHandler(init_socket, HandleInitSocket);!result.ok()){LOG(FATAL)<< result.error();}while(true){auto pending_functions = epoll.Wait(std::nullopt);if(!pending_functions.ok()){LOG(ERROR)<< pending_functions.error();}else{for(constauto& function :*pending_functions){(*function)();}}}}staticvoidhandle_property_set_fd(){.....switch(cmd){case PROP_MSG_SETPROP:{......break;}case PROP_MSG_SETPROP2:{......// 关键代码uint32_t result =HandlePropertySet(name, value, source_context, cr,&socket,&error);if(result != PROP_SUCCESS){LOG(ERROR)<<"Unable to set property '"<< name <<"' from uid:"<< cr.uid
<<" gid:"<< cr.gid <<" pid:"<< cr.pid <<": "<< error;}
socket.SendUint32(result);break;}}}uint32_tHandlePropertySet(const std::string& name,const std::string& value,const std::string& source_context,const ucred& cr,
SocketConnection* socket, std::string* error){.......// 设置属性returnPropertySet(name, value, error);}staticuint32_tPropertySet(const std::string& name,const std::string& value, std::string* error){
size_t valuelen = value.size();if(!IsLegalPropertyName(name)){*error ="Illegal property name";return PROP_ERROR_INVALID_NAME;}if(auto result =IsLegalPropertyValue(name, value);!result.ok()){*error = result.error().message();return PROP_ERROR_INVALID_VALUE;}// 从属性存储空间查找属性
prop_info* pi =(prop_info*)__system_property_find(name.c_str());if(pi !=nullptr){// ro.* properties are actually "write-once".// ro开头的是只读,只能设置一次if(StartsWith(name,"ro.")){*error ="Read-only property was already set";return PROP_ERROR_READ_ONLY_PROPERTY;}__system_property_update(pi, value.c_str(), valuelen);}else{int rc =__system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);if(rc <0){*error ="__system_property_add failed";return PROP_ERROR_SET_FAILED;}}// Don't write properties to disk until after we have read all default// properties to prevent them from being overwritten by default values.if(persistent_properties_loaded &&StartsWith(name,"persist.")){WritePersistentProperty(name, value);}// If init hasn't started its main loop, then it won't be handling property changed messages// anyway, so there's no need to try to send them.auto lock = std::lock_guard{accept_messages_lock};if(accept_messages){PropertyChanged(name, value);}return PROP_SUCCESS;}