本文共 4142 字,大约阅读时间需要 13 分钟。
以Android Pie为例
1.surfaceflinger 是一个独立的CPP应用程序,手机中存放在/system/bin/surfaceflinger
可以看一下surfaceflinger调用的库:
<----------------------------------------------------------------------------
$adb shell
$adb su
#ps -A | grep surfaceflinger
system 1234 1 220351 19868 SyS_epool_wait 0 S surfaceflinger
假设Surfaceflinger的进程号是1234
#pmap 1234
---------------------------------------------------------------------------------->
SurfaceComposerClient 是一个CPP类,
定义在:
androidSourceDir/frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h
成员函数实现在:
androidSourceDir/framework/native/libs/gui/SurfaceComposerClient.cpp
我们先到androidSourceDir/framework$ grep -rn SurfaceComposerClient (核心技术机密外泄^^)
Android中有很多可以入手的点:选screencap吧,最简示例。
先从androidSourceDir/frameworks/base/cmds/screencap/screencap.cpp这个应用程序开始说去,这样会让我们比较感性的接触Android。
攻关目标:将且仅将screencap.cpp的每行代码了然于胸,不留死角。总共261行。其实没必要,还是一招鲜,数据流法:谁的数据?数据从哪里来?数据到哪里去?
阅码方法:静态运行,逐句法。No,数据,数据,数据。
只解读如下用法 $screencap -p helloscreen.png
数据是即将推送到显示器上去的一帧图像;who?
揪出这个数据从哪里来,会给我们带来很多知识。
从main()第一行开始:
int main(int argc, char** argv)
{ const char* pname = argv[0]; bool png = false; int32_t displayId = DEFAULT_DISPLAY_ID; int c; while ((c = getopt(argc, argv, "phd:")) != -1) { switch (c) { case 'p': png = true;//LL:存储为png的标识变量。 break; ... } } argc -= optind; argv += optind;int fd = -1;
const char* fn = NULL; ... fn = argv[0]; fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);//LL:准备存储图片到手机 ... }....
void const* mapbase = MAP_FAILED;
ssize_t mapsize = -1;void* base = NULL;
uint32_t w, s, h, f; android_dataspace d; size_t size = 0;// Maps orientations from DisplayInfo to ISurfaceComposer
static const uint32_t ORIENTATION_MAP[] = { ISurfaceComposer::eRotateNone, // 0 == DISPLAY_ORIENTATION_0 ISurfaceComposer::eRotate270, // 1 == DISPLAY_ORIENTATION_90 ISurfaceComposer::eRotate180, // 2 == DISPLAY_ORIENTATION_180 ISurfaceComposer::eRotate90, // 3 == DISPLAY_ORIENTATION_270 };// setThreadPoolMaxThreadCount(0) actually tells the kernel it's
// not allowed to spawn any additional threads, but we still spawn // a binder thread from userspace when we call startThreadPool(). // See b/36066697 for rationale ProcessState::self()->setThreadPoolMaxThreadCount(0); ProcessState::self()->startThreadPool();sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
....Vector<DisplayInfo> configs;
SurfaceComposerClient::getDisplayConfigs(display, &configs); int activeConfig = SurfaceComposerClient::getActiveConfig(display); ... uint8_t displayOrientation = configs[activeConfig].orientation; uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];sp<GraphicBuffer> outBuffer;
status_t result = ScreenshotClient::capture(display, Rect(), 0 /* reqWidth */, 0 /* reqHeight */, INT32_MIN, INT32_MAX, /* all layers */ false, captureOrientation, &outBuffer); if (result != NO_ERROR) { close(fd); _exit(1); }result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
if (base == NULL) {
close(fd); _exit(1); }w = outBuffer->getWidth();
h = outBuffer->getHeight(); s = outBuffer->getStride(); f = outBuffer->getPixelFormat(); d = HAL_DATASPACE_UNKNOWN; size = s * h * bytesPerPixel(f);if (png) {
const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType, dataSpaceToColorSpace(d)); SkPixmap pixmap(info, base, s * bytesPerPixel(f)); struct FDWStream final : public SkWStream { size_t fBytesWritten = 0; int fFd; FDWStream(int f) : fFd(f) {} size_t bytesWritten() const override { return fBytesWritten; } bool write(const void* buffer, size_t size) override { fBytesWritten += size; return size == 0 || ::write(fFd, buffer, size) > 0; } } fdStream(fd); (void)SkEncodeImage(&fdStream, pixmap, SkEncodedImageFormat::kPNG, 100); if (fn != NULL) { notifyMediaScanner(fn); } } else { uint32_t c = dataSpaceToInt(d); write(fd, &w, 4); write(fd, &h, 4); write(fd, &f, 4); write(fd, &c, 4); size_t Bpp = bytesPerPixel(f); for (size_t y=0 ; y<h ; y++) { write(fd, base, w*Bpp); base = (void *)((char *)base + s*Bpp); } } close(fd); if (mapbase != MAP_FAILED) { munmap((void *)mapbase, mapsize); }// b/36066697: Avoid running static destructors.
_exit(0); }
转载地址:http://krymf.baihongyu.com/