1. 程式人生 > >如何閱讀Android framework層原始碼

如何閱讀Android framework層原始碼

閱讀Android Framework層的原始碼可能是Android 開發者深入學習的必經之路。但在我學習的過程中看到最多的是各路大神的原始碼分析,而很少有展示如何一步一步找到相關程式碼的。直到前不久看到老羅的視訊《Android原始碼情景分析法》,很有啟發。但是老羅也只是講到Java層的分析追蹤,在我的日常工作中,經常涉及從Java 層到JNI 層,再到Native層,經常追著追著就丟了。

之後我仿照老羅的方法,嘗試追蹤MediaRecorder的setVideoEncoder方法是怎麼實現的,現在總結如下。

準備:

  • Source Insight 3

  • Android Framework層原始碼

分析開始

首先看MediaRecorder.java內的setVideoEncoder方法:

    /**
     * Sets the video encoder to be used for recording. If this method is not
     * called, the output file will not contain an video track. Call this after
     * setOutputFormat() and before prepare().
     *
     * @param video_encoder the video encoder to use.
     * @throws
IllegalStateException if it is called before * setOutputFormat() or after prepare() * @see android.media.MediaRecorder.VideoEncoder */
public native void setVideoEncoder(int video_encoder) throws IllegalStateException;

這是一個native方法,根據JNI的規則,我們應該去android_media_MediaRecorder.cpp裡看這個方法的實現:

static void
android_media_MediaRecorder_setVideoEncoder(JNIEnv *env, jobject thiz, jint ve)
{
    ALOGV("setVideoEncoder(%d)", ve);
    if (ve < VIDEO_ENCODER_DEFAULT || ve >= VIDEO_ENCODER_LIST_END) {
        jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video encoder");
        return;
    }
    sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
    process_media_recorder_call(env, mr->setVideoEncoder(ve), "java/lang/RuntimeException", "setVideoEncoder failed.");
}

關鍵是最後的兩句,sp是Android 裡的一個指標,就當沒看見~ 所以最後兩句的意思是呼叫Native層的MediaRecorder的setVideoEncoder方法。

繼續去MediaRecorder.cpp裡看setVideoEncoder方法:

status_t MediaRecorder::setVideoEncoder(int ve)
{
    ALOGV("setVideoEncoder(%d)", ve);
    if (mMediaRecorder == NULL) {
        ALOGE("media recorder is not initialized yet");
        return INVALID_OPERATION;
    }
    if (!mIsVideoSourceSet) {
        ALOGE("try to set the video encoder without setting the video source first");
        return INVALID_OPERATION;
    }
    if (mIsVideoEncoderSet) {
        ALOGE("video encoder has already been set");
        return INVALID_OPERATION;
    }
    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
        ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
        return INVALID_OPERATION;
    }

    status_t ret = mMediaRecorder->setVideoEncoder(ve);
    if (OK != ret) {
        ALOGV("setVideoEncoder failed: %d", ret);
        mCurrentState = MEDIA_RECORDER_ERROR;
        return ret;
    }
    mIsVideoEncoderSet = true;
    return ret;
}

這裡的mMediaReocorder定義在MediaRecorder.h裡:

sp<IMediaRecorder>          mMediaRecorder;

可見其是一個IMediaRecorder型別的變數,這是一個介面型別,看一下其介面定義,在IMediaRecorder.h中:

class IMediaRecorder: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaRecorder);

    virtual status_t setCamera(const sp<hardware::ICamera>& camera,
                               const sp<ICameraRecordingProxy>& proxy) = 0;
    virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) = 0;
    virtual status_t setVideoSource(int vs) = 0;
    virtual status_t setAudioSource(int as) = 0;
    virtual status_t setOutputFormat(int of) = 0;
    virtual status_t setVideoEncoder(int ve) = 0;
    virtual status_t setAudioEncoder(int ae) = 0;
    virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
    virtual status_t setVideoSize(int width, int height) = 0;
    virtual status_t setVideoFrameRate(int frames_per_second) = 0;
    virtual status_t setParameters(const String8& params) = 0;
    virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
    virtual status_t setClientName(const String16& clientName) = 0;
    virtual status_t prepare() = 0;
    virtual status_t getMaxAmplitude(int* max) = 0;
    virtual status_t start() = 0;
    virtual status_t stop() = 0;
    virtual status_t reset() = 0;
    virtual status_t pause() = 0;
    virtual status_t resume() = 0;
    virtual status_t init() = 0;
    virtual status_t close() = 0;
    virtual status_t release() = 0;
    virtual status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface) = 0;
    virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
};

