TAG:
整体思想是这样的: 一,app层:
(qq345260600)camera应用的Camera.java。 一共使用了2个新方法,定义一个callback类,callback类中有2个callback方法,分别供preview和capture使用。 1,2个新方法: mCameraDevice.setCustomSpecialCallback(mCustomSpecialCallback);//只有设置了该callback,然后callback中的方法才会自动被调用 mCameraDevice.doNovatekSpcial(1); 这2个方法从名字上可以大概看出其含义,setCustomSpecialCallback用来设置callback方法的,doNovatekSpcial用来打开或者关闭二维码识别的功能的。 mCameraDevice是android.hardware.Camera类,所以往下的话,应该要找frameworks中的camera类的定义的改变。 2,callback类定义: private class NovatekSpcialCallback implements android.hardware.Camera.NovatekSpcialCallback {//从这里可以看出,该callback实现的是frameworks层的接口类 android.hardware.Camera.NovatekSpcialCallback public void onCustomSpecial1(//供preview使用,如果侦测到,第一个字节返回1 byte [] CustomData, android.hardware.Camera camera) { String value = new String((byte[])CustomData); Log.i(TAG, " novatek callback1 3 "+ value); } public void onCustomSpecial2(//供capture使用,将二维码的数据返回到上层 byte [] CustomData, android.hardware.Camera camera) { String value = new String((byte[])CustomData); Log.i(TAG, " novatek callback2 3 "+ value); } } 二,frameworks实现 我们还是按照app分析过的思路继续往下分析。 路径: frameworks/base/core/java/android/hardware/Camera.java 我们在该类中有添加app调用的2个方法和app引用到的接口类NovatekSpcialCallback。 1,两个方法: 1)public native final void doNovatekSpcial(int ena); 我们发现该方法前面有native的标记,这个代表该方法是本地实现的方法,也就是通过jni接口在native层实现 2)public final void setCustomSpecialCallback(NovatekSpcialCallback cb) { mCustomSpecialCallback = cb; } 该方法简单,app层调用该方法的时候,将app实现的callback传递给frameworks层。 2,NovatekSpcialCallback,定义如下: public interface NovatekSpcialCallback { void onCustomSpecial1(byte[] data, Camera camera); void onCustomSpecial2(byte[] data, Camera camera); } 该接口就是app要实现的接口。 3,系统怎么调用callback? private static final int CAMERA_MSG_CUSTOMSPECIAL1 = 0x4000; private static final int CAMERA_MSG_CUSTOMSPECIAL2 = 0x8000; private class EventHandler extends Handler { ...... public void handleMessage(Message msg) { switch(msg.what) { ...... case CAMERA_MSG_CUSTOMSPECIAL1: if (mCustomSpecialCallback != null) { String value = new String((byte[])msg.obj);//数据从msg中取出 //Log.i(TAG, " novatek callback1 1"+value); mCustomSpecialCallback.onCustomSpecial1((byte[])msg.obj, mCamera); } else { String value = new String((byte[])msg.obj); //Log.i(TAG, " novatek callback1 2"+ value); //Log.i(TAG, " novatek callback1 2"); } return; case CAMERA_MSG_CUSTOMSPECIAL2: if (mCustomSpecialCallback != null) { //Log.i(TAG, "novatek callback2 1"); mCustomSpecialCallback.onCustomSpecial2((byte[])msg.obj, mCamera); } else { String value = new String((byte[])msg.obj); //Log.i(TAG, "novatek callback2 2"+ value); //Log.i(TAG, "novatek callback2 2"); } return; ...... } } } 我们从handleMessage中看到了callback的调用,只要handle接受到处理的消息,那将会执行对应消息的处理部分。所以我们可以肯定在camera的service中有给该handle发送消息的地方。 路径:frameworks/base/services/camera/libcameraservice/CameraService.cpp 我们在status_t CameraService::Client::startPreviewMode() { ...... enableMsgType(CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_CUSTOMSPECIAL1 | CAMERA_MSG_SMILE | CAMERA_MSG_EIS | CAMERA_MSG_MAV); ...... } status_t CameraService::Client::takePicture() { ...... enableMsgType(CAMERA_MSG_SHUTTER | CAMERA_MSG_POSTVIEW_FRAME | CAMERA_MSG_RAW_IMAGE | CAMERA_MSG_COMPRESSED_IMAGE | CAMERA_MSG_COMPRESSED_END | CAMERA_MSG_CUSTOMSPECIAL2 | CAMERA_MSG_PANORAMA); ...... } 我们在preview中使能设置消息1,在capture中使能设置消息2。这样就会在preview和capture时notify到之前分析的那边,然后sendmsg,接受到msg后,就执行handlemessage中对应处理部分。 三,jni层 我们在frameworks分析中知道doNovatekSpcial(int ena)是一个本地方法。 路径:frameworks/base/core/jni/android_hardware_Camera.cpp static void android_hardware_Camera_doNovatekSpcial(JNIEnv *env, jobject thiz, jint value) { // LOGV("doNovatekSpcial"); sp<Camera> camera = get_native_camera(env, thiz, NULL); if (camera == 0) return; if (camera->sendCommand(CAMERA_CMD_DO_NOVATEKSPEC, value, 0) != NO_ERROR) { jniThrowException(env, "java/lang/RuntimeException", "doNovatekSpcial failed"); } } { "doNovatekSpcial", "(I)V", (void *)android_hardware_Camera_doNovatekSpcial }, 我们在本地方法中发现,它想hal层发送了一个CAMERA_CMD_DO_NOVATEKSPEC命令,打开或者关闭二维码识别的功能有后面的value决定。 |