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
40 using namespace android;
41
42 //
43 // Assertion and Logging utilities
44 //
45 #define INFO(...) \
46 do { \
47 printf(__VA_ARGS__); \
48 printf("\n"); \
49 LOGD(__VA_ARGS__); \
50 } while(0)
51
assert_fail(const char * file,int line,const char * func,const char * expr)52 void 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
assert_eq_fail(const char * file,int line,const char * func,const char * expr,int actual)59 void 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 //
83 class IHolder : public IInterface {
84 protected:
85 enum {
86 HOLDER_PUT = IBinder::FIRST_CALL_TRANSACTION,
87 HOLDER_GET,
88 HOLDER_CLEAR
89 };
90 public:
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
98 class 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
105 class BpHolder : public BpInterface<IHolder> {
106 public:
BpHolder(const sp<IBinder> & impl)107 BpHolder(const sp<IBinder>& impl)
108 : BpInterface<IHolder>(impl) {
109 }
110
put(sp<IBinder> obj)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
get()117 virtual sp<IBinder> get() {
118 Parcel data, reply;
119 remote()->transact(HOLDER_GET, data, &reply);
120 return reply.readStrongBinder();
121 }
122
clear()123 virtual void clear() {
124 Parcel data, reply;
125 remote()->transact(HOLDER_CLEAR, data, &reply);
126 }
127 };
128
129 IMPLEMENT_META_INTERFACE(Holder, "CameraServiceTest.Holder");
130
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)131 status_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
151 class HolderService : public BnHolder {
put(sp<IBinder> obj)152 virtual void put(sp<IBinder> obj) {
153 mObj = obj;
154 }
get()155 virtual sp<IBinder> get() {
156 return mObj;
157 }
clear()158 virtual void clear() {
159 mObj.clear();
160 }
161 private:
162 sp<IBinder> mObj;
163 };
164
165 //
166 // A mock CameraClient
167 //
168 class MCameraClient : public BnCameraClient {
169 public:
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
setReleaser(ICamera * releaser)184 void setReleaser(ICamera *releaser) {
185 mReleaser = releaser;
186 }
187 private:
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
clearStat()199 void MCameraClient::clearStat() {
200 Mutex::Autolock _l(mLock);
201 mNotifyCount.clear();
202 mDataCount.clear();
203 mDataSize.clear();
204 }
205
test(OP op,int v1,int v2)206 bool 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
assertTest(OP op,int v1,int v2)218 void 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
assertNotify(int32_t msgType,OP op,int count)225 void 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
assertData(int32_t msgType,OP op,int count)231 void 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
assertDataSize(int32_t msgType,OP op,int dataSize)237 void 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
notifyCallback(int32_t msgType,int32_t ext1,int32_t ext2)243 void 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
dataCallback(int32_t msgType,const sp<IMemory> & data)255 void 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
dataCallbackTimestamp(nsecs_t timestamp,int32_t msgType,const sp<IMemory> & data)276 void MCameraClient::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
277 const sp<IMemory>& data) {
278 dataCallback(msgType, data);
279 }
280
waitNotify(int32_t msgType,OP op,int count)281 void 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
waitData(int32_t msgType,OP op,int count)293 void 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 //
308 class MSurface : public BnSurface {
309 public:
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
320 private:
321 // check callback count
322 Condition mCond;
323 Mutex mLock;
324 int registerBuffersCount;
325 int postBufferCount;
326 int unregisterBuffersCount;
327 };
328
registerBuffers(const BufferHeap & buffers)329 status_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
postBuffer(ssize_t offset)337 void MSurface::postBuffer(ssize_t offset) {
338 // INFO("%s", __func__);
339 Mutex::Autolock _l(mLock);
340 ++postBufferCount;
341 mCond.signal();
342 }
343
unregisterBuffers()344 void MSurface::unregisterBuffers() {
345 INFO("%s", __func__);
346 Mutex::Autolock _l(mLock);
347 ++unregisterBuffersCount;
348 mCond.signal();
349 }
350
requestBuffer(int bufferIdx,int usage)351 sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
352 INFO("%s", __func__);
353 return NULL;
354 }
355
setBufferCount(int bufferCount)356 status_t MSurface::setBufferCount(int bufferCount) {
357 INFO("%s", __func__);
358 return NULL;
359 }
360
clearStat()361 void MSurface::clearStat() {
362 Mutex::Autolock _l(mLock);
363 registerBuffersCount = 0;
364 postBufferCount = 0;
365 unregisterBuffersCount = 0;
366 }
367
waitUntil(int c0,int c1,int c2)368 void 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 //
getHolder()384 sp<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
putTempObject(sp<IBinder> obj)394 void putTempObject(sp<IBinder> obj) {
395 INFO("%s", __func__);
396 getHolder()->put(obj);
397 }
398
getTempObject()399 sp<IBinder> getTempObject() {
400 INFO("%s", __func__);
401 return getHolder()->get();
402 }
403
clearTempObject()404 void clearTempObject() {
405 INFO("%s", __func__);
406 getHolder()->clear();
407 }
408
409 //
410 // Get a Camera Service
411 //
getCameraService()412 sp<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
getNumberOfCameras()422 int getNumberOfCameras() {
423 sp<ICameraService> cs = getCameraService();
424 return cs->getNumberOfCameras();
425 }
426
427 //
428 // Various Connect Tests
429 //
testConnect(int cameraId)430 void 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
testAllowConnectOnceOnly(int cameraId)439 void 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
testReconnectFailed()454 void 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
testReconnectSuccess()461 void 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
testLockFailed()469 void testLockFailed() {
470 INFO("%s", __func__);
471 sp<ICamera> c = interface_cast<ICamera>(getTempObject());
472 ASSERT(c->lock() != NO_ERROR);
473 }
474
testLockUnlockSuccess()475 void 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
testLockSuccess()482 void 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 //
492 const char *gExecutable;
493
494 struct FunctionTableEntry {
495 const char *name;
496 void (*func)();
497 };
498
499 FunctionTableEntry 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
runFunction(const char * tag)509 void 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
runInAnotherProcess(const char * tag)521 void 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
testReconnect(int cameraId)533 void 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
testLockUnlock(int cameraId)548 void 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
testReconnectFromAnotherProcess(int cameraId)567 void 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.
flushCommands()586 static 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.
603 class AfterConnect {
604 public:
init(int cameraId)605 void init(int cameraId) {
606 cs = getCameraService();
607 cc = new MCameraClient();
608 c = cs->connect(cc, cameraId);
609 ASSERT(c != 0);
610 }
611
612 protected:
613 sp<ICameraService> cs;
614 sp<MCameraClient> cc;
615 sp<ICamera> c;
616
~AfterConnect()617 ~AfterConnect() {
618 c->disconnect();
619 c.clear();
620 cc.clear();
621 cs.clear();
622 }
623 };
624
625 class TestSetPreviewDisplay : public AfterConnect {
626 public:
run()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
635 class TestStartPreview : public AfterConnect {
636 public:
run()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
656 class TestStartPreviewWithoutDisplay : public AfterConnect {
657 public:
run()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.
667 class AfterStartPreview : public AfterConnect {
668 public:
init(int cameraId)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
676 protected:
677 sp<MSurface> surface;
678
~AfterStartPreview()679 ~AfterStartPreview() {
680 surface.clear();
681 }
682 };
683
684 class TestAutoFocus : public AfterStartPreview {
685 public:
run()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
695 class TestStopPreview : public AfterStartPreview {
696 public:
run()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
706 class TestTakePicture: public AfterStartPreview {
707 public:
run()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
719 class TestTakeMultiplePictures: public AfterStartPreview {
720 public:
run()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
734 class TestGetParameters: public AfterStartPreview {
735 public:
run()736 void run() {
737 String8 param_str = c->getParameters();
738 INFO("%s", static_cast<const char*>(param_str));
739 }
740 };
741
getNextSize(const char ** ptrS,int * w,int * h)742 static 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
771 class TestPictureSize : public AfterStartPreview {
772 public:
checkOnePicture(int w,int h)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
run()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 LOGD("checking picture size %dx%d", w, h);
801 checkOnePicture(w, h);
802 }
803 }
804 };
805
806 class TestPreviewCallbackFlag : public AfterConnect {
807 public:
run()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 LOGD("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
836 class TestRecording : public AfterConnect {
837 public:
run()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
854 class TestPreviewSize : public AfterStartPreview {
855 public:
checkOnePicture(int w,int h)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
run()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 LOGD("checking preview size %dx%d", w, h);
879 checkOnePicture(w, h);
880 }
881 }
882 };
883
runHolderService()884 void runHolderService() {
885 defaultServiceManager()->addService(
886 String16("CameraServiceTest.Holder"), new HolderService());
887 ProcessState::self()->startThreadPool();
888 }
889
main(int argc,char ** argv)890 int 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