Download - Android Camera Architecture
Android Camera Architecture
Author: Picker
Architecture
Architecture
Path of the Source Code
frameworks/base/core/java/android/hardware/
frameworks/base/core/jni/
frameworks/base/libs/camera/
frameworks/base/services/camera/libcameraservice/
vendor/nvidia/tegra/hal/libnvomxcamera/
Proxy Pattern
Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides
A Possible Object Diagram of Proxy Structure at Run-Time
Proxy Structure
Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides
Implementation
- Design a Abstract Class for Proxy and Server to Extend it.
- Give an RealObject Instance for Proxy. Execute these Methods by Proxy.
- The Client just Need to Face the Proxy.
Singleton Pattern
Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides
Singleton Structure
Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides
Singleton* Singleton::_instance = 0; Singleton* Singleton::Instance () { if (_instance == 0) { _instance = new Singleton; } return _instance; }
Implementation
Architecture Diagram
Proxy Pattern
Singleton Pattern
33 // client singleton for camera service binder interface 34 Mutex Camera::mLock; 35 sp Camera::mCameraService; 36 sp Camera::mDeathNotifier;
Singleton Pattern
Camera.cpp
frameworks/base/libs/camera/
38 // establish binder interface to camera service 39 const sp& Camera::getCameraService() 40 { 41 Mutex::Autolock _l(mLock); 42 if (mCameraService.get() == 0) { 43 sp sm = defaultServiceManager(); 44 sp binder; 45 do { 46 binder = sm->getService(String16("media.camera")); 47 if (binder != 0) 48 break; 49 LOGW("CameraService not published, waiting..."); 50 usleep(500000); // 0.5 s 51 } while(true); 52 if (mDeathNotifier == NULL) { 53 mDeathNotifier = new DeathNotifier(); 54 } 55 binder->linkToDeath(mDeathNotifier); 56 mCameraService = interface_cast(binder); 57 } 58 LOGE_IF(mCameraService==0, "no CameraService!?"); 59 return mCameraService; 60 }
Camera.cpp
frameworks/base/libs/camera/
53 class BpCamera: public BpInterface 54 { 55 public: 56 BpCamera(const sp& impl) 57 : BpInterface(impl) 58 { 59 } 60 61 // disconnect from camera service 62 void disconnect() 63 { 64 LOGV("disconnect"); 65 Parcel data, reply; 66 data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); 67 remote()->transact(DISCONNECT, data, &reply); 68 }
ICamera.cpp
frameworks/base/libs/camera/
Proxy Pattern - Sender
34 class CameraService : 35 public BinderService, 36 public BnCameraService 37 { 38 class Client; 39 friend class BinderService;
82 class Client : public BnCamera 83 { 84 public: 85 // ICamera interface (see ICamera for details) 86 virtual void disconnect(); 87 virtual status_t connect(const sp& client); 88 virtual status_t lock(); 89 virtual status_t unlock();206 }
Proxy Pattern - Receiver
CameraService.h
frameworks/base/services/camera/libcameraservice/
A Simple Workflow of Starting the Camera Preview
An Example: Set the Preview Display
349 public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { 350 if (holder != null) { 351 setPreviewDisplay(holder.getSurface()); 352 } else { 353 setPreviewDisplay((Surface)null); 354 } 355 }
Camera.java
frameworks/base/core/java/android/hardware/
android_hardware_Camera.cpp
381 static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, jobject jSurface)382 {383 LOGV("setPreviewDisplay");384 sp camera = get_native_camera(env, thiz, NULL);385 if (camera == 0) return;386 387 sp surface = NULL; 388 if (jSurface != NULL) {389 surface = reinterpret_cast(env->GetIntField(jSurface, fields.surface));390 }391 if (camera->setPreviewDisplay(surface) != NO_ERROR) {392 jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");393 }394 }
frameworks/base/core/jni/
Camera.cpp
frameworks/base/libs/camera/
171 // pass the buffered ISurface to the camera service172 status_t Camera::setPreviewDisplay(const sp& surface)173 { 174 LOGV("setPreviewDisplay");175 sp c = mCamera;176 if (c == 0) return NO_INIT; 177 if (surface != 0) {178 return c->setPreviewDisplay(surface->getISurface());179 } else {180 LOGD("app passed NULL surface");181 return c->setPreviewDisplay(0);182 }183 }
ICamera.cpp
70 // pass the buffered ISurface to the camera service 71 status_t setPreviewDisplay(const sp& surface) 72 { 73 LOGV("setPreviewDisplay"); 74 Parcel data, reply; 75 data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); 76 data.writeStrongBinder(surface->asBinder()); 77 remote()->transact(SET_PREVIEW_DISPLAY, data, &reply); 78 return reply.readInt32(); 79 }
frameworks/base/libs/camera/
CameraService.cpp
frameworks/base/libs/camera/
485 status_t CameraService::Client::setPreviewDisplay(const sp& surface) { 486 LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
510 mSurface = surface; 511 mOverlayRef = 0; 512 // If preview has been already started, set overlay or register preview 513 // buffers now. 514 if (mHardware->previewEnabled()) { 515 if (mUseOverlay) { 516 result = setOverlay(); 517 } else if (mSurface != 0) { 518 result = registerPreviewBuffers(); 519 } 520 }
frameworks/base/libs/camera/
CameraService.cpp
525 status_t CameraService::Client::registerPreviewBuffers() { 526 int w, h; 527 CameraParameters params(mHardware->getParameters()); 528 params.getPreviewSize(&w, &h); 529 530 // FIXME: don't use a hardcoded format here. 531 ISurface::BufferHeap buffers(w, h, w, h, 532 HAL_PIXEL_FORMAT_YCrCb_420_SP, 533 mOrientation, 534 0, 535 mHardware->getPreviewHeap()); 536 537 status_t result = mSurface->registerBuffers(buffers); 538 if (result != NO_ERROR) { 539 LOGE("registerBuffers failed with status %d", result); 540 } 541 return result; 542 }
frameworks/base/libs/camera/
CameraHardwareStub.cpp
104 sp CameraHardwareStub::getPreviewHeap() const105 { 106 return mPreviewHeap;107 }