chipset: MSM8x25Q
codebase: Android4.1
Screencap和screenshot大同小异,不过前者是直接用build好的一个可执行文件来操作的,文件位于/system/bin/screencap。看下code:
int main(int argc, char** argv)
{
const char* pname = argv[0];
bool png = false;
int c;
while ((c = getopt(argc, argv, "ph")) != -1) {
switch (c) {
case 'p':
png = true;
break;
case '?':
case 'h':
usage(pname);
return 1;
}
}
argc -= optind;
argv += optind;
int fd = -1;
if (argc == 0) {
fd = dup(STDOUT_FILENO);
} else if (argc == 1) {
/*获取参数argv[0],为要保存screencap的path*/
const char* fn = argv[0];
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (fd == -1) {
fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
return 1;
}
const int len = strlen(fn);
/*path file是否为png*/
if (len >= 4 && 0 == strcmp(fn+len-4, ".png")) {
png = true;
}
}
if (fd == -1) {
usage(pname);
return 1;
}
void const* mapbase = MAP_FAILED;
ssize_t mapsize = -1;
void const* base = 0;
uint32_t w, h, f;
size_t size = 0;
ScreenshotClient screenshot;
/*最终通过SF的update去重画*/
if (screenshot.update() == NO_ERROR) {
/*获得显示buffer的address*/
base = screenshot.getPixels();
w = screenshot.getWidth();
h = screenshot.getHeight();
f = screenshot.getFormat();
size = screenshot.getSize();
ALOGE("screencap w:%d, h:%d, f:%d, size:%d", w, h, f, size);
} else {
/*上面用SF更新buffer失败的话就直接从fb中获得。*/
const char* fbpath = "/dev/graphics/fb0";
int fb = open(fbpath, O_RDONLY);
if (fb >= 0) {
struct fb_var_screeninfo vinfo;
if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) == 0) {
uint32_t bytespp;
if (vinfoToPixelFormat(vinfo, &byte