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<ICameraService> Camera::mCameraService; 36 sp<Camera::DeathNotifier> Camera::mDeathNotifier; Singleton Pattern Camera.cpp frameworks/base/libs/camera/
38 // establish binder interface to camera service 39 const sp<ICameraService>& Camera::getCameraService() 40 {  41  Mutex::Autolock _l(mLock); 42  if (mCameraService.get() == 0) { 43  sp<IServiceManager> sm = defaultServiceManager(); 44  sp<IBinder> binder; 45  do { 46  binder = sm->getService(String16(&quot;media.camera&quot;)); 47  if (binder != 0) 48  break; 49  LOGW(&quot;CameraService not published, waiting...&quot;); 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<ICameraService>(binder); 57  } 58  LOGE_IF(mCameraService==0, &quot;no CameraService!?&quot;); 59  return mCameraService; 60 }  Camera.cpp frameworks/base/libs/camera/
53  class BpCamera: public BpInterface<ICamera> 54 { 55 public: 56  BpCamera(const sp<IBinder>& impl) 57  : BpInterface<ICamera>(impl) 58  { 59  } 60  61  // disconnect from camera service 62  void disconnect() 63  { 64  LOGV(&quot;disconnect&quot;); 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<CameraService>, 36  public BnCameraService 37 { 38  class Client; 39  friend class BinderService<CameraService>; 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<ICameraClient>& 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(&quot;setPreviewDisplay&quot;); 384  sp<Camera> camera = get_native_camera(env, thiz, NULL); 385  if (camera == 0) return; 386  387  sp<Surface> surface = NULL;  388  if (jSurface != NULL) { 389  surface = reinterpret_cast<Surface*>( env->GetIntField(jSurface, fields.surface)); 390  } 391  if ( camera->setPreviewDisplay (surface) != NO_ERROR) { 392  jniThrowException(env, &quot;java/io/IOException&quot;, &quot;setPreviewDisplay failed&quot;); 393  } 394 }  frameworks/base/core/jni/
Camera.cpp frameworks/base/libs/camera/ 171 // pass the buffered ISurface to the camera service 172 status_t  Camera::setPreviewDisplay (const sp<Surface>& surface) 173 {  174  LOGV(&quot;setPreviewDisplay&quot;); 175  sp <ICamera> c = mCamera; 176  if (c == 0) return NO_INIT;  177  if (surface != 0) { 178  return  c->setPreviewDisplay (surface->getISurface()); 179  } else { 180  LOGD(&quot;app passed NULL surface&quot;); 181  return  c->setPreviewDisplay (0); 182  } 183 }
ICamera.cpp 70  // pass the buffered ISurface to the camera service 71  status_t  setPreviewDisplay (const sp<ISurface>& surface) 72  { 73  LOGV(&quot;setPreviewDisplay&quot;);  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<ISurface>& surface) { 486  LOG1(&quot;setPreviewDisplay(%p) (pid %d)&quot;, 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(&quot;registerBuffers failed with status %d&quot;, result); 540  } 541  return result; 542 }
frameworks/base/libs/camera/ CameraHardwareStub.cpp 104 sp<IMemoryHeap>  CameraHardwareStub::getPreviewHeap()  const 105 {  106  return mPreviewHeap; 107 }

Android Camera Architecture

  • 1.
    Android Camera Architecture Author: Picker
  • 2.
  • 3.
  • 4.
    Architecture Path ofthe 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/
  • 5.
  • 6.
    Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides
  • 7.
    A Possible ObjectDiagram of Proxy Structure at Run-Time Proxy Structure Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides
  • 8.
    Implementation - Designa 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.
  • 9.
  • 10.
    Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides Singleton Structure
  • 11.
    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
  • 12.
  • 13.
  • 14.
    33 // clientsingleton for camera service binder interface 34 Mutex Camera::mLock; 35 sp<ICameraService> Camera::mCameraService; 36 sp<Camera::DeathNotifier> Camera::mDeathNotifier; Singleton Pattern Camera.cpp frameworks/base/libs/camera/
  • 15.
    38 // establishbinder interface to camera service 39 const sp<ICameraService>& Camera::getCameraService() 40 { 41 Mutex::Autolock _l(mLock); 42 if (mCameraService.get() == 0) { 43 sp<IServiceManager> sm = defaultServiceManager(); 44 sp<IBinder> binder; 45 do { 46 binder = sm->getService(String16(&quot;media.camera&quot;)); 47 if (binder != 0) 48 break; 49 LOGW(&quot;CameraService not published, waiting...&quot;); 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<ICameraService>(binder); 57 } 58 LOGE_IF(mCameraService==0, &quot;no CameraService!?&quot;); 59 return mCameraService; 60 } Camera.cpp frameworks/base/libs/camera/
  • 16.
    53 classBpCamera: public BpInterface<ICamera> 54 { 55 public: 56 BpCamera(const sp<IBinder>& impl) 57 : BpInterface<ICamera>(impl) 58 { 59 } 60 61 // disconnect from camera service 62 void disconnect() 63 { 64 LOGV(&quot;disconnect&quot;); 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
  • 17.
    34 class CameraService: 35 public BinderService<CameraService>, 36 public BnCameraService 37 { 38 class Client; 39 friend class BinderService<CameraService>; 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<ICameraClient>& client); 88 virtual status_t lock(); 89 virtual status_t unlock(); … … … 206 } Proxy Pattern - Receiver CameraService.h frameworks/base/services/camera/libcameraservice/
  • 18.
    A Simple Workflowof Starting the Camera Preview
  • 19.
  • 20.
    An Example: Setthe Preview Display
  • 21.
    349 publicfinal 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/
  • 22.
    android_hardware_Camera.cpp 381 staticvoid android_hardware_Camera_setPreviewDisplay ( JNIEnv *env, jobject thiz, jobject jSurface) 382 { 383 LOGV(&quot;setPreviewDisplay&quot;); 384 sp<Camera> camera = get_native_camera(env, thiz, NULL); 385 if (camera == 0) return; 386 387 sp<Surface> surface = NULL; 388 if (jSurface != NULL) { 389 surface = reinterpret_cast<Surface*>( env->GetIntField(jSurface, fields.surface)); 390 } 391 if ( camera->setPreviewDisplay (surface) != NO_ERROR) { 392 jniThrowException(env, &quot;java/io/IOException&quot;, &quot;setPreviewDisplay failed&quot;); 393 } 394 } frameworks/base/core/jni/
  • 23.
    Camera.cpp frameworks/base/libs/camera/ 171// pass the buffered ISurface to the camera service 172 status_t Camera::setPreviewDisplay (const sp<Surface>& surface) 173 { 174 LOGV(&quot;setPreviewDisplay&quot;); 175 sp <ICamera> c = mCamera; 176 if (c == 0) return NO_INIT; 177 if (surface != 0) { 178 return c->setPreviewDisplay (surface->getISurface()); 179 } else { 180 LOGD(&quot;app passed NULL surface&quot;); 181 return c->setPreviewDisplay (0); 182 } 183 }
  • 24.
    ICamera.cpp 70 // pass the buffered ISurface to the camera service 71 status_t setPreviewDisplay (const sp<ISurface>& surface) 72 { 73 LOGV(&quot;setPreviewDisplay&quot;); 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/
  • 25.
    CameraService.cpp frameworks/base/libs/camera/ 485status_t CameraService::Client::setPreviewDisplay (const sp<ISurface>& surface) { 486 LOG1(&quot;setPreviewDisplay(%p) (pid %d)&quot;, 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 }
  • 26.
    frameworks/base/libs/camera/ CameraService.cpp 525status_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(&quot;registerBuffers failed with status %d&quot;, result); 540 } 541 return result; 542 }
  • 27.
    frameworks/base/libs/camera/ CameraHardwareStub.cpp 104sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const 105 { 106 return mPreviewHeap; 107 }