Android Framework combat video -- BootAnimation startup source code analysis (Android 8.1)

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 of init process (supplement bootanimation startup source code analysis of Android Part 10)

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;
}

Keywords: Java C# Windows Android Framework

Added by grumpy on Mon, 04 Oct 2021 23:54:22 +0300