1

For last two days I was exploring a possiblity of using private Samsung frameworks in my own app, /system/frameworks/seccamera.jar in particular. Nothing worked yet so I'm wondering if it is possible at all.

Some background

I am developing an application which involves scanning QR codes and therefore is very dependent on camera picture quality. So I am struggling to have as much control over camera as possible from the application level. One of the features which greatly improve scanning speed and reliability is the ability of camera to do a spot exposure metering. However, there is no public API for specifying an exposure metering mode.

However with the built-in Camera app on Galaxy Tab 2 you are able to specify several exposure metering modes, spot metering mode among them. So I decided to investigate it further.

What I have already tried

  1. I pulled the apk and odex files for built-in Camera app using Eclipse from /system/frameworks
  2. I ran the odex file through baksmali and wound up with a handful of .smali files
  3. I searched through them for "exposureMetering" and found a class com.sec.android.seccamera.SecCamera which supports specifying exposure metering mode through its Parameters inner class
  4. I determined that this class resides in seccamera.jar (seccamera.odex) so I deodexed it separately:

    java -jar baksmali-1.3.3.jar --deodex seccamera.odex -o seccamera
    
  5. Then I dexed it together again:

    java -jar smali-1.3.3.jar seccamera/ -o seccamera.dex
    
  6. And finally I ran dex-file through dex2jar to create a jar library:

    ../dex2jar-0.0.9.8/dex2jar.sh seccamera.dex
    

which I linked as an external jar to my Eclipse project. I found out that SecCamera class has almost identical API to public android.hardware.Camera so it made converting my code much easier.

The project builds with no errors however it crashes almost instantly on startup with the following error:

06-28 16:49:31.648: E/AndroidRuntime(2329): FATAL EXCEPTION: main
06-28 16:49:31.648: E/AndroidRuntime(2329): java.lang.NoClassDefFoundError: com.google.zxing.client.android.camera.PreviewCallback
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.google.zxing.client.android.camera.CameraManager.<init>(CameraManager.java:70)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.treelev.biennale.MainActivity.onResume(MainActivity.java:212)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1158)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.Activity.performResume(Activity.java:4539)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2448)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2486)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2000)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.access$600(ActivityThread.java:128)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.os.Looper.loop(Looper.java:137)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at android.app.ActivityThread.main(ActivityThread.java:4514)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at java.lang.reflect.Method.invokeNative(Native Method)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at java.lang.reflect.Method.invoke(Method.java:511)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
06-28 16:49:31.648: E/AndroidRuntime(2329):     at dalvik.system.NativeStart.main(Native Method)

com.google.zxing.client.android.camera.PreviewCallback is one of my project classes, which I borrowed from ZXing project, so it is clearly there. I had to change it so it implements SecCamera.PreviewCallback instead of Camera.PreviewCallback. Maybe this is the culprit here.

Before that error there are a couple of other warnings:

06-28 16:49:31.625: I/dalvikvm(2329): Failed resolving Lcom/google/zxing/client/android/camera/PreviewCallback; interface 264 'Lcom/sec/android/seccamera/SecCamera$PreviewCallback;'
06-28 16:49:31.625: W/dalvikvm(2329): Link of class 'Lcom/google/zxing/client/android/camera/PreviewCallback;' failed
06-28 16:49:31.625: E/dalvikvm(2329): Could not find class 'com.google.zxing.client.android.camera.PreviewCallback', referenced from method com.google.zxing.client.android.camera.CameraManager.<init>
06-28 16:49:31.625: W/dalvikvm(2329): VFY: unable to resolve new-instance 111 (Lcom/google/zxing/client/android/camera/PreviewCallback;) in Lcom/google/zxing/client/android/camera/CameraManager;
06-28 16:49:31.625: D/dalvikvm(2329): VFY: replacing opcode 0x22 at 0x000c
06-28 16:49:31.632: I/dalvikvm(2329): Could not find method com.sec.android.seccamera.SecCamera.release, referenced from method com.google.zxing.client.android.camera.CameraManager.closeDriver
06-28 16:49:31.632: W/dalvikvm(2329): VFY: unable to resolve virtual method 1436: Lcom/sec/android/seccamera/SecCamera;.release ()V
06-28 16:49:31.632: D/dalvikvm(2329): VFY: replacing opcode 0x6e at 0x0007
06-28 16:49:31.632: I/dalvikvm(2329): Could not find method com.sec.android.seccamera.SecCamera.open, referenced from method com.google.zxing.client.android.camera.CameraManager.openDriver
06-28 16:49:31.632: W/dalvikvm(2329): VFY: unable to resolve static method 1435: Lcom/sec/android/seccamera/SecCamera;.open ()Lcom/sec/android/seccamera/SecCamera;
06-28 16:49:31.632: D/dalvikvm(2329): VFY: replacing opcode 0x71 at 0x0005
06-28 16:49:31.632: I/dalvikvm(2329): Could not find method com.sec.android.seccamera.SecCamera.setPreviewDisplay, referenced from method com.google.zxing.client.android.camera.CameraManager.openDriver
06-28 16:49:31.632: W/dalvikvm(2329): VFY: unable to resolve virtual method 1439: Lcom/sec/android/seccamera/SecCamera;.setPreviewDisplay (Landroid/view/SurfaceHolder;)V
06-28 16:49:31.632: D/dalvikvm(2329): VFY: replacing opcode 0x6e at 0x0016

So, what am I doing wrong here? Is it possible at all to use private frameworks in my custom app (as opposed to patching existing app)?

  • 1
    You mean, *besides* the blatant copyright violations? AFAIK, Samsung's code is not open source, as evidenced by the fact that you had to resort to ripping it off the device and decompiling it. You have no rights to use that code. – CommonsWare Jun 28 '12 at 13:43

1 Answers1

1

when using external libs like that, you must inform the package manager to link them at run-time

in this case, you add the following xml to the <application> element in AndroidManifest.xml

<uses-library android:name="seccamera" />

android reads /system/etc/permissions/seccamera.xml at bootup, and maps the seccamera lib name to the file the xml mentions (/system/framework/seccamera.jar in this case)

then when you mark it as a used lib, the os will link that code in at run-time, and your free to use the classes

looks like you already figured out the hard part, making eclipse compile against it

as for 'stealing' the code, as long as you dont share the rebuilt seccamera.jar with anybody and only use it to reference the functions from your code (dont include it into the apk), i dont see any real problem

but samsung may change the API later without warning and break your app

you may also want to mark it as not required 1, or it will refuse to install on devices without that lib

clever
  • 1,551
  • 1
  • 10
  • 6