void framebuffer_service(int fd, void *cookie) { struct fbinfo fbinfo; unsigned int i; char buf[640]; int fd_screencap,fb; int w, h, f; int fds[2]; if (pipe(fds) < 0) goto done; pid_t pid = fork(); if (pid < 0) goto done; if (pid == 0) { dup2(fds[1], STDOUT_FILENO); close(fds[0]); close(fds[1]); #if (0 == LCDC_CAPTURE) const char* command = "screencap"; const char *args[2] = {command, NULL}; execvp(command, (char**)args); exit(1); #else // #if (LCDC_CAPTURE) if ((fb=open("/system/bin/lcdc_screen_cap",O_RDONLY)) >= 0){ close(fb); const char * command = "lcdc_screen_cap"; const char *args[2] = {command, NULL}; execvp(command, (char**)args); exit(1); } else{ lcdc_screen_cap(); exit(0); } #endif } fd_screencap = fds[0]; /* read w, h & format */ if(readx(fd_screencap, &w, 4)) goto error; if(readx(fd_screencap, &h, 4)) goto error; if(readx(fd_screencap, &f, 4)) goto error; fbinfo.version = DDMS_RAWIMAGE_VERSION; /* see hardware/hardware.h */ switch (f) { case 1: /* RGBA_8888 */ fbinfo.bpp = 32; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 0; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 16; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 8; break; case 2: /* RGBX_8888 */ fbinfo.bpp = 32; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 0; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 16; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 0; break; case 3: /* RGB_888 */ fbinfo.bpp = 24; fbinfo.size = w * h * 3; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 0; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 16; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 0; break; case 4: /* RGB_565 */ fbinfo.bpp = 16; fbinfo.size = w * h * 2; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 11; fbinfo.red_length = 5; fbinfo.green_offset = 5; fbinfo.green_length = 6; fbinfo.blue_offset = 0; fbinfo.blue_length = 5; fbinfo.alpha_offset = 0; fbinfo.alpha_length = 0; break; case 5: /* BGRA_8888 */ fbinfo.bpp = 32; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 16; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 0; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 8; break; default: goto done; } /* write header */ if(writex(fd, &fbinfo, sizeof(fbinfo))) goto error; /* write data */ for(i = 0; i < fbinfo.size; i += sizeof(buf)) { if ((fbinfo.size - i) < sizeof(buf)) { break; } if(readx(fd_screencap, buf, sizeof(buf))) goto error; if(writex(fd, buf, sizeof(buf))) goto error; } if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto error; if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto error; done: TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0)); goto close_fd; error: /*Alternatively, closes fds should also assure lcdc_screen_cap not block by wrting pipe*/ if(0 == kill(pid, SIGTERM)){ XLOGI("[ADB] Sent SIGTERM to process %d\n", pid); }else{ XLOGE("[ADB] Failed to send SIGTERM to process %d, errno=%s\n",pid, strerror(errno)); /*Note that even parent process failed to send signal, child process(lcdc_screen_cap) should still exit normally*/ } goto close_fd; close_fd: close(fds[0]); close(fds[1]); close(fd); }
void framebuffer_service(int fd, void *cookie) { struct fbinfo fbinfo; unsigned int i; char buf[640]; int fd_screencap,fb; int w, h, f; int fds[2]; if (pipe(fds) < 0) goto done; pid_t pid = fork(); if (pid < 0) goto done; if (pid == 0) { dup2(fds[1], STDOUT_FILENO); close(fds[0]); close(fds[1]); #if (0 == LCDC_CAPTURE) const char* command = "screencap"; const char *args[2] = {command, NULL}; execvp(command, (char**)args); exit(1); #else // #if (LCDC_CAPTURE) if ((fb=open("/system/bin/lcdc_screen_cap",O_RDONLY)) >= 0){ close(fb); const char * command = "lcdc_screen_cap"; const char *args[2] = {command, NULL}; execvp(command, (char**)args); exit(1); } else{ lcdc_screen_cap(); exit(0); } #endif } fd_screencap = fds[0]; /* read w, h & format */ if(readx(fd_screencap, &w, 4)) goto done; if(readx(fd_screencap, &h, 4)) goto done; if(readx(fd_screencap, &f, 4)) goto done; fbinfo.version = DDMS_RAWIMAGE_VERSION; /* see hardware/hardware.h */ switch (f) { case 1: /* RGBA_8888 */ fbinfo.bpp = 32; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 0; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 16; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 8; break; case 2: /* RGBX_8888 */ fbinfo.bpp = 32; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 0; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 16; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 0; break; case 3: /* RGB_888 */ fbinfo.bpp = 24; fbinfo.size = w * h * 3; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 0; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 16; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 0; break; case 4: /* RGB_565 */ fbinfo.bpp = 16; fbinfo.size = w * h * 2; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 11; fbinfo.red_length = 5; fbinfo.green_offset = 5; fbinfo.green_length = 6; fbinfo.blue_offset = 0; fbinfo.blue_length = 5; fbinfo.alpha_offset = 0; fbinfo.alpha_length = 0; break; case 5: /* BGRA_8888 */ fbinfo.bpp = 32; fbinfo.size = w * h * 4; fbinfo.width = w; fbinfo.height = h; fbinfo.red_offset = 16; fbinfo.red_length = 8; fbinfo.green_offset = 8; fbinfo.green_length = 8; fbinfo.blue_offset = 0; fbinfo.blue_length = 8; fbinfo.alpha_offset = 24; fbinfo.alpha_length = 8; break; default: goto done; } /* write header */ if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; /* write data */ for(i = 0; i < fbinfo.size; i += sizeof(buf)) { if(readx(fd_screencap, buf, sizeof(buf))) goto done; if(writex(fd, buf, sizeof(buf))) goto done; } if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto done; if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done; done: TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0)); close(fds[0]); close(fds[1]); close(fd); }