[Android car series] Chapter 4 Activity start to render to SurfaceFlinger process

1 Activity creation

  ActivityThread is the entry point of the App for the App process. In addition, ActivityThread also implements interfaces such as creating the main thread Looper, dumping application memory usage, and obtaining application package names. Let's look at the role of ActivityThread for the four major components. In one sentence, ActivityThread manages the calls of the life cycle methods of the four major components.
  The AMS service process sends a signal to trigger the app ActivityThread通过反射实例化Activity并启动Activity, and then calls attach()the method of the activity.

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    
    //...
   ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
    
    
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 通过反射创建Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
    
    
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
    
    
            if (!mInstrumentation.onException(activity, e)) {
    
    
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }


    //调用activity的attach方法
   activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);

    //...
}

  Then the life cycle of Activity begins. onCreate()-onStart()-onResume(),onResume()The page is not visible when the execution is executed, and the page is only visible after onResume()the first signal after the execution is complete . VSYNConResume()will be DecorViewadded to WindowManagerGlobalthe .

 @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
    
    
        // ...
        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (r.window == null && !a.mFinished && willBeVisible) {
    
    
            // 获取到PhoneWindow和DecorView
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
    
    
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
    
    
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
    
    
                if (!a.mWindowAdded) {
    
    
                    a.mWindowAdded = true;
                    // wm是WindowManagerImpl,
                    // 将DecorView add到App的单例WindowManagerGlobal中
                    wm.addView(decor, l);
                } else {
    
    
                    // The activity will get a callback for this {@link LayoutParams} change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                }
            }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
        } else if (!willBeVisible) {
    
    
            if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }
    }

2 Activity rendering

attach()An object is initialized in the method   of Activity PhoneWindow(an Activity corresponds to a PhoneWindow object).
  In the Android system AMS服务通过Binder与ActivityThread进行通讯, ActivityThread manages the pages of all activities in the App.每个Activity中有一个对应的PhoneWindow,每个PhoneWindow有对应的DecorView,DecorView是布局内layout的容器
insert image description here

3 WindowManagerGlobal

  Each App has only one WindowManagerGlobalobject, the singleton object of the App layer. ActivityThread通过WindowManagerImpl与WindowManagerGlobal实现通讯,WindowManagerGlobal用于缓存所有页面的PhoneWindow、DecorView、ViewRootImpl等界面相关的数据.
  WindowManagerGlobal internally has all methods of adding addView(), removeView()deleting, checking, etc., which are logically processed in the form of traversal, and provide external services.
  It mainly provides WMS with the convenience of managing all Views. Since WMS and WMS are in the SystemServer process, and App belongs to a different process, all use Binder inter-process communication.insert image description here

4 WindowManagerService

  WindowManagerService The window management service is referred to as WMS, and there is only one WMS for a device. WMS管理所有App的全部PhoneWindow.
  WindowManagerGlobal uses Session to communicate with SurfaceFlinger through WMS across processes. According to each different application, a Surface is created for the rendering of the application.
insert image description here

5 Establish Surface and SurfaceFlinger connections

The SurfaceFlinger service mainly implements two Binder services for App connection:
1) SurfaceFlinger
  is derived from BnSurfaceComposer, which is the main service of the SurfaceFlinger program. It is constructed and added to the servicemanager when the program starts. The relevant code is in main_surfaceflinger.cpp, and the service name is "SurfaceFlinger"
2) Client
  is derived from BnSurfaceComposerClient, which is created when SurfaceFlinger::createConnection, corresponding to an App Client connection

Then after the App starts, you need to establish a session with SurfaceFlinger through the following operations:
1) servicemanagerObtain the service SurfaceFlinger BpBinder, and then convert it into BpSurfaceComposer
2) call to BpsurfaceComposer.createConnectionestablish a connection, and then BpBinderconvert the returned one intoBpSurfaceComposeClient

Android then provides two classes to simplify the operation on the App side, mainly including:
1) ComposerService
  single-column class, which mainly encapsulates the connection with SurfaceFlinger, calls the connectlocked member function to connect "SurfaceFlinger" during construction,
and then saves BpSurfaceCompose to the member variable mComposerService
2 )SurfaceComposerClient
  encapsulates the operation of establishing a session connection with SurfaceFlinger, onFirstRefcalls to createConnectionestablish
a session and saves BpSurfaceComposerClient to the member variable mClient
3) Composer
  single-column class, which mainly encapsulates operations related to Layer data configuration

Next, analyze based on the code. After the package is completed, the initial connection of the App is very simple.

sp<SurfaceComposerClient> session= new SurfaceComposerClient();

Just one line of code, then look at the constructor

SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT), mComposer(Composer::getInstance()){
}

Get the Composer singleton object and save it to mComposer, since SurfaceComposerClient is derived from RefBase

class SurfaceComposerClient : public RefBase

So when it is constructed, it will be called to incStrongincrease the strong reference count for the first time, and onFirstRefit will be called at the same time

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

This function completes the final operation of the connection, first by ComposerService::getComposerService()generating
ComposeServicea single column, and calling its connectLockedconnection SurfaceFlinger to return to BpSurfaceComposer, and then calling to sm->createConnection()create a session and save it to mClient. Next, look at the code of SurfaceFlinger.createConnection

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}

Very simple, is to create a Client local object and return

At this point, the initial connection between App and SurfaceFlinger has ended, and the next step is to create a drawing surface based on the session object

6 Flowchart

insert image description here

Guess you like

Origin blog.csdn.net/u010687761/article/details/129781635