server端在binder中提供的服务会以一个binder_node的结构存储在binder驱动中。
viewrootimpl内部会创建一个空的surface,还未被赋值
public final Surface mSurface = new Surface();
程序执行完requestlayout之后最终会调用到session.addTodisplay,最终执行到wms@addWindow
public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, InputChannel outInputChannel) {
win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
win.attach();
return res;
}
WindowState@attach
void attach() {
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "Attaching " + this + " token=" + mToken
+ ", list=" + mToken.windows);
mSession.windowAddedLocked();
}
Session@windowAddedLocked
void windowAddedLocked() {
if (mSurfaceSession == null) {
mSurfaceSession = new SurfaceSession();
mService.mSessions.add(this);
}
mNumWindow++;
windowAddedLocked中创建了SurfaceSession对象。surfacesession的创建会调用nativeCreate进行jni调用
当decorview创建完成后,解析xml布局。最终就到了requestlayout开始计算布局的宽高位置以及绘制。
private void performTraversals() {
//获取decorview的宽高规格
WindowManager.LayoutParams lp = mWindowAttributes;
//顶层视图decorview所需要的宽高
int desiredWindowWidth;
int desiredWindowHeight;
//此时mFirst = true
if (mFirst) {
mFullRedrawNeeded = true;
mLayoutRequested = true;
//如果窗口类型是有状态栏的,则顶层视图的窗口宽度和高度就是除了状态栏
if (shouldUseDisplaySize(lp)) {
Point size = new Point();
mDisplay.getRealSize(size);
desiredWindowWidth = size.x;
desiredWindowHeight = size.y;
} } else {
//如果没有则decorview的宽高就是整个屏幕的宽高
desiredWindowWidth = mWinFrame.width();
desiredWindowHeight = mWinFrame.height();
}
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
...
// Ask host how big it wants to be
//执行测量操作
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
//执行设置位置操作
performLayout(lp, mWidth, mHeight);
...
//绘制操作
performDraw();
}
这个getWindow就是phonewindow,它是在activity的attach方法中被初始化的。
最终调用phonewindow中的setcontentView方法。 mLayoutInflater.inflate(layoutResID,mContentParent)对布局资源进行加载
当系统调用启动一个activity是就会通过反射启动,然后调用handlelauncheractivity。在handlelauncheracitiviy中执行mInstrumentation.callActivityOnCreate调用activity的oncrreate,并且调用activity.attach函数创建窗口视图phonewindow。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
activity.attach(activityBaseContext, 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.activityConfigCallback,
r.assistToken, r.shareableActivityToken, r.initialCallerInfoAccessToken);
r.activity = activity;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
r.setState(ON_CREATE);
return activity;
}
int main(int argc __unused, char** argv)
{
...
InitializeIcuOrDie();
//获得ProcessState实例对象【见小节2.1】
sp<ProcessState> proc(ProcessState::self());
//获取BpServiceManager对象
sp<IServiceManager> sm = defaultServiceManager();
AudioFlinger::instantiate();
//注册多媒体服务 【见小节3.1】
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
SoundTriggerHwService::instantiate();
RadioService::instantiate();
registerExtensions();
//启动Binder线程池
ProcessState::self()->startThreadPool();
//当前线程加入到线程池
IPCThreadState::self()->joinThreadPool();
}
1.打开驱动ProcessState::self()
2.通过defaultServiceManager获取sm对象。
3.开启线程池不断获取客户端发送的数据
activity加载视图,就相当于是一个容器一样。activitythread中启动activity时调用attach
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
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);
}
final void attach(Context context, ActivityThread aThread,...) {
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setCallback(this);
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindowManager = mWindow.getWindowManager();
}
servicemanager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
//先获取SMP对象,则执行注册服务操作【见小节3.2/3.4】
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
匿名binder是要依托于实名binder而存在的。 当服务端通过实名binder向客户端传输一个匿名binder,客户端端会接收到一个匿名binder的引用然后可以向位于匿名binder进程发送数据。 在内核层匿名binder通过实名binder发送给驱动后,驱动会检查当前的flat_binder_obj是否在当前进程有binder_node。
硬件抽象层统一了硬件调用的接口。
图形缓冲,用于保存图形的一段内存。图形缓冲运行在一个独立的进程.由它负责分配图形缓冲。 是一个独立的进程。gralloc对应的接口类
interface IAllocator {
allocate(BufferDescriptor descriptor, uint32_t count)
generates (Error error,
uint32_t stride,
vec<handle> buffers);
};
其中BufferDescriptor描述了申请的buffer的宽高格式等信息。count表示申请的缓冲区的个数。 IAllocator 的具体实现在pasthrough.cpp