Course Q & A and new course information: QQ communication group: 422901085 for course discussion
Video link of FrameWork introductory course: https://edu.csdn.net/course/detail/30298
Video link of FrameWork practical lesson 1: https://edu.csdn.net/course/detail/30275
FrameWork cross process communication video link: https://edu.csdn.net/course/detail/35911
Special blog series:
Android 8.1 zygote startup process source code
Android Framework combat video – the fork process of Zygote
Android Framework combat Video - SystemServer launch
Android Framework combat video – SystemServer launches FallbackHome
Android Framework combat video – FallbackHome process startup and Activity startup
Android Framework combat video – FallbackHome ends launch Launcher
Android Framework combat Video - BootAnimation startup source code analysis (Android 8.1)
Android Framework combat Video - BootAnimation startup source code analysis
Tip: the code is based on Android 8.1
Code path introduction:
bootanimation frameworks/base/cmds/bootanimation/
surfaceflinger frameworks/native/services/surfaceflinger/
init system/core/init/
Detailed analysis of startup process:
When the kernel is up, it will start the first process, the init process.
The init process starts the surface linker process according to the init.rc configuration.
service surfaceflinger /system/bin/surfaceflinger class main user system group graphics drmrpc onrestart restart zygote
The surface linker process starts, and then runs the main() function of the process.
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int argc, char** argv) { .... // instantiate surfaceflinger sp<SurfaceFlinger> flinger = new SurfaceFlinger();//Create a surfacelinker service instance .... flinger->init(); // publish surface flinger sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//Register in the service manager // run in this thread flinger->run();//Run return 0; }
First, create a new SurfaceFlinger instance, then init, and then run
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// Do not call property_set on main thread which will be blocked by init
// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
// Inform native graphics APIs whether the present timestamp is supported: if (getHwComposer().hasCapability( HWC2::Capability::PresentFenceIsNotReliable)) { mStartPropertySetThread = new StartPropertySetThread(false); } else { mStartPropertySetThread = new StartPropertySetThread(true); } if (mStartPropertySetThread->Start() != NO_ERROR) { //Actually start the thread that sets the bootimation property ALOGE("Run StartPropertySetThread failed!"); } ALOGV("Done initializing");
}
After initializing graphics, mStartPropertySetThread() plays the boot animation// Note that it is no longer the previous startBootAnim method
StartPropertySetThread is defined as follows:
StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}
status_t StartPropertySetThread::Start() {
return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);
}
bool StartPropertySetThread::threadLoop() {
// Set property service.sf.present_timestamp, consumer need check its readiness
property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
// Clear BootAnimation exit flag
property_set(“service.bootanim.exit”, “0”);// Key attributes
// Start BootAnimation if not started
property_set(“ctl.start”, “bootanim”);// Key attributes
// Exit immediately
return false;
}
So the bootanim process starts? Why set a property to start? Now let's look at / system/core/init/init.cpp in the main function of init.cpp of the init process:
int main(int argc, char** argv) {
...
property_load_boot_defaults(); export_oem_lock_status(); start_property_service(); //start_property_service set_usb_controller();
}
Let's take a look at start_property_service method in / system/core/init/property_service.cpp:
Start in main function_ property_ Service (), register a mechanism register of epoll handle in this function_ epoll_ handler():
666 void start_property_service() { 667 property_set("ro.property_service.version", "2"); 668 669 property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 670 0666, 0, 0, NULL); 671 if (property_set_fd == -1) { 672 PLOG(ERROR) << "start_property_service socket creation failed"; 673 exit(1); 674 } 675 676 listen(property_set_fd, 8); 677 678 register_epoll_handler(property_set_fd, handle_property_set_fd); 679 }
The init process will use the epoll mechanism to poll for events, one of which is that the system attribute value is modified. When the event is obtained, handle is executed_ property_ set_ FD (), the code is as follows: through handle_property_set_fd():
static void handle_property_set_fd() {
...
switch (cmd) {
409 case PROP_MSG_SETPROP: {
410 char prop_name[PROP_NAME_MAX];
411 char prop_value[PROP_VALUE_MAX];
412
413 if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
414 !socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {
415 PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket";
416 return;
417 }
418
419 prop_name[PROP_NAME_MAX-1] = 0;
420 prop_value[PROP_VALUE_MAX-1] = 0;
421
422 handle_property_set(socket, prop_value, prop_value, true);
423 break;
424 }
This function executes handle_property_set()
static void handle_property_set(SocketConnection& socket,
const std::string& name,
const std::string& value,
bool legacy_protocol) {
. . . . . .
handle_control_message(name.c_str() + 4, value.c_str());
. . . . . .
}
This function performs further handle_control_message(),stay/system/core/init/init.cpp,Parameters passed in msg.name=ctl.start,msg.value=bootanim 179 void handle_control_message(const std::string& msg, const std::string& name) { 180 Service* svc = ServiceManager::GetInstance().FindServiceByName(name); 181 if (svc == nullptr) { 182 LOG(ERROR) << "no such service '" << name << "'"; 183 return; 184 } 185 186 if (msg == "start") { 187 svc->Start(); 188 } else if (msg == "stop") { 189 svc->Stop(); 190 } else if (msg == "restart") { 191 svc->Restart(); 192 } else { 193 LOG(ERROR) << "unknown control msg '" << msg << "'"; 194 } 195 } This function is called first FindServiceByName,from service_list Query whether the service to be started exists. If so, return the relevant information of the service. because init.rc There are bootanimation Therefore, in init Process execution parse_config()The service is added to the service_list Medium, so bootanimation Applications exist. Then, if the service is found, call service_start Start the service.
Set the service.bootanim.exit property to 0. This property will be checked periodically in the bootanimation process. When = 1, the animation will exit. Here = 0 indicates that the animation is to be played.
Then start the bootanimation process through the ctl.start command, and the animation will begin to play.
Now come to the implementation of bootanimation
frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create the boot animation object sp<BootAnimation> boot = new BootAnimation();//Create a BootAnimation instance IPCThreadState::self()->joinThreadPool();//binder thread pool, used for communication with surface linker. } return 0; }