1#define LOG_TAG "CameraServiceTest" 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <sys/types.h> 7#include <sys/wait.h> 8#include <unistd.h> 9#include <surfaceflinger/ISurface.h> 10#include <camera/Camera.h> 11#include <camera/CameraParameters.h> 12#include <ui/GraphicBuffer.h> 13#include <camera/ICamera.h> 14#include <camera/ICameraClient.h> 15#include <camera/ICameraService.h> 16#include <ui/Overlay.h> 17#include <binder/IPCThreadState.h> 18#include <binder/IServiceManager.h> 19#include <binder/ProcessState.h> 20#include <utils/KeyedVector.h> 21#include <utils/Log.h> 22#include <utils/Vector.h> 23#include <utils/threads.h> 24 25using namespace android; 26 27// 28// Assertion and Logging utilities 29// 30#define INFO(...) \ 31 do { \ 32 printf(__VA_ARGS__); \ 33 printf("\n"); \ 34 LOGD(__VA_ARGS__); \ 35 } while(0) 36 37void assert_fail(const char *file, int line, const char *func, const char *expr) { 38 INFO("assertion failed at file %s, line %d, function %s:", 39 file, line, func); 40 INFO("%s", expr); 41 abort(); 42} 43 44void assert_eq_fail(const char *file, int line, const char *func, 45 const char *expr, int actual) { 46 INFO("assertion failed at file %s, line %d, function %s:", 47 file, line, func); 48 INFO("(expected) %s != (actual) %d", expr, actual); 49 abort(); 50} 51 52#define ASSERT(e) \ 53 do { \ 54 if (!(e)) \ 55 assert_fail(__FILE__, __LINE__, __func__, #e); \ 56 } while(0) 57 58#define ASSERT_EQ(expected, actual) \ 59 do { \ 60 int _x = (actual); \ 61 if (_x != (expected)) \ 62 assert_eq_fail(__FILE__, __LINE__, __func__, #expected, _x); \ 63 } while(0) 64 65// 66// Holder service for pass objects between processes. 67// 68class IHolder : public IInterface { 69protected: 70 enum { 71 HOLDER_PUT = IBinder::FIRST_CALL_TRANSACTION, 72 HOLDER_GET, 73 HOLDER_CLEAR 74 }; 75public: 76 DECLARE_META_INTERFACE(Holder); 77 78 virtual void put(sp<IBinder> obj) = 0; 79 virtual sp<IBinder> get() = 0; 80 virtual void clear() = 0; 81}; 82 83class BnHolder : public BnInterface<IHolder> { 84 virtual status_t onTransact(uint32_t code, 85 const Parcel& data, 86 Parcel* reply, 87 uint32_t flags = 0); 88}; 89 90class BpHolder : public BpInterface<IHolder> { 91public: 92 BpHolder(const sp<IBinder>& impl) 93 : BpInterface<IHolder>(impl) { 94 } 95 96 virtual void put(sp<IBinder> obj) { 97 Parcel data, reply; 98 data.writeStrongBinder(obj); 99 remote()->transact(HOLDER_PUT, data, &reply, IBinder::FLAG_ONEWAY); 100 } 101 102 virtual sp<IBinder> get() { 103 Parcel data, reply; 104 remote()->transact(HOLDER_GET, data, &reply); 105 return reply.readStrongBinder(); 106 } 107 108 virtual void clear() { 109 Parcel data, reply; 110 remote()->transact(HOLDER_CLEAR, data, &reply); 111 } 112}; 113 114IMPLEMENT_META_INTERFACE(Holder, "CameraServiceTest.Holder"); 115 116status_t BnHolder::onTransact( 117 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 118 switch(code) { 119 case HOLDER_PUT: { 120 put(data.readStrongBinder()); 121 return NO_ERROR; 122 } break; 123 case HOLDER_GET: { 124 reply->writeStrongBinder(get()); 125 return NO_ERROR; 126 } break; 127 case HOLDER_CLEAR: { 128 clear(); 129 return NO_ERROR; 130 } break; 131 default: 132 return BBinder::onTransact(code, data, reply, flags); 133 } 134} 135 136class HolderService : public BnHolder { 137 virtual void put(sp<IBinder> obj) { 138 mObj = obj; 139 } 140 virtual sp<IBinder> get() { 141 return mObj; 142 } 143 virtual void clear() { 144 mObj.clear(); 145 } 146private: 147 sp<IBinder> mObj; 148}; 149 150// 151// A mock CameraClient 152// 153class MCameraClient : public BnCameraClient { 154public: 155 virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2); 156 virtual void dataCallback(int32_t msgType, const sp<IMemory>& data); 157 virtual void dataCallbackTimestamp(nsecs_t timestamp, 158 int32_t msgType, const sp<IMemory>& data); 159 160 // new functions 161 void clearStat(); 162 enum OP { EQ, GE, LE, GT, LT }; 163 void assertNotify(int32_t msgType, OP op, int count); 164 void assertData(int32_t msgType, OP op, int count); 165 void waitNotify(int32_t msgType, OP op, int count); 166 void waitData(int32_t msgType, OP op, int count); 167 void assertDataSize(int32_t msgType, OP op, int dataSize); 168 169 void setReleaser(ICamera *releaser) { 170 mReleaser = releaser; 171 } 172private: 173 Mutex mLock; 174 Condition mCond; 175 DefaultKeyedVector<int32_t, int> mNotifyCount; 176 DefaultKeyedVector<int32_t, int> mDataCount; 177 DefaultKeyedVector<int32_t, int> mDataSize; 178 bool test(OP op, int v1, int v2); 179 void assertTest(OP op, int v1, int v2); 180 181 ICamera *mReleaser; 182}; 183 184void MCameraClient::clearStat() { 185 Mutex::Autolock _l(mLock); 186 mNotifyCount.clear(); 187 mDataCount.clear(); 188 mDataSize.clear(); 189} 190 191bool MCameraClient::test(OP op, int v1, int v2) { 192 switch (op) { 193 case EQ: return v1 == v2; 194 case GT: return v1 > v2; 195 case LT: return v1 < v2; 196 case GE: return v1 >= v2; 197 case LE: return v1 <= v2; 198 default: ASSERT(0); break; 199 } 200 return false; 201} 202 203void MCameraClient::assertTest(OP op, int v1, int v2) { 204 if (!test(op, v1, v2)) { 205 LOGE("assertTest failed: op=%d, v1=%d, v2=%d", op, v1, v2); 206 ASSERT(0); 207 } 208} 209 210void MCameraClient::assertNotify(int32_t msgType, OP op, int count) { 211 Mutex::Autolock _l(mLock); 212 int v = mNotifyCount.valueFor(msgType); 213 assertTest(op, v, count); 214} 215 216void MCameraClient::assertData(int32_t msgType, OP op, int count) { 217 Mutex::Autolock _l(mLock); 218 int v = mDataCount.valueFor(msgType); 219 assertTest(op, v, count); 220} 221 222void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) { 223 Mutex::Autolock _l(mLock); 224 int v = mDataSize.valueFor(msgType); 225 assertTest(op, v, dataSize); 226} 227 228void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { 229 INFO("%s", __func__); 230 Mutex::Autolock _l(mLock); 231 ssize_t i = mNotifyCount.indexOfKey(msgType); 232 if (i < 0) { 233 mNotifyCount.add(msgType, 1); 234 } else { 235 ++mNotifyCount.editValueAt(i); 236 } 237 mCond.signal(); 238} 239 240void MCameraClient::dataCallback(int32_t msgType, const sp<IMemory>& data) { 241 INFO("%s", __func__); 242 int dataSize = data->size(); 243 INFO("data type = %d, size = %d", msgType, dataSize); 244 Mutex::Autolock _l(mLock); 245 ssize_t i = mDataCount.indexOfKey(msgType); 246 if (i < 0) { 247 mDataCount.add(msgType, 1); 248 mDataSize.add(msgType, dataSize); 249 } else { 250 ++mDataCount.editValueAt(i); 251 mDataSize.editValueAt(i) = dataSize; 252 } 253 mCond.signal(); 254 255 if (msgType == CAMERA_MSG_VIDEO_FRAME) { 256 ASSERT(mReleaser != NULL); 257 mReleaser->releaseRecordingFrame(data); 258 } 259} 260 261void MCameraClient::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, 262 const sp<IMemory>& data) { 263 dataCallback(msgType, data); 264} 265 266void MCameraClient::waitNotify(int32_t msgType, OP op, int count) { 267 INFO("waitNotify: %d, %d, %d", msgType, op, count); 268 Mutex::Autolock _l(mLock); 269 while (true) { 270 int v = mNotifyCount.valueFor(msgType); 271 if (test(op, v, count)) { 272 break; 273 } 274 mCond.wait(mLock); 275 } 276} 277 278void MCameraClient::waitData(int32_t msgType, OP op, int count) { 279 INFO("waitData: %d, %d, %d", msgType, op, count); 280 Mutex::Autolock _l(mLock); 281 while (true) { 282 int v = mDataCount.valueFor(msgType); 283 if (test(op, v, count)) { 284 break; 285 } 286 mCond.wait(mLock); 287 } 288} 289 290// 291// A mock Surface 292// 293class MSurface : public BnSurface { 294public: 295 virtual status_t registerBuffers(const BufferHeap& buffers); 296 virtual void postBuffer(ssize_t offset); 297 virtual void unregisterBuffers(); 298 virtual sp<OverlayRef> createOverlay( 299 uint32_t w, uint32_t h, int32_t format, int32_t orientation); 300 virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage); 301 virtual status_t setBufferCount(int bufferCount); 302 303 // new functions 304 void clearStat(); 305 void waitUntil(int c0, int c1, int c2); 306 307private: 308 // check callback count 309 Condition mCond; 310 Mutex mLock; 311 int registerBuffersCount; 312 int postBufferCount; 313 int unregisterBuffersCount; 314}; 315 316status_t MSurface::registerBuffers(const BufferHeap& buffers) { 317 INFO("%s", __func__); 318 Mutex::Autolock _l(mLock); 319 ++registerBuffersCount; 320 mCond.signal(); 321 return NO_ERROR; 322} 323 324void MSurface::postBuffer(ssize_t offset) { 325 // INFO("%s", __func__); 326 Mutex::Autolock _l(mLock); 327 ++postBufferCount; 328 mCond.signal(); 329} 330 331void MSurface::unregisterBuffers() { 332 INFO("%s", __func__); 333 Mutex::Autolock _l(mLock); 334 ++unregisterBuffersCount; 335 mCond.signal(); 336} 337 338sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) { 339 INFO("%s", __func__); 340 return NULL; 341} 342 343status_t MSurface::setBufferCount(int bufferCount) { 344 INFO("%s", __func__); 345 return NULL; 346} 347 348void MSurface::clearStat() { 349 Mutex::Autolock _l(mLock); 350 registerBuffersCount = 0; 351 postBufferCount = 0; 352 unregisterBuffersCount = 0; 353} 354 355void MSurface::waitUntil(int c0, int c1, int c2) { 356 INFO("waitUntil: %d %d %d", c0, c1, c2); 357 Mutex::Autolock _l(mLock); 358 while (true) { 359 if (registerBuffersCount >= c0 && 360 postBufferCount >= c1 && 361 unregisterBuffersCount >= c2) { 362 break; 363 } 364 mCond.wait(mLock); 365 } 366} 367 368sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format, 369 int32_t orientation) { 370 // Not implemented. 371 ASSERT(0); 372 return NULL; 373} 374 375// 376// Utilities to use the Holder service 377// 378sp<IHolder> getHolder() { 379 sp<IServiceManager> sm = defaultServiceManager(); 380 ASSERT(sm != 0); 381 sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder")); 382 ASSERT(binder != 0); 383 sp<IHolder> holder = interface_cast<IHolder>(binder); 384 ASSERT(holder != 0); 385 return holder; 386} 387 388void putTempObject(sp<IBinder> obj) { 389 INFO("%s", __func__); 390 getHolder()->put(obj); 391} 392 393sp<IBinder> getTempObject() { 394 INFO("%s", __func__); 395 return getHolder()->get(); 396} 397 398void clearTempObject() { 399 INFO("%s", __func__); 400 getHolder()->clear(); 401} 402 403// 404// Get a Camera Service 405// 406sp<ICameraService> getCameraService() { 407 sp<IServiceManager> sm = defaultServiceManager(); 408 ASSERT(sm != 0); 409 sp<IBinder> binder = sm->getService(String16("media.camera")); 410 ASSERT(binder != 0); 411 sp<ICameraService> cs = interface_cast<ICameraService>(binder); 412 ASSERT(cs != 0); 413 return cs; 414} 415 416int getNumberOfCameras() { 417 sp<ICameraService> cs = getCameraService(); 418 return cs->getNumberOfCameras(); 419} 420 421// 422// Various Connect Tests 423// 424void testConnect(int cameraId) { 425 INFO("%s", __func__); 426 sp<ICameraService> cs = getCameraService(); 427 sp<MCameraClient> cc = new MCameraClient(); 428 sp<ICamera> c = cs->connect(cc, cameraId); 429 ASSERT(c != 0); 430 c->disconnect(); 431} 432 433void testAllowConnectOnceOnly(int cameraId) { 434 INFO("%s", __func__); 435 sp<ICameraService> cs = getCameraService(); 436 // Connect the first client. 437 sp<MCameraClient> cc = new MCameraClient(); 438 sp<ICamera> c = cs->connect(cc, cameraId); 439 ASSERT(c != 0); 440 // Same client -- ok. 441 ASSERT(cs->connect(cc, cameraId) != 0); 442 // Different client -- not ok. 443 sp<MCameraClient> cc2 = new MCameraClient(); 444 ASSERT(cs->connect(cc2, cameraId) == 0); 445 c->disconnect(); 446} 447 448void testReconnectFailed() { 449 INFO("%s", __func__); 450 sp<ICamera> c = interface_cast<ICamera>(getTempObject()); 451 sp<MCameraClient> cc = new MCameraClient(); 452 ASSERT(c->connect(cc) != NO_ERROR); 453} 454 455void testReconnectSuccess() { 456 INFO("%s", __func__); 457 sp<ICamera> c = interface_cast<ICamera>(getTempObject()); 458 sp<MCameraClient> cc = new MCameraClient(); 459 ASSERT(c->connect(cc) == NO_ERROR); 460 c->disconnect(); 461} 462 463void testLockFailed() { 464 INFO("%s", __func__); 465 sp<ICamera> c = interface_cast<ICamera>(getTempObject()); 466 ASSERT(c->lock() != NO_ERROR); 467} 468 469void testLockUnlockSuccess() { 470 INFO("%s", __func__); 471 sp<ICamera> c = interface_cast<ICamera>(getTempObject()); 472 ASSERT(c->lock() == NO_ERROR); 473 ASSERT(c->unlock() == NO_ERROR); 474} 475 476void testLockSuccess() { 477 INFO("%s", __func__); 478 sp<ICamera> c = interface_cast<ICamera>(getTempObject()); 479 ASSERT(c->lock() == NO_ERROR); 480 c->disconnect(); 481} 482 483// 484// Run the connect tests in another process. 485// 486const char *gExecutable; 487 488struct FunctionTableEntry { 489 const char *name; 490 void (*func)(); 491}; 492 493FunctionTableEntry function_table[] = { 494#define ENTRY(x) {#x, &x} 495 ENTRY(testReconnectFailed), 496 ENTRY(testReconnectSuccess), 497 ENTRY(testLockUnlockSuccess), 498 ENTRY(testLockFailed), 499 ENTRY(testLockSuccess), 500#undef ENTRY 501}; 502 503void runFunction(const char *tag) { 504 INFO("runFunction: %s", tag); 505 int entries = sizeof(function_table) / sizeof(function_table[0]); 506 for (int i = 0; i < entries; i++) { 507 if (strcmp(function_table[i].name, tag) == 0) { 508 (*function_table[i].func)(); 509 return; 510 } 511 } 512 ASSERT(0); 513} 514 515void runInAnotherProcess(const char *tag) { 516 pid_t pid = fork(); 517 if (pid == 0) { 518 execlp(gExecutable, gExecutable, tag, NULL); 519 ASSERT(0); 520 } else { 521 int status; 522 ASSERT_EQ(pid, wait(&status)); 523 ASSERT_EQ(0, status); 524 } 525} 526 527void testReconnect(int cameraId) { 528 INFO("%s", __func__); 529 sp<ICameraService> cs = getCameraService(); 530 sp<MCameraClient> cc = new MCameraClient(); 531 sp<ICamera> c = cs->connect(cc, cameraId); 532 ASSERT(c != 0); 533 // Reconnect to the same client -- ok. 534 ASSERT(c->connect(cc) == NO_ERROR); 535 // Reconnect to a different client (but the same pid) -- ok. 536 sp<MCameraClient> cc2 = new MCameraClient(); 537 ASSERT(c->connect(cc2) == NO_ERROR); 538 c->disconnect(); 539 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 540} 541 542void testLockUnlock(int cameraId) { 543 sp<ICameraService> cs = getCameraService(); 544 sp<MCameraClient> cc = new MCameraClient(); 545 sp<ICamera> c = cs->connect(cc, cameraId); 546 ASSERT(c != 0); 547 // We can lock as many times as we want. 548 ASSERT(c->lock() == NO_ERROR); 549 ASSERT(c->lock() == NO_ERROR); 550 // Lock from a different process -- not ok. 551 putTempObject(c->asBinder()); 552 runInAnotherProcess("testLockFailed"); 553 // Unlock then lock from a different process -- ok. 554 ASSERT(c->unlock() == NO_ERROR); 555 runInAnotherProcess("testLockUnlockSuccess"); 556 // Unlock then lock from a different process -- ok. 557 runInAnotherProcess("testLockSuccess"); 558 clearTempObject(); 559} 560 561void testReconnectFromAnotherProcess(int cameraId) { 562 INFO("%s", __func__); 563 564 sp<ICameraService> cs = getCameraService(); 565 sp<MCameraClient> cc = new MCameraClient(); 566 sp<ICamera> c = cs->connect(cc, cameraId); 567 ASSERT(c != 0); 568 // Reconnect from a different process -- not ok. 569 putTempObject(c->asBinder()); 570 runInAnotherProcess("testReconnectFailed"); 571 // Unlock then reconnect from a different process -- ok. 572 ASSERT(c->unlock() == NO_ERROR); 573 runInAnotherProcess("testReconnectSuccess"); 574 clearTempObject(); 575} 576 577// We need to flush the command buffer after the reference 578// to ICamera is gone. The sleep is for the server to run 579// the destructor for it. 580static void flushCommands() { 581 IPCThreadState::self()->flushCommands(); 582 usleep(200000); // 200ms 583} 584 585// Run a test case 586#define RUN(class_name, cameraId) do { \ 587 { \ 588 INFO(#class_name); \ 589 class_name instance; \ 590 instance.init(cameraId); \ 591 instance.run(); \ 592 } \ 593 flushCommands(); \ 594} while(0) 595 596// Base test case after the the camera is connected. 597class AfterConnect { 598public: 599 void init(int cameraId) { 600 cs = getCameraService(); 601 cc = new MCameraClient(); 602 c = cs->connect(cc, cameraId); 603 ASSERT(c != 0); 604 } 605 606protected: 607 sp<ICameraService> cs; 608 sp<MCameraClient> cc; 609 sp<ICamera> c; 610 611 ~AfterConnect() { 612 c->disconnect(); 613 c.clear(); 614 cc.clear(); 615 cs.clear(); 616 } 617}; 618 619class TestSetPreviewDisplay : public AfterConnect { 620public: 621 void run() { 622 sp<MSurface> surface = new MSurface(); 623 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR); 624 c->disconnect(); 625 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 626 } 627}; 628 629class TestStartPreview : public AfterConnect { 630public: 631 void run() { 632 sp<MSurface> surface = new MSurface(); 633 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR); 634 635 ASSERT(c->startPreview() == NO_ERROR); 636 ASSERT(c->previewEnabled() == true); 637 638 surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer 639 surface->clearStat(); 640 641 sp<MSurface> another_surface = new MSurface(); 642 c->setPreviewDisplay(another_surface); // just to make sure unregisterBuffers 643 // is called. 644 surface->waitUntil(0, 0, 1); // needs unregisterBuffers 645 646 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 647 } 648}; 649 650class TestStartPreviewWithoutDisplay : public AfterConnect { 651public: 652 void run() { 653 ASSERT(c->startPreview() == NO_ERROR); 654 ASSERT(c->previewEnabled() == true); 655 c->disconnect(); 656 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 657 } 658}; 659 660// Base test case after the the camera is connected and the preview is started. 661class AfterStartPreview : public AfterConnect { 662public: 663 void init(int cameraId) { 664 AfterConnect::init(cameraId); 665 surface = new MSurface(); 666 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR); 667 ASSERT(c->startPreview() == NO_ERROR); 668 } 669 670protected: 671 sp<MSurface> surface; 672 673 ~AfterStartPreview() { 674 surface.clear(); 675 } 676}; 677 678class TestAutoFocus : public AfterStartPreview { 679public: 680 void run() { 681 cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0); 682 c->autoFocus(); 683 cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1); 684 c->disconnect(); 685 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 686 } 687}; 688 689class TestStopPreview : public AfterStartPreview { 690public: 691 void run() { 692 ASSERT(c->previewEnabled() == true); 693 c->stopPreview(); 694 ASSERT(c->previewEnabled() == false); 695 c->disconnect(); 696 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 697 } 698}; 699 700class TestTakePicture: public AfterStartPreview { 701public: 702 void run() { 703 ASSERT(c->takePicture() == NO_ERROR); 704 cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1); 705 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1); 706 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1); 707 c->stopPreview(); 708 c->disconnect(); 709 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 710 } 711}; 712 713class TestTakeMultiplePictures: public AfterStartPreview { 714public: 715 void run() { 716 for (int i = 0; i < 10; i++) { 717 cc->clearStat(); 718 ASSERT(c->takePicture() == NO_ERROR); 719 cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1); 720 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1); 721 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1); 722 } 723 c->disconnect(); 724 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 725 } 726}; 727 728class TestGetParameters: public AfterStartPreview { 729public: 730 void run() { 731 String8 param_str = c->getParameters(); 732 INFO("%s", static_cast<const char*>(param_str)); 733 } 734}; 735 736static bool getNextSize(const char **ptrS, int *w, int *h) { 737 const char *s = *ptrS; 738 739 // skip over ',' 740 if (*s == ',') s++; 741 742 // remember start position in p 743 const char *p = s; 744 while (*s != '\0' && *s != 'x') { 745 s++; 746 } 747 if (*s == '\0') return false; 748 749 // get the width 750 *w = atoi(p); 751 752 // skip over 'x' 753 ASSERT(*s == 'x'); 754 p = s + 1; 755 while (*s != '\0' && *s != ',') { 756 s++; 757 } 758 759 // get the height 760 *h = atoi(p); 761 *ptrS = s; 762 return true; 763} 764 765class TestPictureSize : public AfterStartPreview { 766public: 767 void checkOnePicture(int w, int h) { 768 const float rate = 0.9; // byte per pixel limit 769 int pixels = w * h; 770 771 CameraParameters param(c->getParameters()); 772 param.setPictureSize(w, h); 773 // disable thumbnail to get more accurate size. 774 param.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, 0); 775 param.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, 0); 776 c->setParameters(param.flatten()); 777 778 cc->clearStat(); 779 ASSERT(c->takePicture() == NO_ERROR); 780 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1); 781 //cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2); 782 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1); 783 cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT, 784 int(pixels * rate)); 785 cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0); 786 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0); 787 } 788 789 void run() { 790 CameraParameters param(c->getParameters()); 791 int w, h; 792 const char *s = param.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES); 793 while (getNextSize(&s, &w, &h)) { 794 LOGD("checking picture size %dx%d", w, h); 795 checkOnePicture(w, h); 796 } 797 } 798}; 799 800class TestPreviewCallbackFlag : public AfterConnect { 801public: 802 void run() { 803 sp<MSurface> surface = new MSurface(); 804 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR); 805 806 // Try all flag combinations. 807 for (int v = 0; v < 8; v++) { 808 LOGD("TestPreviewCallbackFlag: flag=%d", v); 809 usleep(100000); // sleep a while to clear the in-flight callbacks. 810 cc->clearStat(); 811 c->setPreviewCallbackFlag(v); 812 ASSERT(c->previewEnabled() == false); 813 ASSERT(c->startPreview() == NO_ERROR); 814 ASSERT(c->previewEnabled() == true); 815 sleep(2); 816 c->stopPreview(); 817 if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) { 818 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0); 819 } else { 820 if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) { 821 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10); 822 } else { 823 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1); 824 } 825 } 826 } 827 } 828}; 829 830class TestRecording : public AfterConnect { 831public: 832 void run() { 833 ASSERT(c->recordingEnabled() == false); 834 sp<MSurface> surface = new MSurface(); 835 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR); 836 c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK); 837 cc->setReleaser(c.get()); 838 c->startRecording(); 839 ASSERT(c->recordingEnabled() == true); 840 sleep(2); 841 c->stopRecording(); 842 usleep(100000); // sleep a while to clear the in-flight callbacks. 843 cc->setReleaser(NULL); 844 cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10); 845 } 846}; 847 848class TestPreviewSize : public AfterStartPreview { 849public: 850 void checkOnePicture(int w, int h) { 851 int size = w*h*3/2; // should read from parameters 852 853 c->stopPreview(); 854 855 CameraParameters param(c->getParameters()); 856 param.setPreviewSize(w, h); 857 c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK); 858 c->setParameters(param.flatten()); 859 860 c->startPreview(); 861 862 cc->clearStat(); 863 cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1); 864 cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size); 865 } 866 867 void run() { 868 CameraParameters param(c->getParameters()); 869 int w, h; 870 const char *s = param.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES); 871 while (getNextSize(&s, &w, &h)) { 872 LOGD("checking preview size %dx%d", w, h); 873 checkOnePicture(w, h); 874 } 875 } 876}; 877 878void runHolderService() { 879 defaultServiceManager()->addService( 880 String16("CameraServiceTest.Holder"), new HolderService()); 881 ProcessState::self()->startThreadPool(); 882} 883 884int main(int argc, char **argv) 885{ 886 if (argc != 1) { 887 runFunction(argv[1]); 888 return 0; 889 } 890 INFO("CameraServiceTest start"); 891 gExecutable = argv[0]; 892 runHolderService(); 893 int n = getNumberOfCameras(); 894 INFO("%d Cameras available", n); 895 896 for (int id = 0; id < n; id++) { 897 INFO("Testing camera %d", id); 898 testConnect(id); flushCommands(); 899 testAllowConnectOnceOnly(id); flushCommands(); 900 testReconnect(id); flushCommands(); 901 testLockUnlock(id); flushCommands(); 902 testReconnectFromAnotherProcess(id); flushCommands(); 903 904 RUN(TestSetPreviewDisplay, id); 905 RUN(TestStartPreview, id); 906 RUN(TestStartPreviewWithoutDisplay, id); 907 RUN(TestAutoFocus, id); 908 RUN(TestStopPreview, id); 909 RUN(TestTakePicture, id); 910 RUN(TestTakeMultiplePictures, id); 911 RUN(TestGetParameters, id); 912 RUN(TestPictureSize, id); 913 RUN(TestPreviewCallbackFlag, id); 914 RUN(TestRecording, id); 915 RUN(TestPreviewSize, id); 916 } 917 918 INFO("CameraServiceTest finished"); 919} 920