Bug 727950: Don't close the camera dso, some of them don't like that. r=fabrice (npotb)
authorChris Jones <jones.chris.g@gmail.com>
Fri, 17 Feb 2012 22:33:52 -0800
changeset 87138 550779e6bab444b48dac408c6f361ab503744472
parent 87137 87bb3cff18646dda0deb6c0555360fc508d1ed92
child 87152 20478b6732123ec2ace4d3568c4ed8221472c0b2
push id22082
push usercjones@mozilla.com
push dateSat, 18 Feb 2012 06:34:03 +0000
treeherdermozilla-central@550779e6bab4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs727950
milestone13.0a1
first release with
nightly linux32
550779e6bab4 / 13.0a1 / 20120218031156 / files
nightly linux64
550779e6bab4 / 13.0a1 / 20120218031156 / files
nightly mac
550779e6bab4 / 13.0a1 / 20120218031156 / files
nightly win32
550779e6bab4 / 13.0a1 / 20120218031156 / files
nightly win64
550779e6bab4 / 13.0a1 / 20120218031156 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 727950: Don't close the camera dso, some of them don't like that. r=fabrice (npotb)
netwerk/protocol/device/GonkCaptureProvider.cpp
--- a/netwerk/protocol/device/GonkCaptureProvider.cpp
+++ b/netwerk/protocol/device/GonkCaptureProvider.cpp
@@ -1,22 +1,24 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <dlfcn.h>
+#include "android/log.h"
 #include "cutils/properties.h"
 
 #include "base/basictypes.h"
 #include "GonkCaptureProvider.h"
 #include "nsXULAppAPI.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "nsRawStructs.h"
+#include "prinit.h"
 
 #define USE_GS2_LIBCAMERA
 #define CameraHardwareInterface CameraHardwareInterface_SGS2
 #define HAL_openCameraHardware HAL_openCameraHardware_SGS2
 #include "camera/CameraHardwareInterface.h"
 #undef CameraHardwareInterface
 #undef USE_GS2_LIBCAMERA
 #undef HAL_openCameraHardware
