00001 #if (ANDROID_VER < 420)
00002 #error must define ANDROID_VER >= 420
00003 #endif
00004 #include <unistd.h>
00005 #include <sys/types.h>
00006 #include <fcntl.h>
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <stdarg.h>
00010 #include <errno.h>
00011 #include <sys/ioctl.h>
00012 #include <sys/mman.h>
00013 #include <math.h>
00014 #include <err.h>
00015 #include <stdbool.h>
00016 #include <sys/time.h>
00017 #include <time.h>
00018 #include <signal.h>
00019 #include <termios.h>
00020 #include <pthread.h>
00021 #include <linux/input.h>
00022 #include <sys/un.h>
00023 #include <sys/socket.h>
00024
00025 #include "libcutils.h"
00026 #include "libgui.h"
00027 #include "libui.h"
00028 #include "libskia.h"
00029 #include "libstagefright.h"
00030
00031 using namespace android;
00032
00033 struct ASC_PRIV_DATA;
00034 struct ASC {
00035 ASC_PRIV_DATA* priv_data;
00036 char* data;
00037 int size;
00038 int w;
00039 int h;
00040 char pixfmtName[32];
00041 };
00042
00043 static bool needLog = true;
00044 #define LOG(fmt, arg...) ({static bool __logged=false; if (needLog||!__logged){_LOG("%s" fmt "%s", needLog?"":"--------rare case--------", ##arg, needLog?"":"\n\n");__logged=true;}})
00045 #define LOGI(fmt, arg...) LOG("--------" fmt "\n\n", ##arg)
00046 #define ABORT(fmt, arg...) ({_LOG(fmt ". Now exit", ##arg); exit(0);})
00047 #define ABORT_ERRNO(fmt, arg...) ({_LOG(fmt " [errno %d(%s)] Now exit", errno, strerror(errno), ##arg); exit(0);})
00048
00049 static void _LOG(const char* format, ...) {
00050 char buf[4096];
00051 int cnt;
00052 va_list va;
00053 struct timespec ct;
00054 struct tm * st;
00055 clock_gettime(CLOCK_REALTIME, &ct);
00056 st = localtime(&ct.tv_sec);
00057 cnt = sprintf(buf, "%02d/%02d %02d:%02d:%02d.%03d [ASC %d] ", st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec, (int)(ct.tv_nsec/1000000), gettid());
00058 va_start(va, format);
00059 cnt += vsnprintf(buf+cnt, sizeof(buf)-cnt, format, va);
00060 va_end(va);
00061 if (cnt > sizeof(buf)) cnt = sizeof(buf); else if (cnt <= 0) {cnt = 7; strcpy(buf, "LogErr");};
00062 if (buf[cnt-1]==0) cnt--;
00063 if (buf[cnt-1]!='\n') buf[cnt++] = '\n';
00064 write(STDERR_FILENO, buf, cnt);
00065 }
00066
00067 static bool isPaused = false;
00068 static bool isScreenOff = false;
00069 static char* blackscreen = NULL;
00070 static int blackscreen_extra_count = 0;
00071
00072 static Mutex mutex;
00073 static Condition cond;
00074
00075 static bool isFirstTime = true;
00076
00077 static void chkDev() {
00078 char k[128] = {0};
00079 char _sn[256] = {0};
00080 char *sn = _sn;
00081 char hb[4+1] = {'0','0','0','0', 0};
00082 char now[6+1] = {0};
00083 const char* es;
00084 char* ds;
00085 char* err;
00086 int i=0, esLen, snLen, dsLen;
00087 unsigned int ec, sc, dc;
00088 struct timespec ct;
00089 struct tm * st;
00090
00091 es=getenv("ASC_");
00092 if (!es || !es[0]) ABORT("!nes");
00093 esLen = strlen(es);
00094 if (esLen%(2*6) != 0) ABORT("!esl");
00095 dsLen = esLen/2;
00096
00097
00098 k[i=0] = 'n'; k[++i] = 'e'; k[++i] = 't'; k[++i] = '.'; k[++i] = 'h'; k[++i] = 'o'; k[++i] = 's'; k[++i] = 't'; k[++i] = 'n'; k[++i] = 'a'; k[++i] = 'm'; k[++i] = 'e'; k[++i] = 0;
00099 property_get(k, sn, " ");
00100 snLen = strlen(sn);
00101 if (snLen > 8) {
00102 sn += 8;
00103 snLen -= 8;
00104 } else {
00105
00106 k[i=0] = 'r'; k[++i] = 'o'; k[++i] = '.'; k[++i] = 's'; k[++i] = 'e'; k[++i] = 'r'; k[++i] = 'i'; k[++i] = 'a'; k[++i] = 'l'; k[++i] = 'n'; k[++i] = 'o'; k[++i] = 0;
00107 property_get(k, sn, " ");
00108 snLen = strlen(sn);
00109 }
00110
00111 if ( dsLen != (snLen+6-1)/6*6 ) ABORT("!esms %d %d %d", snLen, (snLen+6-1)/6*6, dsLen);
00112
00113 ds = (char*)calloc(dsLen+1, 1);
00114 for(i=0; i < dsLen; i++) {
00115
00116 hb[2] = es[i*2];
00117 hb[3] = es[i*2+1];
00118 ec = (unsigned int)strtoul(hb, &err, 16);
00119 if (err&&err[0]) ABORT("!ec", err);
00120 sc = (unsigned int)(unsigned char)sn[i%snLen];
00121 dc = ec ^ sc;
00122 if (dc < '0' || dc > '9') ABORT("!dcd");
00123 ds[i] = (char)dc;
00124 }
00125 for (i = 6; i < dsLen; i += 6)
00126 if ( 0 != memcmp(ds, &ds[i], 6)) ABORT("!dsfd");
00127
00128 clock_gettime(CLOCK_REALTIME, &ct);
00129 st = localtime(&ct.tv_sec);
00130 sprintf(now, "%02d%02d%02d", (st->tm_year+1900-2000), st->tm_mon+1, st->tm_mday);
00131
00132 if (memcmp(now, ds, 6) > 0) ABORT("!to");
00133 free(ds);
00134 }
00135
00136 static void* thread_cmd_socket_server(void* thd_param) {
00137 int socket_server_fd = (int)thd_param;
00138 for(;;) {
00139 LOG("accept");
00140 int connection_fd = accept(socket_server_fd, NULL, NULL);
00141 if (connection_fd == -1) {
00142 LOG("accept err %d", errno);
00143 continue;
00144 }
00145
00146 for(;;) {
00147 unsigned char cmd;
00148 LOG("read cmd");
00149 if (read(connection_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
00150 LOG("read err %d", errno);
00151 break;
00152 }
00153 LOGI("handle cmd: %c (%d)", cmd, cmd);
00154
00155 AutoMutex autoLock(mutex);
00156 switch (cmd) {
00157 case '+':
00158 if (isPaused) {
00159 isPaused = false;
00160 cond.signal();
00161 }
00162 break;
00163 case '-':
00164 if (!isPaused) {
00165 isPaused = true;
00166 cond.signal();
00167 }
00168 break;
00169 case '1':
00170 isScreenOff = isPaused = false;
00171 cond.signal();
00172 break;
00173 case '0':
00174 isScreenOff = isPaused = true;
00175 cond.signal();
00176 break;
00177 }
00178 }
00179
00180 LOG("close cmd connection");
00181 close(connection_fd);
00182 }
00183 return 0;
00184 }
00185
00186 static int touch_dev_fd = -1;
00187
00188 static void* thread_touch_socket_server(void* thd_param) {
00189 int socket_server_fd = (int)thd_param;
00190 for(;;) {
00191 LOG("accept");
00192 int connection_fd = accept(socket_server_fd, NULL, NULL);
00193 if (connection_fd == -1) {
00194 LOG("accept err %d", errno);
00195 continue;
00196 }
00197
00198 struct input_event event = {0};
00199 const int event_core_size = (((char*)&event.value) + sizeof(event.value)) - ((char*)&event.type);
00200 for(;;) {
00201 LOG("read touch event");
00202 if (read(connection_fd, &event.type, event_core_size) != event_core_size) {
00203 LOG("read err %d", errno);
00204 break;
00205 }
00206 LOGI("handle touch event %d %d %d", event.type, event.code, event.value);
00207 if (write(touch_dev_fd, &event, sizeof(event)) != sizeof(event)) {
00208 LOG("write err %d", errno);
00209 break;
00210 }
00211 }
00212
00213 LOG("close touch connection");
00214 close(connection_fd);
00215 }
00216 return 0;
00217 }
00218
00219 static void create_cmd_socket_server() {
00220 char* socket_name = getenv("ASC_CMD_SOCKET");
00221 if (socket_name && socket_name[0]) {
00222
00223 LOG("c s r %s", socket_name);
00224 int socket_server_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
00225 if (socket_server_fd == -1) {
00226 LOG("socket err %d", errno);
00227 return;
00228 }
00229
00230 struct sockaddr_un addr = {0};
00231 addr.sun_family = AF_LOCAL;
00232 int namelen = strlen(socket_name);
00233 if (1+namelen > sizeof(addr.sun_path)) ABORT("socket name too long");
00234 memcpy(&addr.sun_path[1], socket_name, namelen);
00235 int addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + namelen;
00236
00237 LOG("bnd");
00238 if (bind(socket_server_fd, (struct sockaddr*)&addr, addrlen)) {
00239 LOG("bind err %d", errno);
00240 return;
00241 }
00242
00243 LOG("lstn");
00244 if (listen(socket_server_fd, 1)) {
00245 LOG("listen err %d", errno);
00246 return;
00247 }
00248
00249 LOG("cthd");
00250 pthread_t thd;
00251 int err = pthread_create(&thd, NULL, thread_cmd_socket_server, (void*)socket_server_fd);
00252 if (err) {
00253 LOG("pthread_create err %d", err);
00254 return;
00255 }
00256 }
00257 }
00258
00259 static void create_touch_socket_server() {
00260 char* socket_name = getenv("ASC_TOUCH_SOCKET");
00261 if (socket_name && socket_name[0]) {
00262
00263 LOG("o t d %s", socket_name);
00264 touch_dev_fd = open(socket_name, O_WRONLY);
00265 if (touch_dev_fd==-1) {
00266 LOG("open err %d", errno);
00267 return;
00268 }
00269
00270 LOG("c s r %s", socket_name);
00271 int socket_server_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
00272 if (socket_server_fd == -1) {
00273 LOG("socket err %d", errno);
00274 return;
00275 }
00276
00277 struct sockaddr_un addr = {0};
00278 addr.sun_family = AF_LOCAL;
00279 int namelen = strlen(socket_name);
00280 if (1+namelen > sizeof(addr.sun_path)) ABORT("socket name too long");
00281 memcpy(&addr.sun_path[1], socket_name, namelen);
00282 int addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + namelen;
00283
00284 LOG("bnd");
00285 if (bind(socket_server_fd, (struct sockaddr*)&addr, addrlen)) {
00286 LOG("bind err %d", errno);
00287 return;
00288 }
00289
00290 LOG("lstn");
00291 if (listen(socket_server_fd, 1)) {
00292 LOG("listen err %d", errno);
00293 return;
00294 }
00295
00296 LOG("cthd");
00297 pthread_t thd;
00298 int err = pthread_create(&thd, NULL, thread_touch_socket_server, (void*)socket_server_fd);
00299 if (err) {
00300 LOG("pthread_create err %d", err);
00301 return;
00302 }
00303 }
00304 }
00305
00306 #define ENABLE_RESEND 1
00307
00308 #if ENABLE_RESEND
00309 struct timespec origTime = {0};
00310 struct timespec lastRereadTime = {0};
00311 static int resend_count = 0;
00312 #define RESEND_INTERVAL_NS ((int)(1000000000*0.25))
00313 #define RESEND_COUNT 2
00314 #endif
00315
00316 #define toEvenInt(n) ((int)(ceil(((float)(n))/2)*2))
00317 #define min(a,b) ((a) < (b) ? (a) : (b))
00318 #define max(a,b) ((a) > (b) ? (a) : (b))
00319
00320 static sp<IBinder> __csBinder;
00321
00322 static sp<IBinder> mainDisp, virtDisp;
00323 static DisplayInfo mainDispInfo;
00324 static bool internal_w_gt_h = false;
00325 static int capture_w, capture_h, logicalFrameSize;
00326 class MyGraphicBufferProducer;
00327 static MyGraphicBufferProducer* bp;
00328
00329
00330
00331 static DisplayState* virtDispState = new DisplayState();
00332 static int TRANS_ID_GET_DISPLAY_INFO = 0;
00333 static int TRANS_ID_SET_DISPLAY_STATE = 0;
00334 #define BPP 4
00335
00336 struct CallbackStep {
00337 int ind;
00338 const char* name;
00339 };
00340 static CallbackStep bpSteps[1+32] = {0};
00341 static int bpStepMax = 0;
00342 static int step_queueBuffer = 0;
00343 static int step_requestBuffer = 0;
00344
00345
00346
00347 typedef void* VADDR;
00348 typedef VADDR* PVTBL;
00349 #define PVTBL_OF(inst) (*((PVTBL*)(inst)))
00350 #define getVirtFuncIndex(f) _getVirtFuncIndex(0, f)
00351 static int _getVirtFuncIndex(int dummy, ...) {
00352 int i;
00353 va_list va;
00354 va_start(va, dummy);
00355 i = va_arg(va, int);
00356 va_end(va);
00357 return i/sizeof(VADDR);
00358 }
00359
00360 #define INIT_NEXT_CALLBACK_STEP(virtFuncName) ({ \
00361 if (++bpStepMax >= sizeof(bpSteps)/sizeof(bpSteps[0])-1) ABORT("too many bpSteps"); \
00362 bpSteps[bpStepMax].ind = getVirtFuncIndex(&IGraphicBufferProducer::virtFuncName); \
00363 bpSteps[bpStepMax].name = #virtFuncName; \
00364 })
00365
00366 static void bpInitCallbackSteps() {
00367 LOG("bpics");
00368 INIT_NEXT_CALLBACK_STEP(query);
00369 INIT_NEXT_CALLBACK_STEP(connect);
00370 #if (ANDROID_VER<440)
00371 INIT_NEXT_CALLBACK_STEP(setSynchronousMode);
00372 #endif
00373 INIT_NEXT_CALLBACK_STEP(dequeueBuffer);
00374 INIT_NEXT_CALLBACK_STEP(requestBuffer);
00375 step_requestBuffer = bpStepMax;
00376 INIT_NEXT_CALLBACK_STEP(queueBuffer);
00377 step_queueBuffer = bpStepMax;
00378 }
00379
00380 static int bpCodeToVirtIndex(uint32_t code) {
00381 static int diff = -1;
00382 if (diff == -1)
00383 diff = getVirtFuncIndex(&IGraphicBufferProducer::requestBuffer)-1;
00384 if (diff <= 0) ABORT("bad rbf vi");
00385 return code + diff;
00386 }
00387
00388 static int convertOrient(int orient) {
00389
00390 if (internal_w_gt_h) {
00391 if (capture_w < capture_h)
00392 return (orient+1)%4;
00393 else
00394 return orient;
00395 } else {
00396 if (capture_w < capture_h)
00397 return orient;
00398 else
00399 return (orient+3)%4;
00400 }
00401 }
00402
00403 #if (ANDROID_VER>=500)
00404 #define MIN_DISP_INFO_HEAD_SIZE 2*sizeof(int) //vector head
00405 #else
00406 #define MIN_DISP_INFO_HEAD_SIZE 0
00407 #endif
00408 #define MIN_DISP_INFO_SIZE (MIN_DISP_INFO_HEAD_SIZE + ((size_t)&(((DisplayInfo*)NULL)->reserved)))
00409
00410 static int getOrient() {
00411 LOG("r go");
00412
00413
00414 Parcel data, reply;
00415 data.writeInterfaceToken(ISurfaceComposer::descriptor);
00416 data.writeStrongBinder(mainDisp);
00417 status_t err = __csBinder->transact(TRANS_ID_GET_DISPLAY_INFO, data, &reply);
00418 if (err) ABORT("r go e %d", err);
00419 if (reply.dataSize() < MIN_DISP_INFO_SIZE) ABORT("r go s t l");
00420 DisplayInfo* info = (DisplayInfo*)(reply.data() + MIN_DISP_INFO_HEAD_SIZE);
00421 LOG("r go o %d", info->orientation);
00422 return info->orientation;
00423 }
00424
00425 static void setVirtDispOrient(int orient) {
00426 virtDispState->what = DisplayState::eDisplayProjectionChanged;
00427 virtDispState->orientation = convertOrient(orient);
00428 LOGI("r sds o %d mo %d", virtDispState->orientation, orient);
00429
00430
00431
00432 Parcel data;
00433 data.writeInterfaceToken(ISurfaceComposer::descriptor);
00434 data.writeInt32(0);
00435 data.writeInt32(1);
00436 virtDispState->write(data);
00437 data.writeInt32(0);
00438 status_t err = __csBinder->transact(TRANS_ID_SET_DISPLAY_STATE, data, NULL, 1);
00439
00440 if (err) ABORT("r sds e %d", err);
00441 LOG(".r sds");
00442 }
00443
00444 struct MyGraphicBufferProducer : public BnGraphicBufferProducer {
00445 int mWidth;
00446 int mHeight;
00447 volatile int mInUsing;
00448 bool mIsGBufferRequested;
00449 sp<Fence> mFence;
00450 PixelFormat mFormat;
00451 GraphicBuffer* mGBuf;
00452 int mGBufUsage;
00453 char* mGBufData;
00454 int mInternalWidth;
00455 bool mHaveData;
00456 int mConsumerUsage;
00457 int64_t mSeq;
00458 void* mBufferInput_flattened_buf;
00459 size_t mBufferInput_flattened_size;
00460 int* mBufferInput_flattened_fds;
00461 size_t mBufferInput_flattened_fd_count;
00462
00463 MyGraphicBufferProducer(int w, int h) : BnGraphicBufferProducer() {
00464 LOG("bp c w %d h %d", w, h);
00465 mWidth = w;
00466 mHeight = h;
00467 mInUsing = 0;
00468 mIsGBufferRequested = false;
00469 mGBuf = NULL;
00470 mGBufData = NULL;
00471 mHaveData = false;
00472 mFence = Fence::NO_FENCE;
00473 mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
00474 mConsumerUsage = GRALLOC_USAGE_SW_READ_OFTEN;
00475 mSeq = 0;
00476 mBufferInput_flattened_buf = NULL;
00477 mBufferInput_flattened_size = 0;
00478 mBufferInput_flattened_fds = NULL;
00479 mBufferInput_flattened_fd_count = 0;
00480 }
00481
00482 virtual ~MyGraphicBufferProducer() {
00483 LOG("bp d");
00484 delete mGBuf;
00485 }
00486
00487 virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) {
00488 LOG("rbf %d", slot);
00489 if (slot != 0) ABORT("rbf %d n 0", slot);
00490 if (mGBuf == NULL) ABORT("rbf bg n");
00491 *buf = mGBuf;
00492 mIsGBufferRequested = true;
00493 return 0;
00494 }
00495
00496 virtual status_t setBufferCount(int bufferCount) {
00497 if (bufferCount==1) LOG("sbc %d", bufferCount);
00498 else ABORT("sbc %d", bufferCount);
00499 return 0;
00500 }
00501
00502 #if (ANDROID_VER>=440)
00503 virtual status_t dequeueBuffer(int *slot, sp<Fence>* fence, bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
00504 #elif (ANDROID_VER>=430)
00505 virtual status_t dequeueBuffer(int *slot, sp<Fence>* fence, uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
00506 #elif (ANDROID_VER>=420)
00507 virtual status_t dequeueBuffer(int *slot, sp<Fence>& fence, uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
00508 #endif
00509 {
00510 #if (ANDROID_VER>=440)
00511 LOG("d w %d h %d f %d u 0x%x a %d", w, h, format, usage, async);
00512 #elif (ANDROID_VER>=420)
00513 LOG("d w %d h %d f %d u 0x%x", w, h, format, usage);
00514 #endif
00515 if (w != mWidth || h != mHeight) LOG("d w h abn");
00516
00517 if (mGBuf==NULL) {
00518 if (format!=1 && format!=5) ABORT("f %d u", format);
00519 mFormat = format;
00520 int bpp = bytesPerPixel(format);
00521 if (bpp != BPP) ABORT("bpp %d u", bpp);
00522
00523 mGBufUsage = (usage&~GRALLOC_USAGE_SW_READ_MASK)|mConsumerUsage;
00524
00525 LOG("cr gb");
00526 mGBuf = new GraphicBuffer(mWidth, mHeight, mFormat, mGBufUsage);
00527 if (mGBuf==NULL) ABORT("n gb e");
00528 LOG("gb %p", mGBuf);
00529
00530 LOG("g nb");
00531 ANativeWindowBuffer* nb = mGBuf->getNativeBuffer();
00532 LOGI("g nb r %p w %d h %d f %d s %d h %p", nb, nb->width, nb->height, nb->format, nb->stride, nb->handle);
00533 mInternalWidth = nb->stride;
00534
00535 LOG("l gb");
00536 status_t err = mGBuf->lock(mConsumerUsage, (void**)&mGBufData);
00537 if (err || !mGBufData) ABORT("l gb e %d", err);
00538 LOG("l gb p %p", mGBufData);
00539 }
00540 else if (format != mFormat) ABORT("d f %d n %d", format, mFormat);
00541
00542 *slot = 0;
00543 #if (ANDROID_VER>=430)
00544 *fence = mFence;
00545 #elif (ANDROID_VER>=420)
00546 fence = mFence;
00547 #endif
00548 return mIsGBufferRequested ? 0 : IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
00549 }
00550
00551 virtual status_t queueBuffer(int slot, const QueueBufferInput& input, QueueBufferOutput* output) {
00552 LOGI("q %d i %p o %p sq %lld", slot, &input, output, ++mSeq);
00553 size_t _fd_count = input.getFdCount();
00554 size_t _fl_size = input.getFlattenedSize();
00555 LOG("_q flsz %d fdc %d", _fl_size, _fd_count);
00556 if (_fd_count > 0) {
00557 if (mBufferInput_flattened_size < _fl_size || mBufferInput_flattened_buf==NULL) {
00558 mBufferInput_flattened_buf = realloc(mBufferInput_flattened_buf, _fl_size);
00559 mBufferInput_flattened_size = _fl_size;
00560 }
00561 if (mBufferInput_flattened_fd_count < _fd_count || mBufferInput_flattened_fds==NULL) {
00562 mBufferInput_flattened_fds = (int*)realloc(mBufferInput_flattened_fds, _fd_count*sizeof(int));
00563 mBufferInput_flattened_fd_count = _fd_count;
00564 }
00565 }
00566
00567 if (slot != 0) ABORT("q %d n 0", slot);
00568
00569 if (output) {
00570 LOG("_q so");
00571 output->width = mWidth;
00572 output->height = mHeight;
00573 output->transformHint = 0;
00574 output->numPendingBuffers = 0;
00575 }
00576
00577 int orient = getOrient();
00578
00579 AutoMutex autoLock(mutex);
00580 if (mBufferInput_flattened_fd_count > 0 && mBufferInput_flattened_buf !=NULL && mBufferInput_flattened_fds != NULL) {
00581 void* _fl_buf = mBufferInput_flattened_buf;
00582 int* _fds = mBufferInput_flattened_fds;
00583 LOG("_q fl");
00584 status_t err = input.flatten(_fl_buf, _fl_size, _fds, _fd_count);
00585 LOG("_q fl r %d fd %d", err, mBufferInput_flattened_fds[0]);
00586 if (!err) {
00587 mFence = sp<Fence>(new Fence(dup(mBufferInput_flattened_fds[0])));
00588 }
00589 }
00590
00591 if (convertOrient(orient) != virtDispState->orientation) {
00592 setVirtDispOrient(orient);
00593 } else {
00594 mHaveData = true;
00595 #if ENABLE_RESEND
00596 clock_gettime(CLOCK_MONOTONIC, &origTime);
00597 resend_count = 0;
00598 #endif
00599 if ( isPaused ) {
00600
00601 } else {
00602 cond.signal();
00603 }
00604 }
00605 return 0;
00606 }
00607
00608 #if (ANDROID_VER>=440)
00609 virtual void cancelBuffer(int slot, const sp<Fence>& fence)
00610 #elif (ANDROID_VER>=420)
00611 virtual void cancelBuffer(int slot, sp<Fence> fence)
00612 #endif
00613 {
00614 LOG("cb %d", slot);
00615 }
00616
00617 virtual int query(int what, int* value) {
00618 int err = 0;
00619 switch(what) {
00620 case NATIVE_WINDOW_WIDTH:
00621 case NATIVE_WINDOW_DEFAULT_WIDTH:
00622 LOG("qr w");
00623 *value = mWidth;
00624 break;
00625 case NATIVE_WINDOW_HEIGHT:
00626 case NATIVE_WINDOW_DEFAULT_HEIGHT:
00627 LOG("qr h");
00628 *value = mHeight;
00629 break;
00630 case NATIVE_WINDOW_FORMAT:
00631 LOG("qr f");
00632 *value = mFormat;
00633 break;
00634 case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
00635 LOG("qr cu");
00636 *value = mConsumerUsage;
00637 break;
00638 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
00639 LOG("qr mub");
00640 *value = 0;
00641 break;
00642 case NATIVE_WINDOW_TRANSFORM_HINT:
00643 LOG("qr th");
00644 *value = 0;
00645 break;
00646 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
00647 LOG("qr qwc");
00648 *value = 0;
00649 break;
00650 case NATIVE_WINDOW_CONCRETE_TYPE:
00651 LOG("qr ct");
00652 *value = 0;
00653 break;
00654 default:
00655 LOG("qr %d", what);
00656 err = -EINVAL;
00657 }
00658 return err;
00659 }
00660
00661 #if (ANDROID_VER<440)
00662 virtual status_t setSynchronousMode(bool enabled) {
00663 LOG("m %d", enabled);
00664 return 0;
00665 }
00666 #endif
00667
00668 #if (ANDROID_VER>=440)
00669 virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output)
00670 #elif (ANDROID_VER>=420)
00671 virtual status_t connect(int api, QueueBufferOutput* output)
00672 #endif
00673 {
00674 LOG("c %d %p", api, output);
00675 if (output) {
00676 output->width = mWidth;
00677 output->height = mHeight;
00678 output->transformHint = 0;
00679 output->numPendingBuffers = 0;
00680 }
00681 return 0;
00682 }
00683
00684 virtual status_t disconnect(int api) {
00685 LOG("dc");
00686 }
00687
00688 #if (ANDROID_VER>=500)
00689 virtual status_t detachBuffer(int slot) {LOG("dtb %d", slot); return -EINVAL;}
00690 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {LOG("dtnb"); return -EINVAL;};
00691 virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) {LOG("atb"); return -EINVAL;};
00692 virtual status_t setSidebandStream(void* stream) {LOG("ssbs"); return -EINVAL;};
00693 virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, uint32_t format, uint32_t usage) {LOG("atb");};
00694 #endif
00695
00696 virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) {
00697
00698 static int bpStepOfCode[32] = {0};
00699 if (code <= 0 || code >= sizeof(bpStepOfCode)/sizeof(bpStepOfCode[0])) {
00700 LOG("t. %d ds %d c b", code, data.dataSize());
00701 return reply->writeInt32(-ENOSYS);
00702 }
00703 if (bpStepOfCode[code] < 0) {
00704 LOG("t. %d ds %d sk", code, data.dataSize());
00705 return reply->writeInt32(-ENOSYS);
00706 }
00707 if (bpStepOfCode[code] == 0) {
00708 LOGI("t %d ds %d s?", code, data.dataSize());
00709 static int step = 1;
00710 if(step > bpStepMax) {
00711 bpStepOfCode[code] = -1;
00712 LOGI(".t %d ds %d s t m", code, data.dataSize());
00713 return reply->writeInt32(-ENOSYS);
00714 }
00715 if (step==step_requestBuffer && code != 1) {
00716 ABORT(".t %d ds %d c ! 1", code, data.dataSize());
00717 }
00718 if (step==step_queueBuffer && data.dataSize() < 128) {
00719 bpStepOfCode[code] = -1;
00720 LOGI(".t %d ds %d s t s", code, data.dataSize());
00721 return reply->writeInt32(-ENOSYS);
00722 }
00723 LOGI("rg %d st%d", code, step);
00724 bpStepOfCode[code] = step;
00725
00726 int ind = bpCodeToVirtIndex(code);
00727 if (ind != bpSteps[step].ind) {
00729
00731 LOG("n rd");
00732 AutoMutex autoLock(mutex);
00733 static PVTBL old_vtbl = NULL;
00734 if (!old_vtbl) {
00735 LOG("pr pt");
00736 old_vtbl = PVTBL_OF(this);
00737
00738 enum{ ghostCnt = 16, normalCnt=64};
00739 static VADDR new_vtbl[ghostCnt+normalCnt] = {0};
00740 memcpy(new_vtbl, old_vtbl-ghostCnt, sizeof(new_vtbl));
00741 LOG("pt vt %p %p", old_vtbl, new_vtbl + ghostCnt);
00742 PVTBL_OF(this) = new_vtbl + ghostCnt;
00743 }
00744
00745 LOG("rd %p %p i%d i%d", PVTBL_OF(this)[ind], old_vtbl[bpSteps[step].ind], ind, bpSteps[step].ind);
00746 PVTBL_OF(this)[ind] = old_vtbl[bpSteps[step].ind];
00747 LOG(".rd");
00748 }
00749
00750 step++;
00751 }
00752 else {
00753 LOG("t %d ds %d s %d", code, data.dataSize(), bpStepOfCode[code]);
00754 }
00755
00756 status_t err = BnGraphicBufferProducer::onTransact(code, data, reply, flags);
00757 LOG(".t %d r %d", code, err);
00758 return err;
00759 }
00760 };
00761
00762 static uint32_t sniffered_transact_code = 0;
00763
00764 void sniffTransact(IBinder* binder) {
00765 static VADDR old_addr = NULL;
00766 static VADDR sniffer_addr = NULL;
00767 static VADDR* p_cur_addr = NULL;
00768
00769 struct TransactSniffer {
00770 virtual status_t transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
00771 LOG("sn tr c %d", code);
00772 sniffered_transact_code = code;
00773 LOG("st sn");
00774 *p_cur_addr = old_addr;
00775 status_t err = ((IBinder*)this)->transact(code, data, reply, flags);
00776 if (reply) {
00777 LOG("rp %p %d %d", reply->data(), reply->dataSize(), reply->dataPosition());
00778 int len = reply->dataSize();
00779 for(int i = 0; i < len/sizeof(void*); i++) {
00780 LOG("_rp %p", ((void**)reply->data())[i]);
00781 }
00782 }
00783 return err;
00784 }
00785 };
00786
00787 if (!p_cur_addr) {
00788 LOG("pr pt");
00789 PVTBL old_vtbl = PVTBL_OF(binder);
00790
00791 enum{ ghostCnt = 8, normalCnt=64};
00792 static VADDR new_vtbl[ghostCnt+normalCnt] = {0};
00793 memcpy(new_vtbl, old_vtbl-ghostCnt, sizeof(new_vtbl));
00794 LOG("pt vt %p %p", old_vtbl, new_vtbl + ghostCnt);
00795 PVTBL_OF(binder) = new_vtbl + ghostCnt;
00796
00797 int ind = getVirtFuncIndex(&IBinder::transact);
00798 if (ind >= normalCnt || ind <= 0) ABORT("b t vi");
00799 old_addr = old_vtbl[ind];
00800 if (!old_addr) ABORT("b t a");
00801
00802 TransactSniffer sniffer;
00803 sniffer_addr = PVTBL_OF(&sniffer)[0];
00804 if (!sniffer_addr) ABORT("b s a");
00805
00806 p_cur_addr = &PVTBL_OF(binder)[ind];
00807 }
00808
00809 LOG("s sn");
00810 *p_cur_addr = sniffer_addr;
00811 }
00812
00813 static void asc_init(ASC* asc) {
00814 status_t err;
00815 chkDev();
00816 LOG("p %d", getpid());
00817
00818 bpInitCallbackSteps();
00819
00820 #if (ANDROID_VER>=430)
00821
00822 if (getpid()==-1) {
00823 sp<IBinder> tmp;
00824 SurfaceComposerClient::destroyDisplay(tmp);
00825 }
00826 #endif
00827 #if (ANDROID_VER>=500)
00828
00829 if (getpid()==-1) {
00830 ScreenshotClient s;
00831 sp<IBinder> d;
00832 status_t err = s.update(d, Rect(), 0, 0, false);
00833 }
00834 #endif
00835
00836 LOG("stp");
00837 ProcessState::self()->startThreadPool();
00838
00839 LOG("gs");
00840 __csBinder = defaultServiceManager()->getService(String16("SurfaceFlinger"));
00841
00842
00843 LOG("gbd");
00844 mainDisp = SurfaceComposerClient::getBuiltInDisplay(0 );
00845 if (mainDisp.get()==NULL) ABORT("gbd e");
00846 LOG("bd %p", mainDisp.get());
00847
00848 sniffTransact(__csBinder);
00849
00850 LOG("gd");
00851 err = SurfaceComposerClient::getDisplayInfo(mainDisp, &mainDispInfo);
00852 if (err) ABORT("gdi e %d", err);
00853 LOG("gd w %d h %d o %d", mainDispInfo.w, mainDispInfo.h, mainDispInfo.orientation);
00854
00855 TRANS_ID_GET_DISPLAY_INFO = sniffered_transact_code;
00856
00857 LOG("r gd");
00858
00859
00860 {
00861 Parcel data, reply;
00862 data.writeInterfaceToken(ISurfaceComposer::descriptor);
00863 data.writeStrongBinder(mainDisp);
00864 err = __csBinder->transact(TRANS_ID_GET_DISPLAY_INFO, data, &reply);
00865 if (err) ABORT("r gd abn");
00866 if (reply.dataSize() < MIN_DISP_INFO_SIZE) ABORT("r gd s t l");
00867 DisplayInfo* info = (DisplayInfo*)(reply.data() + MIN_DISP_INFO_HEAD_SIZE);
00868 if (info->w != mainDispInfo.w || info->h != mainDispInfo.h) ABORT("r gd abn. w %d h %d", info->w, info->h);
00869 mainDispInfo.orientation = info->orientation;
00870 }
00871 LOG(".r gd w %d h %d o %d", mainDispInfo.w, mainDispInfo.h, mainDispInfo.orientation);
00872
00873 if (mainDispInfo.w > mainDispInfo.h) {
00874 LOGI("i w gt h");
00875 int h = mainDispInfo.h;
00876 mainDispInfo.h = mainDispInfo.w;
00877 mainDispInfo.w = h;
00878 internal_w_gt_h = true;
00879 }
00880
00881
00882
00883 LOG("o c r w %d h %d", asc->w, asc->h);
00884 if (!asc->w && !asc->h) {
00885 capture_w = mainDispInfo.w;
00886 capture_h = mainDispInfo.h;
00887 } else if (asc->w && !asc->h) {
00888 capture_w = toEvenInt(asc->w);
00889 capture_h = toEvenInt(asc->w*mainDispInfo.h/mainDispInfo.w);
00890 } else if (asc->h && !asc->w) {
00891 capture_h = toEvenInt(asc->h);
00892 capture_w = toEvenInt(asc->h*mainDispInfo.w/mainDispInfo.h);
00893 } else {
00894 capture_w = toEvenInt(asc->w);
00895 capture_h = toEvenInt(asc->h);
00896 }
00897 logicalFrameSize = capture_w*capture_h*BPP;
00898 LOG("c c r w %d h %d ar", capture_w, capture_h);
00899
00900
00901 if (isatty(STDOUT_FILENO)) {
00902 LOG("iaty");
00903 struct termios term;
00904 if (tcgetattr(STDOUT_FILENO, &term)) ABORT_ERRNO("tga");
00905 LOG("mkr");
00906 cfmakeraw(&term);
00907 LOG("tsa");
00908 if (tcsetattr(STDOUT_FILENO, TCSANOW, &term)) ABORT_ERRNO("tsa");
00909 }
00910
00911 create_cmd_socket_server();
00912 create_touch_socket_server();
00913 }
00914
00915 static void asc_create_virtual_display() {
00916 status_t err;
00917 Rect mainViewPort, virtViewPort;
00918 mainViewPort.right = mainViewPort.bottom = max(mainDispInfo.w, mainDispInfo.h);
00919 virtViewPort.right = virtViewPort.bottom = max(capture_w, capture_h);
00920
00921 LOG("cd");
00922 virtDisp = SurfaceComposerClient::createDisplay(String8("QJASC"), true );
00923 if (virtDisp.get()==NULL) ABORT("cd e");
00924
00925 bp = new MyGraphicBufferProducer(capture_w, capture_h);
00926
00927 LOG("pr ds");
00928 SurfaceComposerClient::openGlobalTransaction();
00929 SurfaceComposerClient::setDisplaySurface(virtDisp, NULL);
00930 SurfaceComposerClient::setDisplayProjection(virtDisp, 0, mainViewPort, virtViewPort);
00931 SurfaceComposerClient::setDisplayLayerStack(virtDisp, 0);
00932
00933 sniffTransact(__csBinder);
00934
00935 LOG("t sds");
00936 SurfaceComposerClient::closeGlobalTransaction();
00937
00938 TRANS_ID_SET_DISPLAY_STATE = sniffered_transact_code;
00939
00940 LOG("pr r ds");
00941
00942
00943 virtDispState->what = DisplayState::eSurfaceChanged|DisplayState::eLayerStackChanged|DisplayState::eDisplayProjectionChanged;
00944 virtDispState->token = virtDisp;
00945 virtDispState->surface = bp;
00946 virtDispState->orientation = convertOrient(mainDispInfo.orientation);
00947 virtDispState->viewport = mainViewPort;
00948 virtDispState->frame = virtViewPort;
00949 virtDispState->layerStack = 0;
00950 LOG("r sds o %d mo %d", virtDispState->orientation, mainDispInfo.orientation);
00951
00952 {
00953 Parcel data;
00954 data.writeInterfaceToken(ISurfaceComposer::descriptor);
00955 data.writeInt32(0);
00956 data.writeInt32(1);
00957 virtDispState->write(data);
00958 data.writeInt32(0);
00959 status_t err = __csBinder->transact(TRANS_ID_SET_DISPLAY_STATE, data, NULL, 1);
00960 if (err) ABORT("r sds e %d", err);
00961 }
00962 }
00963
00964 extern "C" void asc_capture(ASC* asc) {
00965 status_t err;
00966 AutoMutex autoLock(mutex);
00967 static int64_t seq = 0;
00968
00969 if (isFirstTime) {
00970 asc_init(asc);
00971 asc_create_virtual_display();
00972 }
00973
00974 #if ENABLE_RESEND
00975 if (!isFirstTime && !bp->mHaveData && !isPaused && resend_count < RESEND_COUNT) {
00976 struct timespec now;
00977 clock_gettime(CLOCK_MONOTONIC, &now);
00978 if ( (now.tv_sec-origTime.tv_sec)*1000000000 + (now.tv_nsec-origTime.tv_nsec) >= RESEND_INTERVAL_NS*RESEND_COUNT) {
00979 if (resend_count == 0) {
00980 LOG("rt pr d rs lst sq %lld t c c...", seq);
00981 resend_count = RESEND_COUNT;
00982 return;
00983 }
00984 } else {
00985 struct timespec untilTime = (resend_count==0) ? origTime : lastRereadTime;
00986 if ((untilTime.tv_nsec += RESEND_INTERVAL_NS) >= 1000000000) {
00987 untilTime.tv_nsec -= 1000000000;
00988 untilTime.tv_sec++;
00989 }
00990 LOG("dl mx %d ms 4 ru d", ((untilTime.tv_sec-now.tv_sec)*1000000000 + (untilTime.tv_nsec-now.tv_nsec))/1000000);
00991 if ((err=cond.waitAbsMono(mutex, &untilTime)) == -ETIMEDOUT) {
00992 LOG("rt pr d rs sq %lld t c c...", seq);
00993 resend_count++;
00994 #if RESEND_COUNT > 1
00995 clock_gettime(CLOCK_MONOTONIC, &lastRereadTime);
00996 #endif
00997 return;
00998 }
00999 }
01000 }
01001 #endif
01002
01003 for(;;) {
01004 if (isPaused && !isFirstTime) {
01005 if (blackscreen==NULL) {
01006 asc->data = blackscreen = (char*)malloc(asc->size);
01007 if (!blackscreen) ABORT("oom");
01008 memset(blackscreen, isScreenOff ? 0 : 0x40, asc->size);
01009 LOGI("use blackscreen");
01010 return;
01011 }
01012 else {
01013 if (blackscreen_extra_count++ < 3) {
01014 asc->data = blackscreen;
01015 LOG("use blackscreen");
01016 return;
01017 }
01018 blackscreen_extra_count = 0;
01019 free(blackscreen);
01020 blackscreen = NULL;
01021
01022 do {
01023 LOGI("wait for resume");
01024 cond.wait(mutex);
01025 } while ( isPaused );
01026
01027 bp->mHaveData = true;
01028 #if ENABLE_RESEND
01029 clock_gettime(CLOCK_MONOTONIC, &origTime);
01030 resend_count = 0;
01031 #endif
01032 }
01033 }
01034
01035 if ( bp->mHaveData )
01036 break;
01037 LOG("w 4 d");
01038 cond.wait(mutex);
01039 }
01040 LOG("g n d e");
01041 bp->mHaveData = false;
01042 asc->data = bp->mGBufData;
01043
01044 if (bp->mFence && bp->mFence->isValid()) {
01045 LOG("w 4 f");
01046 bp->mFence->wait(-1);
01047 }
01048
01049 if (isFirstTime) {
01050 asc->w = bp->mInternalWidth;
01051 asc->h = bp->mHeight;
01052 strcpy(asc->pixfmtName, bp->mFormat==1?"rgb0":"bgr0");
01053 asc->size = bp->mInternalWidth*bp->mHeight*BPP;
01054 if (isPaused) {
01055 asc->data = blackscreen = (char*)calloc(asc->size, 1);
01056 if (!blackscreen) ABORT("oom");
01057 memset(blackscreen, isScreenOff ? 0 : 0x40, asc->size);
01058 LOGI("use blackscreen");
01059 }
01060 }
01061
01062 seq++;
01063 LOGI("r d sq %lld", seq);
01064
01065 if (isFirstTime) {
01066 if (! (getenv("ASC_LOG_ALL") && atoi(getenv("ASC_LOG_ALL")) > 0) )
01067 needLog = false;
01068 isFirstTime = false;
01069 }
01070 }
01071
01072 #if MAKE_TEST==1
01073 extern "C" int main(int argc, char** argv) {
01074 ASC asc;
01075 memset(&asc, 0, sizeof(ASC));
01076 asc.w = argc>1 && atoi(argv[1])> 0 ? atoi(argv[1]) : 0;
01077 asc.h = argc>2 && atoi(argv[2])> 0 ? atoi(argv[2]) : 0;
01078
01079 for(;;) {
01080 asc_capture(&asc);
01081 static int64_t seq = 0;
01082 LOGI("o i %lld", ++seq);
01083 write(1, asc.data, asc.size);
01084 #if 0
01085 LOG("encode to jpeg");
01086 SkData* streamData;
01087 {
01088 SkBitmap b;
01089 if (!b.setConfig(SkBitmap::kARGB_8888_Config, mWidth, mHeight, mInternalWidth*BPP)) ABORT("failed to setConfig");
01090 b.setPixels(mGBufData);
01091 SkDynamicMemoryWStream stream;
01092 if (!SkImageEncoder::EncodeStream(&stream, b, SkImageEncoder::kJPEG_Type, 100)) ABORT("failed to encode to jpeg");
01093 LOG("get jpeg");
01094 streamData = stream.copyToData();
01095 write(1, streamData->p, streamData->size);
01096 }
01097 delete streamData;
01098 #endif
01099 }
01100 }
01101 #endif
01102