blob: 29320e0e7a7864dab22dde45c3059f68d24809c0 [file] [log] [blame]
Chih-Chung Chang799ae612009-11-13 12:49:14 +08001#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 <ui/ISurface.h>
10#include <ui/Camera.h>
11#include <ui/CameraParameters.h>
12#include <ui/GraphicBuffer.h>
13#include <ui/ICamera.h>
14#include <ui/ICameraClient.h>
15#include <ui/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 exit(1);
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 exit(1);
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
180 ICamera *mReleaser;
181};
182
183void MCameraClient::clearStat() {
184 Mutex::Autolock _l(mLock);
185 mNotifyCount.clear();
186 mDataCount.clear();
187 mDataSize.clear();
188}
189
190bool MCameraClient::test(OP op, int v1, int v2) {
191 switch (op) {
192 case EQ: return v1 == v2;
193 case GT: return v1 > v2;
194 case LT: return v1 < v2;
195 case GE: return v1 >= v2;
196 case LE: return v1 <= v2;
197 default: ASSERT(0); break;
198 }
199 return false;
200}
201
202void MCameraClient::assertNotify(int32_t msgType, OP op, int count) {
203 Mutex::Autolock _l(mLock);
204 int v = mNotifyCount.valueFor(msgType);
205 ASSERT(test(op, v, count));
206}
207
208void MCameraClient::assertData(int32_t msgType, OP op, int count) {
209 Mutex::Autolock _l(mLock);
210 int v = mDataCount.valueFor(msgType);
211 ASSERT(test(op, v, count));
212}
213
214void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) {
215 Mutex::Autolock _l(mLock);
216 int v = mDataSize.valueFor(msgType);
217 ASSERT(test(op, v, dataSize));
218}
219
220void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
221 INFO(__func__);
222 Mutex::Autolock _l(mLock);
223 ssize_t i = mNotifyCount.indexOfKey(msgType);
224 if (i < 0) {
225 mNotifyCount.add(msgType, 1);
226 } else {
227 ++mNotifyCount.editValueAt(i);
228 }
229 mCond.signal();
230}
231
232void MCameraClient::dataCallback(int32_t msgType, const sp<IMemory>& data) {
233 INFO(__func__);
234 int dataSize = data->size();
235 INFO("data type = %d, size = %d", msgType, dataSize);
236 Mutex::Autolock _l(mLock);
237 ssize_t i = mDataCount.indexOfKey(msgType);
238 if (i < 0) {
239 mDataCount.add(msgType, 1);
240 mDataSize.add(msgType, dataSize);
241 } else {
242 ++mDataCount.editValueAt(i);
243 mDataSize.editValueAt(i) = dataSize;
244 }
245 mCond.signal();
246
247 if (msgType == CAMERA_MSG_VIDEO_FRAME) {
248 ASSERT(mReleaser != NULL);
249 mReleaser->releaseRecordingFrame(data);
250 }
251}
252
253void MCameraClient::waitNotify(int32_t msgType, OP op, int count) {
254 INFO("waitNotify: %d, %d, %d", msgType, op, count);
255 Mutex::Autolock _l(mLock);
256 while (true) {
257 int v = mNotifyCount.valueFor(msgType);
258 if (test(op, v, count)) {
259 break;
260 }
261 mCond.wait(mLock);
262 }
263}
264
265void MCameraClient::waitData(int32_t msgType, OP op, int count) {
266 INFO("waitData: %d, %d, %d", msgType, op, count);
267 Mutex::Autolock _l(mLock);
268 while (true) {
269 int v = mDataCount.valueFor(msgType);
270 if (test(op, v, count)) {
271 break;
272 }
273 mCond.wait(mLock);
274 }
275}
276
277//
278// A mock Surface
279//
280class MSurface : public BnSurface {
281public:
282 virtual status_t registerBuffers(const BufferHeap& buffers);
283 virtual void postBuffer(ssize_t offset);
284 virtual void unregisterBuffers();
285 virtual sp<OverlayRef> createOverlay(
286 uint32_t w, uint32_t h, int32_t format);
287 virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
288
289 // new functions
290 void clearStat();
291 void waitUntil(int c0, int c1, int c2);
292
293private:
294 // check callback count
295 Condition mCond;
296 Mutex mLock;
297 int registerBuffersCount;
298 int postBufferCount;
299 int unregisterBuffersCount;
300};
301
302status_t MSurface::registerBuffers(const BufferHeap& buffers) {
303 INFO(__func__);
304 Mutex::Autolock _l(mLock);
305 ++registerBuffersCount;
306 mCond.signal();
307 return NO_ERROR;
308}
309
310void MSurface::postBuffer(ssize_t offset) {
311 // INFO(__func__);
312 Mutex::Autolock _l(mLock);
313 ++postBufferCount;
314 mCond.signal();
315}
316
317void MSurface::unregisterBuffers() {
318 INFO(__func__);
319 Mutex::Autolock _l(mLock);
320 ++unregisterBuffersCount;
321 mCond.signal();
322}
323
324sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
325 INFO(__func__);
326 return NULL;
327}
328
329void MSurface::clearStat() {
330 Mutex::Autolock _l(mLock);
331 registerBuffersCount = 0;
332 postBufferCount = 0;
333 unregisterBuffersCount = 0;
334}
335
336void MSurface::waitUntil(int c0, int c1, int c2) {
337 INFO("waitUntil: %d %d %d", c0, c1, c2);
338 Mutex::Autolock _l(mLock);
339 while (true) {
340 if (registerBuffersCount >= c0 &&
341 postBufferCount >= c1 &&
342 unregisterBuffersCount >= c2) {
343 break;
344 }
345 mCond.wait(mLock);
346 }
347}
348
349sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format) {
350 // We don't expect this to be called in current hardware.
351 ASSERT(0);
352 sp<OverlayRef> dummy;
353 return dummy;
354}
355
356//
357// Utilities to use the Holder service
358//
359sp<IHolder> getHolder() {
360 sp<IServiceManager> sm = defaultServiceManager();
361 ASSERT(sm != 0);
362 sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder"));
363 ASSERT(binder != 0);
364 sp<IHolder> holder = interface_cast<IHolder>(binder);
365 ASSERT(holder != 0);
366 return holder;
367}
368
369void putTempObject(sp<IBinder> obj) {
370 INFO(__func__);
371 getHolder()->put(obj);
372}
373
374sp<IBinder> getTempObject() {
375 INFO(__func__);
376 return getHolder()->get();
377}
378
379void clearTempObject() {
380 INFO(__func__);
381 getHolder()->clear();
382}
383
384//
385// Get a Camera Service
386//
387sp<ICameraService> getCameraService() {
388 sp<IServiceManager> sm = defaultServiceManager();
389 ASSERT(sm != 0);
390 sp<IBinder> binder = sm->getService(String16("media.camera"));
391 ASSERT(binder != 0);
392 sp<ICameraService> cs = interface_cast<ICameraService>(binder);
393 ASSERT(cs != 0);
394 return cs;
395}
396
397//
398// Various Connect Tests
399//
400void testConnect() {
401 INFO(__func__);
402 sp<ICameraService> cs = getCameraService();
403 sp<MCameraClient> cc = new MCameraClient();
404 sp<ICamera> c = cs->connect(cc);
405 ASSERT(c != 0);
406 c->disconnect();
407}
408
409void testAllowConnectOnceOnly() {
410 INFO(__func__);
411 sp<ICameraService> cs = getCameraService();
412 // Connect the first client.
413 sp<MCameraClient> cc = new MCameraClient();
414 sp<ICamera> c = cs->connect(cc);
415 ASSERT(c != 0);
416 // Same client -- ok.
417 ASSERT(cs->connect(cc) != 0);
418 // Different client -- not ok.
419 sp<MCameraClient> cc2 = new MCameraClient();
420 ASSERT(cs->connect(cc2) == 0);
421 c->disconnect();
422}
423
424void testReconnectFailed() {
425 INFO(__func__);
426 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
427 sp<MCameraClient> cc2 = new MCameraClient();
428 ASSERT(c->connect(cc2) != NO_ERROR);
429}
430
431void testReconnectSuccess() {
432 INFO(__func__);
433 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
434 sp<MCameraClient> cc = new MCameraClient();
435 ASSERT(c->connect(cc) == NO_ERROR);
436}
437
438void testLockFailed() {
439 INFO(__func__);
440 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
441 ASSERT(c->lock() != NO_ERROR);
442}
443
444void testLockUnlockSuccess() {
445 INFO(__func__);
446 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
447 ASSERT(c->lock() == NO_ERROR);
448 ASSERT(c->unlock() == NO_ERROR);
449}
450
451void testLockSuccess() {
452 INFO(__func__);
453 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
454 ASSERT(c->lock() == NO_ERROR);
455}
456
457//
458// Run the connect tests in another process.
459//
460const char *gExecutable;
461
462struct FunctionTableEntry {
463 const char *name;
464 void (*func)();
465};
466
467FunctionTableEntry function_table[] = {
468#define ENTRY(x) {#x, &x}
469 ENTRY(testReconnectFailed),
470 ENTRY(testReconnectSuccess),
471 ENTRY(testLockUnlockSuccess),
472 ENTRY(testLockFailed),
473 ENTRY(testLockSuccess),
474#undef ENTRY
475};
476
477void runFunction(const char *tag) {
478 INFO("runFunction: %s", tag);
479 int entries = sizeof(function_table) / sizeof(function_table[0]);
480 for (int i = 0; i < entries; i++) {
481 if (strcmp(function_table[i].name, tag) == 0) {
482 (*function_table[i].func)();
483 return;
484 }
485 }
486 ASSERT(0);
487}
488
489void runInAnotherProcess(const char *tag) {
490 pid_t pid = fork();
491 if (pid == 0) {
492 execlp(gExecutable, gExecutable, tag, NULL);
493 ASSERT(0);
494 } else {
495 int status;
496 ASSERT_EQ(pid, wait(&status));
497 ASSERT_EQ(0, status);
498 }
499}
500
501void testReconnect() {
502 INFO(__func__);
503 sp<ICameraService> cs = getCameraService();
504 sp<MCameraClient> cc = new MCameraClient();
505 sp<ICamera> c = cs->connect(cc);
506 ASSERT(c != 0);
507 // Reconnect to the same client -- ok.
508 ASSERT(c->connect(cc) == NO_ERROR);
509 // Reconnect to a different client (but the same pid) -- ok.
510 sp<MCameraClient> cc2 = new MCameraClient();
511 ASSERT(c->connect(cc2) == NO_ERROR);
512 c->disconnect();
513 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
514}
515
516void testLockUnlock() {
517 sp<ICameraService> cs = getCameraService();
518 sp<MCameraClient> cc = new MCameraClient();
519 sp<ICamera> c = cs->connect(cc);
520 ASSERT(c != 0);
521 // We can lock as many times as we want.
522 ASSERT(c->lock() == NO_ERROR);
523 ASSERT(c->lock() == NO_ERROR);
524 // Lock from a different process -- not ok.
525 putTempObject(c->asBinder());
526 runInAnotherProcess("testLockFailed");
527 // Unlock then lock from a different process -- ok.
528 ASSERT(c->unlock() == NO_ERROR);
529 runInAnotherProcess("testLockUnlockSuccess");
530 // Unlock then lock from a different process -- ok.
531 runInAnotherProcess("testLockSuccess");
532 c->disconnect();
533 clearTempObject();
534}
535
536void testReconnectFromAnotherProcess() {
537 INFO(__func__);
538
539 sp<ICameraService> cs = getCameraService();
540 sp<MCameraClient> cc = new MCameraClient();
541 sp<ICamera> c = cs->connect(cc);
542 ASSERT(c != 0);
543 // Reconnect from a different process -- not ok.
544 putTempObject(c->asBinder());
545 runInAnotherProcess("testReconnectFailed");
546 // Unlock then reconnect from a different process -- ok.
547 ASSERT(c->unlock() == NO_ERROR);
548 runInAnotherProcess("testReconnectSuccess");
549 c->disconnect();
550 clearTempObject();
551}
552
553// We need to flush the command buffer after the reference
554// to ICamera is gone. The sleep is for the server to run
555// the destructor for it.
556static void flushCommands() {
557 IPCThreadState::self()->flushCommands();
558 usleep(200000); // 200ms
559}
560
561// Run a test case
562#define RUN(class_name) do { \
563 { \
564 INFO(#class_name); \
565 class_name instance; \
566 instance.run(); \
567 } \
568 flushCommands(); \
569} while(0)
570
571// Base test case after the the camera is connected.
572class AfterConnect {
573protected:
574 sp<ICameraService> cs;
575 sp<MCameraClient> cc;
576 sp<ICamera> c;
577
578 AfterConnect() {
579 cs = getCameraService();
580 cc = new MCameraClient();
581 c = cs->connect(cc);
582 ASSERT(c != 0);
583 }
584
585 ~AfterConnect() {
586 c.clear();
587 cc.clear();
588 cs.clear();
589 }
590};
591
592class TestSetPreviewDisplay : public AfterConnect {
593public:
594 void run() {
595 sp<MSurface> surface = new MSurface();
596 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
597 c->disconnect();
598 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
599 }
600};
601
602class TestStartPreview : public AfterConnect {
603public:
604 void run() {
605 sp<MSurface> surface = new MSurface();
606 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
607
608 ASSERT(c->startPreview() == NO_ERROR);
609 ASSERT(c->previewEnabled() == true);
610
611 surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer
612 surface->clearStat();
613
614 c->disconnect();
615 // TODO: CameraService crashes for this. Fix it.
616#if 0
617 sp<MSurface> another_surface = new MSurface();
618 c->setPreviewDisplay(another_surface); // just to make sure unregisterBuffers
619 // is called.
620 surface->waitUntil(0, 0, 1); // needs unregisterBuffers
621#endif
622 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
623 }
624};
625
626class TestStartPreviewWithoutDisplay : AfterConnect {
627public:
628 void run() {
629 ASSERT(c->startPreview() == NO_ERROR);
630 ASSERT(c->previewEnabled() == true);
631 c->disconnect();
632 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
633 }
634};
635
636// Base test case after the the camera is connected and the preview is started.
637class AfterStartPreview : public AfterConnect {
638protected:
639 sp<MSurface> surface;
640
641 AfterStartPreview() {
642 surface = new MSurface();
643 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
644 ASSERT(c->startPreview() == NO_ERROR);
645 }
646
647 ~AfterStartPreview() {
648 surface.clear();
649 }
650};
651
652class TestAutoFocus : public AfterStartPreview {
653public:
654 void run() {
655 cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0);
656 c->autoFocus();
657 cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1);
658 c->disconnect();
659 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
660 }
661};
662
663class TestStopPreview : public AfterStartPreview {
664public:
665 void run() {
666 ASSERT(c->previewEnabled() == true);
667 c->stopPreview();
668 ASSERT(c->previewEnabled() == false);
669 c->disconnect();
670 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
671 }
672};
673
674class TestTakePicture: public AfterStartPreview {
675public:
676 void run() {
677 ASSERT(c->takePicture() == NO_ERROR);
678 cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
679 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
680 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
681 c->stopPreview();
682#if 1 // TODO: It crashes if we don't have this. Fix it.
683 usleep(100000);
684#endif
685 c->disconnect();
686 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
687 }
688};
689
690class TestTakeMultiplePictures: public AfterStartPreview {
691public:
692 void run() {
693 for (int i = 0; i < 10; i++) {
694 cc->clearStat();
695 ASSERT(c->takePicture() == NO_ERROR);
696 cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
697 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
698 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
699 usleep(100000); // 100ms
700 }
701 c->disconnect();
702 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
703 }
704};
705
706class TestGetParameters: public AfterStartPreview {
707public:
708 void run() {
709 String8 param_str = c->getParameters();
710 INFO(param_str);
711 }
712};
713
714class TestPictureSize : public AfterStartPreview {
715public:
716 void checkOnePicture(int w, int h) {
717 const float rate = 0.5; // byte per pixel limit
718 int pixels = w * h;
719
720 CameraParameters param(c->getParameters());
721 param.setPictureSize(w, h);
722 c->setParameters(param.flatten());
723
724 cc->clearStat();
725 ASSERT(c->takePicture() == NO_ERROR);
726 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
727 cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2);
728 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
729 cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT,
730 int(pixels * rate));
731 cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0);
732 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
733 usleep(100000); // 100ms
734 }
735
736 void run() {
737 checkOnePicture(2048, 1536);
738 checkOnePicture(1600, 1200);
739 checkOnePicture(1024, 768);
740 }
741};
742
743class TestPreviewCallbackFlag : public AfterConnect {
744public:
745 void run() {
746 sp<MSurface> surface = new MSurface();
747 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
748
749 // Try all flag combinations.
750 for (int v = 0; v < 8; v++) {
751 cc->clearStat();
752 c->setPreviewCallbackFlag(v);
753 ASSERT(c->previewEnabled() == false);
754 ASSERT(c->startPreview() == NO_ERROR);
755 ASSERT(c->previewEnabled() == true);
756 sleep(2);
757 c->stopPreview();
758 if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
759 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
760 } else {
761 if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
762 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
763 } else {
764 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
765 }
766 }
767 }
768 }
769};
770
771class TestRecording : public AfterConnect {
772public:
773 void run() {
774 ASSERT(c->recordingEnabled() == false);
775 sp<MSurface> surface = new MSurface();
776 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
777 c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
778 cc->setReleaser(c.get());
779 c->startRecording();
780 ASSERT(c->recordingEnabled() == true);
781 sleep(2);
782 c->stopRecording();
783 cc->setReleaser(NULL);
784 cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10);
785 }
786};
787
788class TestPreviewSize : public AfterStartPreview {
789public:
790 void checkOnePicture(int w, int h) {
791 int size = w*h*3/2; // should read from parameters
792
793 c->stopPreview();
794
795 CameraParameters param(c->getParameters());
796 param.setPreviewSize(w, h);
797 c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
798 c->setParameters(param.flatten());
799
800 c->startPreview();
801
802 cc->clearStat();
803 cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1);
804 cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size);
805 }
806
807 void run() {
808 checkOnePicture(480, 320);
809 checkOnePicture(352, 288);
810 checkOnePicture(176, 144);
811 }
812};
813
814void runHolderService() {
815 defaultServiceManager()->addService(
816 String16("CameraServiceTest.Holder"), new HolderService());
817 ProcessState::self()->startThreadPool();
818}
819
820int main(int argc, char **argv)
821{
822 if (argc != 1) {
823 runFunction(argv[1]);
824 return 0;
825 }
826 INFO("CameraServiceTest start");
827 gExecutable = argv[0];
828 runHolderService();
829
830 testConnect(); flushCommands();
831 testAllowConnectOnceOnly(); flushCommands();
832 testReconnect(); flushCommands();
833 testLockUnlock(); flushCommands();
834 testReconnectFromAnotherProcess(); flushCommands();
835
836 RUN(TestSetPreviewDisplay);
837 RUN(TestStartPreview);
838 RUN(TestStartPreviewWithoutDisplay);
839 RUN(TestAutoFocus);
840 RUN(TestStopPreview);
841 RUN(TestTakePicture);
842 RUN(TestTakeMultiplePictures);
843 RUN(TestGetParameters);
844 RUN(TestPictureSize);
845 RUN(TestPreviewCallbackFlag);
846 RUN(TestRecording);
847 RUN(TestPreviewSize);
848}