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