Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d453830 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

Camera3Device: Add dumpsys monitoring of request/result metadata

Add new -m dumpsys option to cameraservice dump for monitoring
changes in selected metadata values in requests and results.

This option takes a comma-separated list of metadata keys, or the
shortcut value "3a", which expands to all the "android.control" tags.

In subsequent dumpsys calls, the last 100 changes to the tags being
monitored are listed.

The monitoring must be turned on once the camera device is running.

Bug:
Change-Id: If8938b30611ccafa86c2c4a06e57fc72680f827b
parent cecb30a2
Loading
Loading
Loading
Loading
+109 −1
Original line number Diff line number Diff line
@@ -20,8 +20,9 @@
#include <utils/Log.h>
#include <utils/Errors.h>

#include <camera/CameraMetadata.h>
#include <binder/Parcel.h>
#include <camera/CameraMetadata.h>
#include <camera/VendorTagDescriptor.h>

namespace android {

@@ -277,6 +278,18 @@ status_t CameraMetadata::update(uint32_t tag,
    return updateImpl(tag, (const void*)string.string(), string.size() + 1);
}

status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
    status_t res;
    if (mLocked) {
        ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
        return INVALID_OPERATION;
    }
    if ( (res = checkType(entry.tag, entry.type)) != OK) {
        return res;
    }
    return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
}

status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
        size_t data_count) {
    status_t res;
@@ -681,4 +694,99 @@ void CameraMetadata::swap(CameraMetadata& other) {
    mBuffer = otherBuf;
}

status_t CameraMetadata::getTagFromName(const char *name,
        const VendorTagDescriptor* vTags, uint32_t *tag) {

    if (name == nullptr || tag == nullptr) return BAD_VALUE;

    size_t nameLength = strlen(name);

    const SortedVector<String8> *vendorSections;
    size_t vendorSectionCount = 0;

    if (vTags != NULL) {
        vendorSections = vTags->getAllSectionNames();
        vendorSectionCount = vendorSections->size();
    }

    // First, find the section by the longest string match
    const char *section = NULL;
    size_t sectionIndex = 0;
    size_t sectionLength = 0;
    size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
    for (size_t i = 0; i < totalSectionCount; ++i) {

        const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
                (*vendorSections)[i - ANDROID_SECTION_COUNT].string();

        ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);

        if (strstr(name, str) == name) { // name begins with the section name
            size_t strLength = strlen(str);

            ALOGV("%s: Name begins with section name", __FUNCTION__);

            // section name is the longest we've found so far
            if (section == NULL || sectionLength < strLength) {
                section = str;
                sectionIndex = i;
                sectionLength = strLength;

                ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
            }
        }
    }

    // TODO: Make above get_camera_metadata_section_from_name ?

    if (section == NULL) {
        return NAME_NOT_FOUND;
    } else {
        ALOGV("%s: Found matched section '%s' (%zu)",
              __FUNCTION__, section, sectionIndex);
    }

    // Get the tag name component of the name
    const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
    if (sectionLength + 1 >= nameLength) {
        return BAD_VALUE;
    }

    // Match rest of name against the tag names in that section only
    uint32_t candidateTag = 0;
    if (sectionIndex < ANDROID_SECTION_COUNT) {
        // Match built-in tags (typically android.*)
        uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
        tagBegin = camera_metadata_section_bounds[sectionIndex][0];
        tagEnd = camera_metadata_section_bounds[sectionIndex][1];

        for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
            const char *tagName = get_camera_metadata_tag_name(candidateTag);

            if (strcmp(nameTagName, tagName) == 0) {
                ALOGV("%s: Found matched tag '%s' (%d)",
                      __FUNCTION__, tagName, candidateTag);
                break;
            }
        }

        if (candidateTag == tagEnd) {
            return NAME_NOT_FOUND;
        }
    } else if (vTags != NULL) {
        // Match vendor tags (typically com.*)
        const String8 sectionName(section);
        const String8 tagName(nameTagName);

        status_t res = OK;
        if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
            return NAME_NOT_FOUND;
        }
    }

    *tag = candidateTag;
    return OK;
}


}; // namespace android
+2 −2
Original line number Diff line number Diff line
@@ -280,8 +280,8 @@ status_t VendorTagDescriptor::writeToParcel(Parcel* parcel) const {
    return res;
}

SortedVector<String8> VendorTagDescriptor::getAllSectionNames() const {
    return mSections;
const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
    return &mSections;
}

status_t VendorTagDescriptor::lookupTag(String8 name, String8 section, /*out*/uint32_t* tag) const {
+14 −0
Original line number Diff line number Diff line
@@ -18,12 +18,15 @@
#define ANDROID_CLIENT_CAMERA2_CAMERAMETADATA_CPP

#include "system/camera_metadata.h"

#include <utils/String8.h>
#include <utils/Vector.h>
#include <binder/Parcelable.h>

namespace android {

class VendorTagDescriptor;

/**
 * A convenience wrapper around the C-based camera_metadata_t library.
 */
@@ -137,6 +140,8 @@ class CameraMetadata: public Parcelable {
            const camera_metadata_rational_t *data, size_t data_count);
    status_t update(uint32_t tag,
            const String8 &string);
    status_t update(const camera_metadata_ro_entry &entry);


    template<typename T>
    status_t update(uint32_t tag, Vector<T> data) {
@@ -206,6 +211,15 @@ class CameraMetadata: public Parcelable {
    static status_t writeToParcel(Parcel &parcel,
                                  const camera_metadata_t* metadata);

    /**
     * Find tag id for a given tag name, also checking vendor tags if available.
     * On success, returns OK and writes the tag id into tag.
     *
     * This is a slow method.
     */
    static status_t getTagFromName(const char *name,
            const VendorTagDescriptor* vTags, uint32_t *tag);

  private:
    camera_metadata_t *mBuffer;
    mutable bool       mLocked;
+3 −1
Original line number Diff line number Diff line
@@ -81,8 +81,10 @@ class VendorTagDescriptor : public Parcelable {
        /**
         * Convenience method to get a vector containing all vendor tag
         * sections, or an empty vector if none are defined.
         * The pointer is valid for the lifetime of the VendorTagDescriptor,
         * or until readParcel or copyFrom is invoked.
         */
        SortedVector<String8> getAllSectionNames() const;
        const SortedVector<String8>* getAllSectionNames() const;

        /**
         * Lookup the tag id for a given tag name and section.
+2 −1
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@ LOCAL_SRC_FILES := \
    device3/Camera3BufferManager.cpp \
    gui/RingBufferConsumer.cpp \
    utils/CameraTraces.cpp \
    utils/AutoConditionLock.cpp
    utils/AutoConditionLock.cpp \
    utils/TagMonitor.cpp

LOCAL_SHARED_LIBRARIES:= \
    libui \
Loading