• 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 <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