@@ -43,29 +45,29 @@
 #include "camera/CameraHardwareInterface.h"
 #undef CameraHardwareInterface
 
 using namespace android;
 using namespace mozilla;
 
 class CameraHardwareInterface {
   public:
-    typedef enum {
+    enum Type {
       CAMERA_SGS2,
       CAMERA_MAGURO,
       CAMERA_DEFAULT
-    } Type;
+    };
 
     static Type getType() {
       char propValue[PROPERTY_VALUE_MAX];
       property_get("ro.product.board", propValue, NULL);
       if (!strcmp(propValue, "GT-I9100"))
         return CAMERA_SGS2;
 
-      if (!strcmp(propValue, "MSM7627A_SKU1") || !strcmp(propValue, "MSM7627A_SKU3"))
+      if (!strcmp(propValue, "msm7627a_sku1") || !strcmp(propValue, "MSM7627A_SKU3"))
         return CAMERA_MAGURO;
 
       printf_stderr("CameraHardwareInterface : unsupported camera for device %s\n", propValue);
       return CAMERA_DEFAULT;
     }
 
     static CameraHardwareInterface* openCamera(PRUint32 aCamera);
     
@@ -84,56 +86,50 @@ class CameraHardwareInterface {
     virtual void release();
     virtual status_t setParameters(const CameraParameters& params);
     virtual CameraParameters getParameters() const;
 
   protected:
     CameraHardwareInterface(PRUint32 aCamera = 0) { };
 };
 
-class DlopenWrapper {
-  public:
-    DlopenWrapper() : mHandle(nsnull) { };
-
-    DlopenWrapper(const char* aLibrary) : mHandle(nsnull) {
-      mHandle = dlopen(aLibrary, RTLD_LAZY);
-    };
+// Intentionally not trying to dlclose() this handle.  That's playing
+// Russian roulette with security bugs.
+static void* sCameraLib;
+static PRCallOnceType sInitCameraLib;
 
-    ~DlopenWrapper() {
-      if (mHandle)
-        dlclose(mHandle);
-    };
+static PRStatus
+InitCameraLib()
+{
+  sCameraLib = dlopen("/system/lib/libcamera.so", RTLD_LAZY);
+  // We might fail to open the camera lib.  That's OK.
+  return PR_SUCCESS;
+}
 
-    bool opened() {
-      return mHandle != nsnull;
-    };
-    
-    void* dlsym(const char* aFunction) {
-      return ::dlsym(mHandle, aFunction);
-    };
-
-  protected:
-    void* mHandle;
-};
+static void*
+GetCameraLibHandle()
+{
+  PR_CallOnce(&sInitCameraLib, InitCameraLib);
+  return sCameraLib;
+}
 
 template<class T> class CameraImpl : public CameraHardwareInterface {
   public:
     typedef sp<T> (*HAL_openCameraHardware_DEFAULT)(int);
     typedef sp<T> (*HAL_openCameraHardware_SGS2)(int);
     typedef sp<T> (*HAL_openCameraHardware_MAGURO)(int, int);
 
     CameraImpl(PRUint32 aCamera = 0) : mOk(false), mCamera(nsnull) {
-      DlopenWrapper wrapper("/system/lib/libcamera.so");
-
-      if (!wrapper.opened())
+      void* cameraLib = GetCameraLibHandle();
+      if (!cameraLib) {
+        printf_stderr("CameraImpl: Failed to dlopen() camera library.");
         return;
+      }
 
-      mOk = true;
-
-      void *hal = wrapper.dlsym("HAL_openCameraHardware");
+      void *hal = dlsym(cameraLib, "HAL_openCameraHardware");
       HAL_openCameraHardware_DEFAULT funct0;
       HAL_openCameraHardware_SGS2 funct1;
       HAL_openCameraHardware_MAGURO funct2;
       switch(getType()) {
         case CAMERA_SGS2:
           funct1 = reinterpret_cast<HAL_openCameraHardware_SGS2> (hal);       
           mCamera = funct1(aCamera);
           break;
@@ -141,16 +137,21 @@ template<class T> class CameraImpl : pub
           funct2 = reinterpret_cast<HAL_openCameraHardware_MAGURO> (hal);  
           mCamera = funct2(aCamera, 1);
           break;
         case CAMERA_DEFAULT:
           funct0 = reinterpret_cast<HAL_openCameraHardware_DEFAULT> (hal);  
           mCamera = funct0(aCamera);
           break;
       }
+
+      mOk = mCamera != nsnull;
+      if (!mOk) {
+        printf_stderr("CameraImpl: HAL_openCameraHardware() returned NULL (no camera interface).");
+      }
     }
 
     bool ok() {
       return mOk;
     };
 
     void enableMsgType(int32_t msgType) {
       mCamera->enableMsgType(msgType);
@@ -246,22 +247,21 @@ void
 GonkCameraInputStream::DataCallback(int32_t aMsgType, const sp<IMemory>& aDataPtr, void *aUser) {
   GonkCameraInputStream* stream = (GonkCameraInputStream*)(aUser);
   stream->ReceiveFrame((char*)aDataPtr->pointer(), aDataPtr->size());
 }
 
 PRUint32
 GonkCameraInputStream::getNumberOfCameras() {
   typedef int (*HAL_getNumberOfCamerasFunct)(void);
-  DlopenWrapper wrapper("/system/lib/libcamera.so");
-
-  if (!wrapper.opened())
+  void* cameraLib = GetCameraLibHandle();
+  if (!cameraLib)
     return 0;
   
-  void *hal = wrapper.dlsym("HAL_getNumberOfCameras");
+  void *hal = dlsym(cameraLib, "HAL_getNumberOfCameras");
   if (nsnull == hal)
     return 0;
 
   HAL_getNumberOfCamerasFunct funct = reinterpret_cast<HAL_getNumberOfCamerasFunct> (hal);       
   return funct();
 }
 
 NS_IMETHODIMP