blob: f89d9d3556c7a48a25cbf353d23b8b124dd87586 [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(
Chih-Chung Chang52e72002010-01-21 17:31:06 -0800286 uint32_t w, uint32_t h, int32_t format, int32_t orientation);
Chih-Chung Chang799ae612009-11-13 12:49:14 +0800287 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
Chih-Chung Chang52e72002010-01-21 17:31:06 -0800349sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format,
350 int32_t orientation) {
Chih-Chung Chang799ae612009-11-13 12:49:14 +0800351 // We don't expect this to be called in current hardware.
352 ASSERT(0);
353 sp<OverlayRef> dummy;
354 return dummy;
355}
356
357//
358// Utilities to use the Holder service
359//
360sp<IHolder> getHolder() {
361 sp<IServiceManager> sm = defaultServiceManager();
362 ASSERT(sm != 0);
363 sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder"));
364 ASSERT(binder != 0);
365 sp<IHolder> holder = interface_cast<IHolder>(binder);
366 ASSERT(holder != 0);
367 return holder;
368}
369
370void putTempObject(sp<IBinder> obj) {
371 INFO(__func__);
372 getHolder()->put(obj);
373}
374
375sp<IBinder> getTempObject() {
376 INFO(__func__);
377 return getHolder()->get();
378}
379
380void clearTempObject() {
381 INFO(__func__);
382 getHolder()->clear();
383}
384
385//
386// Get a Camera Service
387//
388sp<ICameraService> getCameraService() {
389 sp<IServiceManager> sm = defaultServiceManager();
390 ASSERT(sm != 0);
391 sp<IBinder> binder = sm->getService(String16("media.camera"));
392 ASSERT(binder != 0);
393 sp<ICameraService> cs = interface_cast<ICameraService>(binder);
394 ASSERT(cs != 0);
395 return cs;
396}
397
398//
399// Various Connect Tests
400//
401void testConnect() {
402 INFO(__func__);
403 sp<ICameraService> cs = getCameraService();
404 sp<MCameraClient> cc = new MCameraClient();
405 sp<ICamera> c = cs->connect(cc);
406 ASSERT(c != 0);
407 c->disconnect();
408}
409
410void testAllowConnectOnceOnly() {
411 INFO(__func__);
412 sp<ICameraService> cs = getCameraService();
413 // Connect the first client.
414 sp<MCameraClient> cc = new MCameraClient();
415 sp<ICamera> c = cs->connect(cc);
416 ASSERT(c != 0);
417 // Same client -- ok.
418 ASSERT(cs->connect(cc) != 0);
419 // Different client -- not ok.
420 sp<MCameraClient> cc2 = new MCameraClient();
421 ASSERT(cs->connect(cc2) == 0);
422 c->disconnect();
423}
424
425void testReconnectFailed() {
426 INFO(__func__);
427 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
428 sp<MCameraClient> cc2 = new MCameraClient();
429 ASSERT(c->connect(cc2) != NO_ERROR);
430}
431
432void testReconnectSuccess() {
433 INFO(__func__);
434 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
435 sp<MCameraClient> cc = new MCameraClient();
436 ASSERT(c->connect(cc) == NO_ERROR);
437}
438
439void testLockFailed() {
440 INFO(__func__);
441 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
442 ASSERT(c->lock() != NO_ERROR);
443}
444
445void testLockUnlockSuccess() {
446 INFO(__func__);
447 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
448 ASSERT(c->lock() == NO_ERROR);
449 ASSERT(c->unlock() == NO_ERROR);
450}
451
452void testLockSuccess() {
453 INFO(__func__);
454 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
455 ASSERT(c->lock() == NO_ERROR);
456}
457
458//
459// Run the connect tests in another process.
460//
461const char *gExecutable;
462
463struct FunctionTableEntry {
464 const char *name;
465 void (*func)();
466};
467
468FunctionTableEntry function_table[] = {
469#define ENTRY(x) {#x, &x}
470 ENTRY(testReconnectFailed),
471 ENTRY(testReconnectSuccess),
472 ENTRY(testLockUnlockSuccess),
473 ENTRY(testLockFailed),
474 ENTRY(testLockSuccess),
475#undef ENTRY
476};
477
478void runFunction(const char *tag) {
479 INFO("runFunction: %s", tag);
480 int entries = sizeof(function_table) / sizeof(function_table[0]);
481 for (int i = 0; i < entries; i++) {
482 if (strcmp(function_table[i].name, tag) == 0) {
483 (*function_table[i].func)();
484 return;
485 }
486 }
487 ASSERT(0);
488}
489
490void runInAnotherProcess(const char *tag) {
491 pid_t pid = fork();
492 if (pid == 0) {
493 execlp(gExecutable, gExecutable, tag, NULL);
494 ASSERT(0);
495 } else {
496 int status;
497 ASSERT_EQ(pid, wait(&status));
498 ASSERT_EQ(0, status);
499 }
500}
501
502void testReconnect() {
503 INFO(__func__);
504 sp<ICameraService> cs = getCameraService();
505 sp<MCameraClient> cc = new MCameraClient();
506 sp<ICamera> c = cs->connect(cc);
507 ASSERT(c != 0);
508 // Reconnect to the same client -- ok.
509 ASSERT(c->connect(cc) == NO_ERROR);
510 // Reconnect to a different client (but the same pid) -- ok.
511 sp<MCameraClient> cc2 = new MCameraClient();
512 ASSERT(c->connect(cc2) == NO_ERROR);
513 c->disconnect();
514 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
515}
516
517void testLockUnlock() {
518 sp<ICameraService> cs = getCameraService();
519 sp<MCameraClient> cc = new MCameraClient();
520 sp<ICamera> c = cs->connect(cc);
521 ASSERT(c != 0);
522 // We can lock as many times as we want.
523 ASSERT(c->lock() == NO_ERROR);
524 ASSERT(c->lock() == NO_ERROR);
525 // Lock from a different process -- not ok.
526 putTempObject(c->asBinder());
527 runInAnotherProcess("testLockFailed");
528 // Unlock then lock from a different process -- ok.
529 ASSERT(c->unlock() == NO_ERROR);
530 runInAnotherProcess("testLockUnlockSuccess");
531 // Unlock then lock from a different process -- ok.
532 runInAnotherProcess("testLockSuccess");
533 c->disconnect();
534 clearTempObject();
535}
536
537void testReconnectFromAnotherProcess() {
538 INFO(__func__);
539
540 sp<ICameraService> cs = getCameraService();
541 sp<MCameraClient> cc = new MCameraClient();
542 sp<ICamera> c = cs->connect(cc);
543 ASSERT(c != 0);
544 // Reconnect from a different process -- not ok.
545 putTempObject(c->asBinder());
546 runInAnotherProcess("testReconnectFailed");
547 // Unlock then reconnect from a different process -- ok.
548 ASSERT(c->unlock() == NO_ERROR);
549 runInAnotherProcess("testReconnectSuccess");
550 c->disconnect();
551 clearTempObject();
552}
553
554// We need to flush the command buffer after the reference
555// to ICamera is gone. The sleep is for the server to run
556// the destructor for it.
557static void flushCommands() {
558 IPCThreadState::self()->flushCommands();
559 usleep(200000); // 200ms
560}
561
562// Run a test case
563#define RUN(class_name) do { \
564 { \
565 INFO(#class_name); \
566 class_name instance; \
567 instance.run(); \
568 } \
569 flushCommands(); \
570} while(0)
571
572// Base test case after the the camera is connected.
573class AfterConnect {
574protected:
575 sp<ICameraService> cs;
576 sp<MCameraClient> cc;
577 sp<ICamera> c;
578
579 AfterConnect() {
580 cs = getCameraService();
581 cc = new MCameraClient();
582 c = cs->connect(cc);
583 ASSERT(c != 0);
584 }
585
586 ~AfterConnect() {
587 c.clear();
588 cc.clear();
589 cs.clear();
590 }
591};
592
593class TestSetPreviewDisplay : public AfterConnect {
594public:
595 void run() {
596 sp<MSurface> surface = new MSurface();
597 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
598 c->disconnect();
599 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
600 }
601};
602
603class TestStartPreview : public AfterConnect {
604public:
605 void run() {
606 sp<MSurface> surface = new MSurface();
607 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
608
609 ASSERT(c->startPreview() == NO_ERROR);
610 ASSERT(c->previewEnabled() == true);
611
612 surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer
613 surface->clearStat();
614
615 c->disconnect();
616 // TODO: CameraService crashes for this. Fix it.
617#if 0
618 sp<MSurface> another_surface = new MSurface();
619 c->setPreviewDisplay(another_surface); // just to make sure unregisterBuffers
620 // is called.
621 surface->waitUntil(0, 0, 1); // needs unregisterBuffers
622#endif
623 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
624 }
625};
626
627class TestStartPreviewWithoutDisplay : AfterConnect {
628public:
629 void run() {
630 ASSERT(c->startPreview() == NO_ERROR);
631 ASSERT(c->previewEnabled() == true);
632 c->disconnect();
633 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
634 }
635};
636
637// Base test case after the the camera is connected and the preview is started.
638class AfterStartPreview : public AfterConnect {
639protected:
640 sp<MSurface> surface;
641
642 AfterStartPreview() {
643 surface = new MSurface();
644 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
645 ASSERT(c->startPreview() == NO_ERROR);
646 }
647
648 ~AfterStartPreview() {
649 surface.clear();
650 }
651};
652
653class TestAutoFocus : public AfterStartPreview {
654public:
655 void run() {
656 cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0);
657 c->autoFocus();
658 cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1);
659 c->disconnect();
660 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
661 }
662};
663
664class TestStopPreview : public AfterStartPreview {
665public:
666 void run() {
667 ASSERT(c->previewEnabled() == true);
668 c->stopPreview();
669 ASSERT(c->previewEnabled() == false);
670 c->disconnect();
671 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
672 }
673};
674
675class TestTakePicture: public AfterStartPreview {
676public:
677 void run() {
678 ASSERT(c->takePicture() == NO_ERROR);
679 cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
680 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
681 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
682 c->stopPreview();
683#if 1 // TODO: It crashes if we don't have this. Fix it.
684 usleep(100000);
685#endif
686 c->disconnect();
687 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
688 }
689};
690
691class TestTakeMultiplePictures: public AfterStartPreview {
692public:
693 void run() {
694 for (int i = 0; i < 10; i++) {
695 cc->clearStat();
696 ASSERT(c->takePicture() == NO_ERROR);
697 cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
698 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
699 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
700 usleep(100000); // 100ms
701 }
702 c->disconnect();
703 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
704 }
705};
706
707class TestGetParameters: public AfterStartPreview {
708public:
709 void run() {
710 String8 param_str = c->getParameters();
711 INFO(param_str);
712 }
713};
714
715class TestPictureSize : public AfterStartPreview {
716public:
717 void checkOnePicture(int w, int h) {
718 const float rate = 0.5; // byte per pixel limit
719 int pixels = w * h;
720
721 CameraParameters param(c->getParameters());
722 param.setPictureSize(w, h);
723 c->setParameters(param.flatten());
724
725 cc->clearStat();
726 ASSERT(c->takePicture() == NO_ERROR);
727 cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
728 cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2);
729 cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
730 cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT,
731 int(pixels * rate));
732 cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0);
733 cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
734 usleep(100000); // 100ms
735 }
736
737 void run() {
738 checkOnePicture(2048, 1536);
739 checkOnePicture(1600, 1200);
740 checkOnePicture(1024, 768);
741 }
742};
743
744class TestPreviewCallbackFlag : public AfterConnect {
745public:
746 void run() {
747 sp<MSurface> surface = new MSurface();
748 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
749
750 // Try all flag combinations.
751 for (int v = 0; v < 8; v++) {
752 cc->clearStat();
753 c->setPreviewCallbackFlag(v);
754 ASSERT(c->previewEnabled() == false);
755 ASSERT(c->startPreview() == NO_ERROR);
756 ASSERT(c->previewEnabled() == true);
757 sleep(2);
758 c->stopPreview();
759 if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
760 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
761 } else {
762 if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
763 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
764 } else {
765 cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
766 }
767 }
768 }
769 }
770};
771
772class TestRecording : public AfterConnect {
773public:
774 void run() {
775 ASSERT(c->recordingEnabled() == false);
776 sp<MSurface> surface = new MSurface();
777 ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
778 c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
779 cc->setReleaser(c.get());
780 c->startRecording();
781 ASSERT(c->recordingEnabled() == true);
782 sleep(2);
783 c->stopRecording();
784 cc->setReleaser(NULL);
785 cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10);
786 }
787};
788
789class TestPreviewSize : public AfterStartPreview {
790public:
791 void checkOnePicture(int w, int h) {
792 int size = w*h*3/2; // should read from parameters
793
794 c->stopPreview();
795
796 CameraParameters param(c->getParameters());
797 param.setPreviewSize(w, h);
798 c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
799 c->setParameters(param.flatten());
800
801 c->startPreview();
802
803 cc->clearStat();
804 cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1);
805 cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size);
806 }
807
808 void run() {
809 checkOnePicture(480, 320);
810 checkOnePicture(352, 288);
811 checkOnePicture(176, 144);
812 }
813};
814
815void runHolderService() {
816 defaultServiceManager()->addService(
817 String16("CameraServiceTest.Holder"), new HolderService());
818 ProcessState::self()->startThreadPool();
819}
820
821int main(int argc, char **argv)
822{
823 if (argc != 1) {
824 runFunction(argv[1]);
825 return 0;
826 }
827 INFO("CameraServiceTest start");
828 gExecutable = argv[0];
829 runHolderService();
830
831 testConnect(); flushCommands();
832 testAllowConnectOnceOnly(); flushCommands();
833 testReconnect(); flushCommands();
834 testLockUnlock(); flushCommands();
835 testReconnectFromAnotherProcess(); flushCommands();
836
837 RUN(TestSetPreviewDisplay);
838 RUN(TestStartPreview);
839 RUN(TestStartPreviewWithoutDisplay);
840 RUN(TestAutoFocus);
841 RUN(TestStopPreview);
842 RUN(TestTakePicture);
843 RUN(TestTakeMultiplePictures);
844 RUN(TestGetParameters);
845 RUN(TestPictureSize);
846 RUN(TestPreviewCallbackFlag);
847 RUN(TestRecording);
848 RUN(TestPreviewSize);
849}