当前位置: 首页 > news >正文

【安卓源码】SurfaceFlinger 启动及其与应用通信

1. surfaceFlinger 初始化和消息队列处理机制

surfaceflinger 的makefile 文件

/frameworks/native/services/surfaceflinger/Android.bp

235 cc_binary {
236     name: "surfaceflinger",
237     defaults: ["libsurfaceflinger_binary"],
238     init_rc: ["surfaceflinger.rc"],
239     srcs: [
240         ":surfaceflinger_binary_sources",
241         // Note: SurfaceFlingerFactory is not in the filegroup so that it
242         // can be easily replaced.
243         "SurfaceFlingerFactory.cpp",
244     ],
245     shared_libs: [
246         "libSurfaceFlingerProp",
247     ],
248 
249      logtags: ["EventLog/EventLogTags.logtags"],
250 }
251 

init进程就可以解析 "surfaceflinger.rc" ,启动 SurfaceFlinger 服务进程,执行 main 方法,启动surfaceflinger 进程:

 /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

#include "SurfaceFlingerFactory.h"int main(int, char**) {// 管道破裂的信号signal(SIGPIPE, SIG_IGN);hardware::configureRpcThreadpool(1 /* maxThreads */,false /* callerWillJoin */);startGraphicsAllocatorService();// 限制 binder 的线程为 4 个ProcessState::self()->setThreadPoolMaxThreadCount(4);if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {ALOGW("Couldn't set uclamp.min: %s\n", strerror(errno));}。。。// start the thread poolsp<ProcessState> ps(ProcessState::self());
// 开启线程池ps->startThreadPool();// Reset current thread's policy and priorityif (errorInPriorityModification == 0) {errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);} else {ALOGE("Failed to set SurfaceFlinger binder threadpool priority to SCHED_FIFO");}// 1. 创建 surfaceflinger 对象sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();// Set the minimum policy of surfaceflinger node to be SCHED_FIFO.// So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run// at least with SCHED_FIFO policy and priority 1.if (errorInPriorityModification == 0) {flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);}setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);set_sched_policy(0, SP_FOREGROUND);// Put most SurfaceFlinger threads in the system-background cpuset// Keeps us from unnecessarily using big cores// Do this after the binder thread pool initif (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);// 2. 初始化 surfaceflinger flinger->init();// 通过 ServiceManager 增加 "surfaceflinger"服务到 manager中,通过getService可以获取到biander服务sp<IServiceManager> sm(defaultServiceManager());sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);startDisplayService(); // dependency on SF getting registered aboveif (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));}//3. 调用 surfaceflinger 的run 方法,开启消息队列机制flinger->run();return 0;
}

基本操作如下: 

  1. 创建SurfaceFlinger对象,触发执行 SurfaceFlinger::onFirstRef()
  2. 调用SurfaceFlinger::init()进行初始化
  3. 注册服务到ServiceManager(名字是"SurfaceFlinger")
  4. 调用SurfaceFlinger::run()

1). 创建 surfaceflinger 对象

surfaceflinger::createSurfaceFlinger()

调用的是 SurfaceFlingerFactory 头文件

#include "SurfaceFlingerFactory.h"

/frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

namespace android::surfaceflinger {sp<SurfaceFlinger> createSurfaceFlinger() {static DefaultFactory factory;// 创建了 SurfaceFlinger 对象,传入的对象是 DefaultFactoryreturn new SurfaceFlinger(factory);
}

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp


SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
// factory 为 DefaultFactory,将其赋值给 mFactory: mFactory(factory),mInterceptor(mFactory.createSurfaceInterceptor()),mTimeStats(std::make_shared<impl::TimeStats>()),mFrameTracer(mFactory.createFrameTracer()),mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, getpid())),// 创建了消息队列 mFactory.createMessageQueuemEventQueue(mFactory.createMessageQueue()),// 创建了 CompositionEngine 对象mCompositionEngine(mFactory.createCompositionEngine()),mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),mPowerAdvisor(*this) {ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); });
}SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {ALOGI("SurfaceFlinger is starting");hasSyncFramework = running_without_sync_framework(true);dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);

创建了消息队列 mFactory.createMessageQueue

/frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.h

DefaultFactory 头文件 

