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