当前位置: 首页 > 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;当单机数据库的容量达到瓶颈时…...

动态规划-基础(斐波那契数、爬楼梯、使用最小花费爬楼梯、不同路径、不同路径II、整数拆分、不同的二叉搜索树)

动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的。动态规划问题&#xff0c;五步走&#xff1a;状态定义&am…...

深入理解WebSocket协议

“ 一直以来对WebSocket仅停留在使用阶段&#xff0c;也没有深入理解其背后的原理。当看到 x x x was not upgraded to websocket&#xff0c;我是彻底蒙了&#xff0c;等我镇定下来&#xff0c;打开百度输入这行报错信息&#xff0c;随即看到的就是大家说的跨域&#xff0c;或…...

Vector的扩容机制

到需要扩容的时候&#xff0c;Vector会根据需要的大小&#xff0c;创建一个新数组&#xff0c;然后把旧数组的元素复制进新数组。 我们可以看到&#xff0c;扩容后&#xff0c;其实是一个新数组&#xff0c;内部元素的地址已经改变了。所以扩容之后&#xff0c;原先的迭代器会…...

22讲MySQL有哪些“饮鸩止渴”提高性能的方法

短连接风暴 是指数据库有很多链接之后只执行了几个语句就断开的客户端&#xff0c;然后我们知道数据库客户端和数据库每次连接不仅需要tcp的三次握手&#xff0c;而且还有mysql的鉴权操作都要占用很多服务器的资源。话虽如此但是如果连接的不多的话其实这点资源无所谓的。 但是…...

10.0自定义SystemUI下拉状态栏和通知栏视图(六)之监听系统通知

1.前言 在进行rom产品定制化开发中,在10.0中针对systemui下拉状态栏和通知栏的定制UI的工作开发中,原生系统的下拉状态栏和通知栏的视图UI在产品开发中会不太满足功能, 所以根据产品需要来自定义SystemUI的下拉状态栏和通知栏功能,首选实现的就是下拉通知栏左滑删除通知的部…...

怎样在外网登录访问CRM管理系统?

一、什么是CRM管理系统&#xff1f; Customer Relationship Management&#xff0c;简称CRM&#xff0c;指客户关系管理&#xff0c;是企业利用信息互联网技术&#xff0c;协调企业、顾客和服务上的交互&#xff0c;提升管理服务。为了企业信息安全以及使用方便&#xff0c;企…...

Activity工作流(三):Service服务

3. Service服务 所有的Service都通过流程引擎获得。 3.1 RepositoryService 仓库服务是存储相关的服务&#xff0c;一般用来部署流程文件&#xff0c;获取流程文件&#xff08;bpmn和图片&#xff09;&#xff0c;查询流程定义信息等操作&#xff0c;是引擎中的一个重要的服务。…...

算法--最长回文子串--java--python

这个算法题里面总是有 暴力解法 把所有字串都拿出来判断一下 这里有小小的优化&#xff1a; 就是当判断的字串小于等于我们自己求得的最长回文子串的长度&#xff0c;那么我们就不需要在进行对这个的判断这里的begin&#xff0c;还可以用来取得最小回文子串是什么 java // 暴…...

ElasticSearch-第二天

目录 文档批量操作 批量获取文档数据 批量操作文档数据 DSL语言高级查询 DSL概述 无查询条件 叶子条件查询 模糊匹配 match的复杂用法 精确匹配 组合条件查询(多条件查询) 连接查询(多文档合并查询) 查询DSL和过滤DSL 区别 query DSL filter DSL Query方式查…...

【AI大比拼】文心一言 VS ChatGPT-4

摘要&#xff1a;本文将对比分析两款知名的 AI 对话引擎&#xff1a;文心一言和 OpenAI 的 ChatGPT&#xff0c;通过实际案例让大家对这两款对话引擎有更深入的了解&#xff0c;以便大家选择合适的 AI 对话引擎。 亲爱的 CSDN 朋友们&#xff0c;大家好&#xff01;近年来&…...