// ----------------------------------------------------------------------------

class BnMediaRecorder: public BnInterface<IMediaRecorder>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

吶~關鍵的步驟來了,在以前我基本就追到這,就算完蛋了,不知道怎麼繼續往下追了,後來看Binder相關的內容,知道了BnInterface的作用,這是Binder中關鍵的一環,我們這就不展開講了,只要記得,接下來我們要追的是BnMediaRecorder這個類。

全域性搜尋一下“: public BnMediaRecorder”,也就是去找它的實現類,發現在MediaRecorderClient.h當中有如下的定義:

class MediaRecorderClient : public BnMediaRecorder
{
    class ServiceDeathNotifier: public IBinder::DeathRecipient
    {
    public:
        ServiceDeathNotifier(
                const sp<IBinder>& service,
                const sp<IMediaRecorderClient>& listener,
                int which);
        virtual ~ServiceDeathNotifier();
        virtual void binderDied(const wp<IBinder>& who);

    private:
        int mWhich;
        sp<IBinder> mService;
        wp<IMediaRecorderClient> mListener;
    };

public:
    virtual     status_t   setCamera(const sp<hardware::ICamera>& camera,
                                    const sp<ICameraRecordingProxy>& proxy);
    virtual     status_t   setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
    virtual     status_t   setVideoSource(int vs);
    virtual     status_t   setAudioSource(int as);
    virtual     status_t   setOutputFormat(int of);
    virtual     status_t   setVideoEncoder(int ve);
    virtual     status_t   setAudioEncoder(int ae);
    virtual     status_t   setOutputFile(int fd, int64_t offset,
                                                  int64_t length);
    virtual     status_t   setVideoSize(int width, int height);
    virtual     status_t   setVideoFrameRate(int frames_per_second);
    virtual     status_t   setParameters(const String8& params);
    virtual     status_t   setListener(
                              const sp<IMediaRecorderClient>& listener);
    virtual     status_t   setClientName(const String16& clientName);
    virtual     status_t   prepare();
    virtual     status_t   getMaxAmplitude(int* max);
    virtual     status_t   start();
    virtual     status_t   stop();
    virtual     status_t   reset();
    virtual     status_t   pause();
    virtual     status_t   resume();
    virtual     status_t   init();
    virtual     status_t   close();
    virtual     status_t   release();
    virtual     status_t   dump(int fd, const Vector<String16>& args);
    virtual     status_t   setInputSurface(const sp<IGraphicBufferConsumer>& surface);
    virtual     sp<IGraphicBufferProducer> querySurfaceMediaSource();

private:
    friend class           MediaPlayerService;  // for accessing private constructor

                           MediaRecorderClient(
                                   const sp<MediaPlayerService>& service,
                                                               pid_t pid,
                                                               const String16& opPackageName);
    virtual                ~MediaRecorderClient();

    sp<IBinder::DeathRecipient> mCameraDeathListener;
    sp<IBinder::DeathRecipient> mCodecDeathListener;

    pid_t                  mPid;
    Mutex                  mLock;
    MediaRecorderBase      *mRecorder;
    sp<MediaPlayerService> mMediaPlayerService;
};

那麼我們去MediaRecorderClient.cpp裡看看:

status_t MediaRecorderClient::setVideoEncoder(int ve)
{
    ALOGV("setVideoEncoder(%d)", ve);
    Mutex::Autolock lock(mLock);
    if (mRecorder == NULL) {
        ALOGE("recorder is not initialized");
        return NO_INIT;
    }
    return mRecorder->setVideoEncoder((video_encoder)ve);
}

這裡的mRecorder 定義在MediaRecorderClient.h當中:

MediaRecorderBase      *mRecorder;

來,我們繼續搜尋“: public MediaRecorderBase”,在StagefrightRecorder.h中找到了,那麼我們去StagefrightRecorder.cpp當中看看~

status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
    ALOGV("setVideoEncoder: %d", ve);
    if (ve < VIDEO_ENCODER_DEFAULT ||
        ve >= VIDEO_ENCODER_LIST_END) {
        ALOGE("Invalid video encoder: %d", ve);
        return BAD_VALUE;
    }

    mVideoEncoder = ve;

    return OK;
}

吶,這就算完了~最後我們會發現MediaRecorder中的介面實現基本到最後都會落在這個StagefrightRecorder.cpp當中。

總結

在Android原始碼閱讀當中,由於大多數人都沒接觸過大型的C++工程,所以在Native層的追蹤上一開始會有較大困難,但只要靜下心來,會發現其實只要記住C++的繼承、實現、介面的相關概念,和一般的讀程式碼沒啥區別。