class DefaultFactory : public surfaceflinger::Factory {
public:virtual ~DefaultFactory();std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override;std::unique_ptr<MessageQueue> createMessageQueue() override;

/frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

namespace android::surfaceflinger {DefaultFactory::~DefaultFactory() = default;std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) {return std::make_unique<android::impl::HWComposer>(serviceName);
}// 创建独占智能指针 MessageQueue
std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() {return std::make_unique<android::impl::MessageQueue>();
}

创建独占智能指针 MessageQueue

代码路径为如下:

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp

2). 初始化 surfaceflinger 

flinger->init()

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {// 会打印下列的logALOGI(  "SurfaceFlinger's main thread ready to run. ""Initializing graphics H/W...");Mutex::Autolock _l(mStateLock);// Get a RenderEngine for the given display / config (can't fail)// TODO(b/77156734): We need to stop casting and use HAL types when possible.// Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.// CompositionEngine 去设置渲染引擎 RenderEngine::createmCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(renderengine::RenderEngineCreationArgs::Builder().setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat)).setImageCacheSize(maxFrameBufferAcquiredBuffers).setUseColorManagerment(useColorManagement).setEnableProtectedContext(enable_protected_contents(false)).setPrecacheToneMapperShaderOnly(false).setSupportsBackgroundBlur(mSupportsBlur).setContextPriority(useContextPriority? renderengine::RenderEngine::ContextPriority::REALTIME: renderengine::RenderEngine::ContextPriority::MEDIUM).build()));// Set SF main policy after initializing RenderEngine which has its own policy.if (!SetTaskProfiles(0, {"SFMainPolicy"})) {ALOGW("Failed to set main task profile");}mCompositionEngine->setTimeStats(mTimeStats);// 设置 HwComposermCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));// HwComposer 设置回调为 surfaceFlingermCompositionEngine->getHwComposer().setCallback(this);ClientCache::getInstance().setRenderEngine(&getRenderEngine());if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {enableHalVirtualDisplays(true);}// Process any initial hotplug and resulting display changes.processDisplayHotplugEventsLocked();const auto display = getDefaultDisplayDeviceLocked();LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");const auto displayId = display->getPhysicalId();LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),"Internal display is disconnected.");// initialize our drawing statemDrawingState = mCurrentState;// set initial conditions (e.g. unblank default device)initializeDisplays();mPowerAdvisor.init();char primeShaderCache[PROPERTY_VALUE_MAX];property_get("service.sf.prime_shader_cache", primeShaderCache, "1");if (atoi(primeShaderCache)) {if (setSchedFifo(false) != NO_ERROR) {ALOGW("Can't set SCHED_OTHER for primeCache");}mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache();if (setSchedFifo(true) != NO_ERROR) {ALOGW("Can't set SCHED_OTHER for primeCache");}}getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());// Inform native graphics APIs whether the present timestamp is supported:const bool presentFenceReliable =!getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);if (mStartPropertySetThread->Start() != NO_ERROR) {ALOGE("Run StartPropertySetThread failed!");}ALOGV("Done initializing");
}
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName)

方法解析

/frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) {// 创建 HWComposer 对象return std::make_unique<android::impl::HWComposer>(serviceName);
}

创建 HWComposer 对象

/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp

namespace impl {HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)// mComposer 为:Composer 对象: mComposer(std::move(composer)),mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),mUpdateDeviceProductInfoOnHotplugReconnect(sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}HWComposer::HWComposer(const std::string& composerServiceName)
// 这里创建了 Composer 对象,参数是:composerServiceName: HWComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {}

mComposer 为:Composer 对象,composerServiceName 传入的参数为:"default"

/frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp

Composer 相当于获取hal 层服务的接口

Composer::Composer(const std::string& serviceName) : mWriter(kWriterInitialSize) {// 获取hal 层服务mComposer = V2_1::IComposer::getService(serviceName);if (mComposer == nullptr) {LOG_ALWAYS_FATAL("failed to get hwcomposer service");}if (sp<IComposer> composer_2_4 = IComposer::castFrom(mComposer)) {composer_2_4->createClient_2_4([&](const auto& tmpError, const auto& tmpClient) {if (tmpError == V2_4::Error::NONE) {mClient = tmpClient;mClient_2_2 = tmpClient;mClient_2_3 = tmpClient;mClient_2_4 = tmpClient;}});} else if (sp<V2_3::IComposer> composer_2_3 = V2_3::IComposer::castFrom(mComposer)) {composer_2_3->createClient_2_3([&](const auto& tmpError, const auto& tmpClient) {if (tmpError == Error::NONE) {mClient = tmpClient;mClient_2_2 = tmpClient;mClient_2_3 = tmpClient;}});} else {mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {if (tmpError != Error::NONE) {return;}mClient = tmpClient;

3). 调用 surfaceflinger 的run 方法,开启消息队列机制

