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