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