static jobject
android_media_MediaExtractor_native_getMetrics(JNIEnv * env, jobject thiz)
{
    ALOGV("android_media_MediaExtractor_native_getMetrics");

    sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
    if (extractor == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return NULL;
    }

    // get what we have for the metrics from the codec
    Parcel reply;
    status_t err = extractor->getMetrics(&reply);
    if (err != OK) {
        ALOGE("getMetrics failed");
        return (jobject) NULL;
    }

    // build and return the Bundle
    MediaAnalyticsItem *item = new MediaAnalyticsItem;
    item->readFromParcel(reply);
    jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL);

    // housekeeping
    delete item;
    item = NULL;

    return mybundle;
}
status_t BnMediaAnalyticsService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{


    // get calling pid/tid
    IPCThreadState *ipc = IPCThreadState::self();
    int clientPid = ipc->getCallingPid();
    // permission checking

    if(DEBUGGING_FLOW) {
        ALOGD("running in service, code %d, pid %d; called from pid %d",
            code, getpid(), clientPid);
    }

    switch (code) {

        case GENERATE_UNIQUE_SESSIONID: {
            CHECK_INTERFACE(IMediaAnalyticsService, data, reply);

            MediaAnalyticsItem::SessionID_t sessionid = generateUniqueSessionID();
            reply->writeInt64(sessionid);

            return NO_ERROR;
        } break;

        case SUBMIT_ITEM: {
            CHECK_INTERFACE(IMediaAnalyticsService, data, reply);

            bool forcenew;
            MediaAnalyticsItem *item = new MediaAnalyticsItem;

            data.readBool(&forcenew);
            item->readFromParcel(data);

            item->setPid(clientPid);

            // submit() takes over ownership of 'item'
            MediaAnalyticsItem::SessionID_t sessionid = submit(item, forcenew);
            reply->writeInt64(sessionid);

            return NO_ERROR;
        } break;

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}