flinger->run()

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp


void SurfaceFlinger::run() {// 循环遍历消息while (true) {mEventQueue->waitMessage();}
}// 发送消息的接口
template <typename F, typename T>
inline std::future<T> SurfaceFlinger::schedule(F&& f) {auto [task, future] = makeTask(std::move(f));mEventQueue->postMessage(std::move(task));return std::move(future);
}

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp

void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {mFlinger = flinger;// 创建 Looper 对象mLooper = new Looper(true);mHandler = new Handler(*this);
}-------
// waitMessage 也是个死循环,调用 Looper->pollOnce 方法void MessageQueue::waitMessage() {do {IPCThreadState::self()->flushCommands();int32_t ret = mLooper->pollOnce(-1);switch (ret) {case Looper::POLL_WAKE:case Looper::POLL_CALLBACK:continue;case Looper::POLL_ERROR:ALOGE("Looper::POLL_ERROR");continue;case Looper::POLL_TIMEOUT:// timeout (should not happen)continue;default:// should not happenALOGE("Looper::pollOnce() returned unknown status %d", ret);continue;}} while (true);
}

调用 Looper 的头文件为如下:

27  #include <utils/Looper.h>

/system/core/libutils/include/utils/Looper.h

    int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);inline int pollOnce(int timeoutMillis) {return pollOnce(timeoutMillis, nullptr, nullptr, nullptr);}

/system/core/libutils/Looper.cpp


int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {int result = 0;for (;;) {while (mResponseIndex < mResponses.size()) {
。。result = pollInner(timeoutMillis);}
}
==========int Looper::pollInner(int timeoutMillis) {
#if DEBUG_POLL_AND_WAKEALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
#endif
。。。。。。。。struct epoll_event eventItems[EPOLL_MAX_EVENTS];
// 线程阻塞int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);

看下发送消息的流程:

template <typename F, typename T>
inline std::future<T> SurfaceFlinger::schedule(F&& f) {// a. 先调用 makeTask 创建taskauto [task, future] = makeTask(std::move(f));
// b. 将task 发到消息队列中mEventQueue->postMessage(std::move(task));// 返回future,可以通过 future.get() 获取异步处理回来的结果return std::move(future);
}

比如调用下列的设置帧率的方法,异步调用:

status_t SurfaceFlinger::setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,int8_t compatibility, int8_t changeFrameRateStrategy) {if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy,"SurfaceFlinger::setFrameRate")) {return BAD_VALUE;}// schedule 方法static_cast<void>(schedule([=] {Mutex::Autolock lock(mStateLock);if (authenticateSurfaceTextureLocked(surface)) {sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer();if (layer == nullptr) {ALOGE("Attempt to set frame rate on a layer that no longer exists");return BAD_VALUE;}const auto strategy =Layer::FrameRate::convertChangeFrameRateStrategy(changeFrameRateStrategy);if (layer->setFrameRate(Layer::FrameRate(Fps{frameRate},Layer::FrameRate::convertCompatibility(compatibility),strategy))) {setTransactionFlags(eTraversalNeeded);}} else {ALOGE("Attempt to set frame rate on an unrecognized IGraphicBufferProducer");return BAD_VALUE;}return NO_ERROR;}));return NO_ERROR;
}

// a. 先调用 makeTask 创建task
    auto [task, future] = makeTask(std::move(f));

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h

std::packaged_task的作用就是提供一个不同线程之间的数据同步机制,它可以存储一个函数操作,并将其返回值传递给对应的future, 而这个future在另外一个线程中也可以安全的访问到这个值 

vtemplate <typename F>// 继承了 MessageHandler 
class Task : public MessageHandler {template <typename G>friend auto makeTask(G&&);explicit Task(F&& f) : mTask(std::move(f)) {}// 执行 handleMessage 消息,则执行 mTask 方法;mTask 就是 f 方法void handleMessage(const Message&) override { mTask(); }using T = std::invoke_result_t<F>;std::packaged_task<T()> mTask;
};template <typename F>
inline auto makeTask(F&& f) {sp<Task<F>> task = new Task<F>(std::move(f));return std::make_pair(task, task->mTask.get_future());
}

所以,如果调用Task 的 handleMessage 方法,则执行了回调的方法 f


// b. 将task 发到消息队列中
    mEventQueue->postMessage(std::move(task));

