• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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