将 task 放入到消息队列中,task->mTask 可以获取到对应传入的函数 f

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp

// Task 的父类是 MessageHandler
void MessageQueue::postMessage(sp<MessageHandler>&& handler) {// 传入 Task 和 Message 对象mLooper->sendMessage(handler, Message());
}

Message 对象在  Looper 头文件有定义

/system/core/libutils/include/utils/Looper.h

初始化 Message,其中 what 为 0 

 * A message that can be posted to a Looper.*/
struct Message {Message() : what(0) { }Message(int w) : what(w) { }/* The message type. (interpretation is left up to the handler) */int what;
};

/system/core/libutils/Looper.cpp


  Vector<MessageEnvelope> mMessageEnvelopes 是个动态数组,将其保存到数组中


void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);sendMessageAtTime(now, handler, message);
}===============// 其中 mMessageEnvelopes 是个动态数组Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLockvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,const Message& message) {
#if DEBUG_CALLBACKSALOGD("%p ~ sendMessageAtTime - uptime=%" PRId64 ", handler=%p, what=%d",this, uptime, handler.get(), message.what);
#endifsize_t i = 0;{ // acquire lockAutoMutex _l(mLock);size_t messageCount = mMessageEnvelopes.size();// 如果当前时间 uptime  有延时处理,则遍历所有的消息执行时间,插入到数组中while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {i += 1;}
// MessageEnvelope 包装 handler, messageMessageEnvelope messageEnvelope(uptime, handler, message);// 插入到数组中mMessageEnvelopes.insertAt(messageEnvelope, i, 1);// Optimization: If the Looper is currently sending a message, then we can skip// the call to wake() because the next thing the Looper will do after processing// messages is to decide when the next wakeup time should be.  In fact, it does// not even matter whether this code is running on the Looper thread.if (mSendingMessage) {return;}} // release lock// Wake the poll loop only when we enqueue a new message at the head.// 如果需要立即执行,则唤醒阻塞的线程if (i == 0) {wake();}
}

wake 唤醒阻塞的线程

void Looper::wake() {
#if DEBUG_POLL_AND_WAKEALOGD("%p ~ wake", this);
#endifuint64_t inc = 1;// 写入到 mWakeEventFd 文件描述符,可以执行了ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd.get(), &inc, sizeof(uint64_t)));if (nWrite != sizeof(uint64_t)) {if (errno != EAGAIN) {LOG_ALWAYS_FATAL("Could not write wake signal to fd %d (returned %zd): %s",mWakeEventFd.get(), nWrite, strerror(errno));}}
}

Looper 中的 pollInner 方法,继续往下执行:

int Looper::pollInner(int timeoutMillis) {
#if DEBUG_POLL_AND_WAKEALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
#endif
。。。for (int i = 0; i < eventCount; i++) {int fd = eventItems[i].data.fd;uint32_t epollEvents = eventItems[i].events;if (fd == mWakeEventFd.get()) {if (epollEvents & EPOLLIN) {// 读取对应的文件描述符awoken();} else {ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);}v。。。// Invoke pending message callbacks.mNextMessageUptime = LLONG_MAX;while (mMessageEnvelopes.size() != 0) {nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);// 获取数组中的首个元素const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);// 判断时间是否满足if (messageEnvelope.uptime <= now) {// Remove the envelope from the list.// We keep a strong reference to the handler until the call to handleMessage// finishes.  Then we drop it so that the handler can be deleted *before*// we reacquire our lock.{ // obtain handler// 获取 handler sp<MessageHandler> handler = messageEnvelope.handler;Message message = messageEnvelope.message;// 移除这个消息 MessageEnvelopesmMessageEnvelopes.removeAt(0);mSendingMessage = true;mLock.unlock();#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKSALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",this, handler.get(), message.what);
#endif// 调用 handleMessage 方法handler->handleMessage(message);} // release handler

调用 handleMessage 方法

/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h

template <typename F>
class Task : public MessageHandler {template <typename G>friend auto makeTask(G&&);explicit Task(F&& f) : mTask(std::move(f)) {}// 回调函数的方法void handleMessage(const Message&) override { mTask(); }

利用C++的新特型做了抽象与封装,本质还是向主线程发送一个Message并指定其MessageHandler,所以其实还是在 SurfaceFlinger 的主线程中进行

2. 应用与 surfaceFlinger 通信

每个应用进程均会创建一个与 SurfaceFlinger 进程binder 通信的接口,为如下流程:

在创建应用的时候,有如下流程:

/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

在WMS中,每一个Window都会对应一个WindowState,表示具体窗口信息

1374      public int addWindow(Session session, IWindow client, int seq,
1375              LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
1376              Rect outContentInsets, Rect outStableInsets,
1377              DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
1378              InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
1379              int requestUserId) {
1380          Arrays.fill(outActiveControls, null);。。。
// 创建了 WindowState 对象
1555              final WindowState win = new WindowState(this, session, client, token, parentWindow,
1556                      appOp[0], seq, attrs, viewVisibility, session.mUid, userId,
1557                      session.mCanAddInternalSystemWindow);// 调用 WindowState 对象的 attach 方法
1634              win.attach();

调用 WindowState 对象的 attach 方法

/frameworks/base/services/core/java/com/android/server/wm/WindowState.java

273      final Session mSession;962      void attach() {
963          if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
964          mSession.windowAddedLocked(mAttrs.packageName);
965      }

windowAddedLocked

/frameworks/base/services/core/java/com/android/server/wm/Session.java

512      void windowAddedLocked(String packageName) {
513          mPackageName = packageName;
514          mRelayoutTag = "relayoutWindow: " + mPackageName;
515          if (mSurfaceSession == null) {
516              if (DEBUG) {
517                  Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession");
518              }// 创建 SurfaceSession 对象
519              mSurfaceSession = new SurfaceSession();
520              ProtoLog.i(WM_SHOW_TRANSACTIONS, "  NEW SURFACE SESSION %s", mSurfaceSession);
521              mService.mSessions.add(this);
522              if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
523                  mService.dispatchNewAnimatorScaleLocked(this);
524              }
525          }
526          mNumWindow++;
527      }

创建 SurfaceSession 对象

/frameworks/base/core/java/android/view/SurfaceSession.java

30      private long mNativeClient; // SurfaceComposerClient*
31  
32      private static native long nativeCreate();
33      private static native void nativeDestroy(long ptr);
34      private static native void nativeKill(long ptr);
35  
36      /** Create a new connection with the surface flinger. */
37      @UnsupportedAppUsage
38      public SurfaceSession() {// native 层去创建
39          mNativeClient = nativeCreate();
40      }

nativeCreate 方法

/frameworks/base/core/jni/android_view_SurfaceSession.cpp

static const JNINativeMethod gMethods[] = {/* name, signature, funcPtr */{ "nativeCreate", "()J",(void*)nativeCreate },。。。
static jlong nativeCreate(JNIEnv* env, jclass clazz) {// 创建 SurfaceComposerClient 对象SurfaceComposerClient* client = new SurfaceComposerClient();client->incStrong((void*)nativeCreate);return reinterpret_cast<jlong>(client);
}

创建 SurfaceComposerClient 对象

/frameworks/native/libs/gui/SurfaceComposerClient.cpp

SurfaceComposerClient::SurfaceComposerClient(): mStatus(NO_INIT)
{
}
--------
// 由于 SurfaceComposerClient 继承了 RefBase ,所以初始化会调用 onFirstRef 方法void SurfaceComposerClient::onFirstRef() {sp<ISurfaceComposer> sf(ComposerService::getComposerService());if (sf != nullptr && mStatus == NO_INIT) {sp<ISurfaceComposerClient> conn;conn = sf->createConnection();if (conn != nullptr) {mClient = conn;mStatus = NO_ERROR;}}
}

sf 的值通过 ComposerService 获取服务:

41  class ComposerService : public Singleton<ComposerService>
42  {
43      sp<ISurfaceComposer> mComposerService;=============/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {// ComposerService 继承了 Singleton 是单例模式,调用构造函数去:connectLockedComposerService& instance = ComposerService::getInstance();Mutex::Autolock _l(instance.mLock);if (instance.mComposerService == nullptr) {ComposerService::getInstance().connectLocked();assert(instance.mComposerService != nullptr);ALOGD("ComposerService reconnected");}
// 返回对象的 mComposerService 成员return instance.mComposerService;
}------
void ComposerService::connectLocked() {const String16 name("SurfaceFlinger");// ServiceManager 去获取到 "SurfaceFlinger" 服务,赋值给 mComposerServicewhile (getService(name, &mComposerService) != NO_ERROR) {usleep(250000);}assert(mComposerService != nullptr);

接着调用:sf->createConnection,sf 为 sp<ISurfaceComposer> mComposerService

根据binder 通信原理,BpSurfaceComposer 为客户端,去调用服务器端的方法

/frameworks/native/libs/gui/include/gui/ISurfaceComposer.h

class ISurfaceComposer: public IInterface {
public:// 宏定义去展开一系列 的函数定义DECLARE_META_INTERFACE(SurfaceComposer)// createConnection 方法* Create a connection with SurfaceFlinger.*/virtual sp<ISurfaceComposerClient> createConnection() = 0;// Out-of-line virtual method definition to trigger vtable emission in this
// translation unit (see clang warning -Wweak-vtables)
BpSurfaceComposer::~BpSurfaceComposer() {}// 并且,调用了下列的宏定义
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");

DECLARE_META_INTERFACE(SurfaceComposer)  宏定义去展开一系列 的函数定义

/frameworks/native/libs/binder/include/binder/IInterface.h

#define DECLARE_META_INTERFACE(INTERFACE)                               \
public:                                                                 \static const ::android::String16 descriptor;                        \static ::android::sp<I##INTERFACE> asInterface(                     \const ::android::sp<::android::IBinder>& obj);              \。。。。
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)    \#endif#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\const ::android::StaticString16                                     \I##INTERFACE##_descriptor_static_str16(__IINTF_CONCAT(u, NAME));\const ::android::String16 I##INTERFACE::descriptor(                 \I##INTERFACE##_descriptor_static_str16);                        \const ::android::String16&                                          \I##INTERFACE::getInterfaceDescriptor() const {              \return I##INTERFACE::descriptor;                                \}                                                                   \// asInterface 的方法实现。I##INTERFACE 为:ISurfaceComposer::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \const ::android::sp<::android::IBinder>& obj)               \{                                                                   \::android::sp<I##INTERFACE> intr;                               \if (obj != nullptr) {                                           \intr = static_cast<I##INTERFACE*>(                          \obj->queryLocalInterface(                               \I##INTERFACE::descriptor).get());               \if (intr == nullptr) {                                      \
// 创建 BpSurfaceComposer 对象,并返回intr = new Bp##INTERFACE(obj);                          \}                                                           \}                                                               \return intr;                                                    \}                                                                   \std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl;           \

创建 BpSurfaceComposer 对象,调用 createConnection 方法

 /frameworks/native/libs/gui/ISurfaceComposer.cpp

class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:explicit BpSurfaceComposer(const sp<IBinder>& impl): BpInterface<ISurfaceComposer>(impl){}virtual ~BpSurfaceComposer();virtual sp<ISurfaceComposerClient> createConnection(){Parcel data, reply;data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());// binder 通信remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
// reply 为对端回复的消息return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());}

remote()->transact(BnSurfaceComposer::CREATE_CONNECTION

BnSurfaceComposer 和 BpSurfaceComposer 一般情况下均是在同一个文件中

// ----------------------------------------------------------------------status_t BnSurfaceComposer::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{switch(code) {// 回调onTransact 方法case CREATE_CONNECTION: {CHECK_INTERFACE(ISurfaceComposer, data, reply);// 调用其子类的 createConnection 方法sp<IBinder> b = IInterface::asBinder(createConnection());reply->writeStrongBinder(b);return NO_ERROR;}

看下谁继承了 BnSurfaceComposer

/frameworks/native/services/surfaceflinger/SurfaceFlinger.h

class SurfaceFlinger : public BnSurfaceComposer,public PriorityDumper,public ClientCache::ErasedRecipient,private IBinder::DeathRecipient,private HWC2::ComposerCallback,private ISchedulerCallback {

SurfaceFlinger 继承了 BnSurfaceComposer,SurfaceFlinger 重写了 onTransact 方法

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply,uint32_t flags) {status_t credentialCheck = CheckTransactCodeCredentials(code);if (credentialCheck != OK) {return credentialCheck;}// 再次调用父类的方法 onTransactstatus_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {CHECK_INTERFACE(ISurfaceComposer, data, reply);

createConnection 方法


sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {// 这里创建了一个客户端 Client作为中介,传入了this 指针const sp<Client> client = new Client(this);return client->initCheck() == NO_ERROR ? client : nullptr;
}

client  对象为如下:

/frameworks/native/services/surfaceflinger/Client.h

class Client : public BnSurfaceComposerClient
{
public:explicit Client(const sp<SurfaceFlinger>& flinger);

/frameworks/native/services/surfaceflinger/Client.cpp

45  status_t Client::initCheck() const {
46      return NO_ERROR;
47  }

总结,时序图为如下:

  • SurfaceFlinger系统服务的Binder RPC架构

SurfaceFlinger作为典型的Binder系统服务,遵循Binder服务设计的一般原则:

Interface接口:ISurfaceComposer 、ISurfaceComposerClient

Bp客户端:BpSurfaceComposer、BpSurfaceComposerClient

Bn服务端:BnSurfaceComposer、BnSurfaceComposerClient

服务实现:SurfaceFlinger、Client

相关文章:

【安卓源码】SurfaceFlinger 启动及其与应用通信

1. surfaceFlinger 初始化和消息队列处理机制 surfaceflinger 的makefile 文件 /frameworks/native/services/surfaceflinger/Android.bp 235 cc_binary { 236 name: "surfaceflinger", 237 defaults: ["libsurfaceflinger_binary"], 238 i…...

springboot车辆充电桩

sprinboot车辆充电桩演示录像2022开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;ecli…...

linux进程和进程通信编程(1)

What makes the desert beautiful is that somewhere it hides a well. 沙漠之所以美丽,是因为在它的某个角落隐藏着一口井. linux进程和进程通信编程&#xff08;1&#xff09;1.什么是进程2.进程id(pid)3.进程间通信的方法管道信号IPCSocket4.创建进程forkfork有三个返回值父…...

操作系统(1.3)--习题

一、课堂习题 1、一个作业第一 次执行时用了5min ,而第二次执行时用了6min,这说明了操作系统的( )特点。 A、并发性 B、共享性 C、虚拟性 D、不确定性 D 2、在计算机系统中,操作系统是( )。 A、处于裸机之上的第一层软件 B、处于硬件之下的低层软件 C、处于应用软件之上的系统软…...

刷题笔记之十三(有假币、最难的问题、因子个数)

目录 1. 求正数数组的最小不可组成和 2. 有假币 3. 继承时先调用父类的构造方法;类中的成员变量的初始化操作都在构造方法时进行 4. 学会并理解装箱拆箱,注意new出来的也可以拆!! 5. getDeclaredMethods()是标识类或接口的声明成员(这个表示public private 包访问权限 pro…...

5个代码技巧,加速你的Python

5个代码技巧&#xff0c;加速你的Python 人生苦短&#xff0c;快学Python&#xff01; Python作为一种功能强大的编程语言&#xff0c;因其简单易学而受到很多初学者的青睐。它的应用领域又非常广泛&#xff1a;科学计算、游戏开发、爬虫、人工智能、自动化办公、Web应用开发…...

字节跳动软件测试岗,前两面过了,第三面HR天坑!竟然跟我说……

阎王易见&#xff0c;小鬼难缠。我一直相信这个世界上好人居多&#xff0c;但是也没想到自己也会在阴沟里翻船。我感觉自己被字节跳动的HR坑了。在这里&#xff0c;我只想告诫大家&#xff0c;offer一定要拿到自己的手里才是真的&#xff0c;口头offer都是不牢靠的&#xff0c;…...

[数据分析与可视化] Python绘制数据地图1-GeoPandas入门指北

本文主要介绍GeoPandas的基本使用方法&#xff0c;以绘制简单的地图。GeoPandas是一个Python开源项目&#xff0c;旨在提供丰富而简单的地理空间数据处理接口。GeoPandas扩展了Pandas的数据类型&#xff0c;并使用matplotlib进行绘图。GeoPandas官方仓库地址为&#xff1a;GeoP…...

ChatGPT加强版GPT-4面世,打工人的方式将被颠覆

&#x1f517; 运行环境&#xff1a;chatGPT&#xff0c;GPT-4 &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#…...

Python逆向及相关知识

今天第二次看见python字节码的逆向题&#xff0c;然后发现了一个介绍Python逆向的文章&#xff0c;所以把文章里的内容简单整理记录一下。 文章参考&#xff1a;https://www.cnblogs.com/blili/p/11799398.html Python运行原理&#xff1a; 一.什么是Python Python 是一种解…...

Python基础语法、注意点加实例全解

本篇文章我们讲解Python最基础语法&#xff0c;包含&#xff1a;数据类型、注释、变量、类型转换、命名规范、运算符、字符串拼接、字符串格式化、if条件判断、while循环、for循环、函数、读取文件、写入文件、异常捕获、包导入等。通过讲解语法注意事项实例代码详解&#xff0…...

ETH RPC搭建

配置选择先是看了aws、谷歌云、阿里云这个配置都要1-2wrmb一个月&#xff0c;太贵了问了很多朋友&#xff0c;打算用hetzner&#xff0c;50欧一个月足以我选的配置&#xff1a;64gb&#xff0c;2tb ssd开好后在邮箱收到信息链接后按以下步骤安装系统&#xff1a;https://0o0.me…...

南京邮电大学数据库第一次课后作业

1.单选题 (5分) (B)是存储在计算机内有结构的数据的集合。 &#xff08;A&#xff09;数据库系统 &#xff08;B&#xff09;数据库 &#xff08;C&#xff09;数据库管理系统 &#xff08;D&#xff09;数据结构 2.单选题 (5分) 数据库的特点之一是数据的共享,严格的讲,这里的…...

近期投简历、找日常实习的一些碎碎念(大二---测试岗)

嘿嘿嘿&#xff0c;我又回来了&#xff0c;相信不少兄弟已经发现我似乎已经断更了好久&#xff0c;哈哈&#xff0c;我是尝试去找实习&#xff0c;投简历面试去了。 先说一下背景。 目录 背景 求职进行中 简历 投递和沟通 收获和感受 背景 博主&#xff0c;大二软件工程…...

ThreadLocal的使用

1. ThreadLocal介绍 ThreadLocal顾名思义&#xff0c;就是线程的本地变量&#xff0c;只有当前线程可见&#xff0c;对其他线程来说是封闭且隔离的。每一个线程为自己本身创建ThreadLocal变量&#xff0c;只有当前线程可以访问&#xff0c;其他的线程不可以&#xff0c;从根源…...

Java ~ Reference【总结】

一 概述 简介 在JDK1.2之前&#xff0c;Java中引用的定义是十分传统的&#xff1a;如果引用类型的变量中存储的数值代表的是另一块内存的起始地址&#xff0c;就称这块内存代表着一个引用。在这种定义之下&#xff0c;一个对象只有被引用和没有被引用两种状态。 实际上&#xf…...

最快方法求最长上升子序列(LIS)+最长公共子序列(LCS)模板(C/C++)

目录 1 LIS算法&#xff08;最长上升子序列&#xff09; 1.1 简介 1.2 代码 1.3 相关解释 2 LCS算法&#xff08;最长公共子序列&#xff09; 2.1 简介 2.2 代码&#xff08;动态规划&#xff0c;时间复杂度O&#xff08;nlogn&#xff09;&#xff09; 2.3 特殊…...

012+limou+C语言深入知识——(4)“结构体”与“枚举体”与“联合体”

一、结构体 1、结构体基础 &#xff08;1&#xff09;结构体完全声明 struct tag {member-list; }variable-list;//描述一个人 struct people {char name[10];//人名int age;//年龄int idnumber;//身份证 };&#xff08;2&#xff09;结构体不完全声明&#xff08;匿名结构体…...

Canvas百战成神-圆(1)

Canvas百战成神-圆 初始化容器 <canvas id"canvas"></canvas>canvas{border: 1px solid black; }让页面占满屏幕 *{margin: 0;padding: 0; } html,body{width: 100%;height: 100%;overflow: hidden; } ::-webkit-scrollbar{display: none; }初始化画笔…...

详解分库分表设计

详解分库分表设计 背景 ​ 在传统的单机数据库架构中&#xff0c;所有数据都存储在同一个数据库中&#xff0c;随着业务规模的不断扩大&#xff0c;数据量和并发量也会越来越大&#xff0c;这会给数据库的性能和可用性带来挑战。此外&#xff0c;当单机数据库的容量达到瓶颈时…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程

基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...

13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析

LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...

Pandas 可视化集成:数据科学家的高效绘图指南

为什么选择 Pandas 进行数据可视化&#xff1f; 在数据科学和分析领域&#xff0c;可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具&#xff0c;如 Matplotlib、Seaborn、Plotly 等&#xff0c;但 Pandas 内置的可视化功能因其与数据结…...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能

vxe-table vue 表格复选框多选数据&#xff0c;实现快捷键 Shift 批量选择功能 查看官网&#xff1a;https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...

【Axure高保真原型】图片列表添加和删除图片

今天和大家分享图片列表添加和删除图片的原型模板&#xff0c;效果包括&#xff1a; 点击图片列表的加号可以显示图片选择器&#xff0c;选择里面的图片&#xff1b; 选择图片后点击添加按钮&#xff0c;可以将该图片添加到图片列表&#xff1b; 鼠标移入图片列表的图片&…...