blob: c2c865b66299cd25664bf6022fcabecd633766d8 [file] [log] [blame]
/*
* Copyright 2019 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef CAMERA_HAL_ADAPTER_CAMERA_METADATA_INSPECTOR_H_
#define CAMERA_HAL_ADAPTER_CAMERA_METADATA_INSPECTOR_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <base/files/file.h>
#include <base/sequence_checker.h>
#include <base/threading/thread.h>
#include <base/time/time.h>
#include <camera/camera_metadata.h>
#include <hardware/camera3.h>
#include <re2/re2.h>
namespace cros {
struct DiffData {
std::string key;
std::string old_val;
std::string new_val;
std::string FormatKey(int width);
std::string FormatValue(int width);
};
class CameraMetadataInspector {
public:
// Holds the string representation of the entries of a metadata.
using DataMap = std::map<std::string, std::string>;
// The factory function that creates a CameraMetadataInspector from the
// command line switches of the current process:
// --metadata_inspector_output=<path/to/output/file>
// --metadata_inspector_allowlist=<regex_filter> (optional)
// --metadata_inspector_denylist=<regex_filter> (optional)
// --metadata_inspector_position=<comma_separated_numbers> (optional)
// See the comments of |output_file_|, |allowlist_|, |denylist_| and
// |inspect_position_| below for more details. Returns nullptr on error.
static std::unique_ptr<CameraMetadataInspector> Create(
int partial_result_count);
// Disallow copy constructor and assign operator.
CameraMetadataInspector(const CameraMetadataInspector&) = delete;
CameraMetadataInspector& operator=(const CameraMetadataInspector&) = delete;
// Inspect a capture request and dump the difference from the previous one
// in |output_file_|.
void InspectRequest(const camera3_capture_request_t* request,
size_t position);
// Inspect a capture result and dump the difference from the previous one
// in |output_file_|. Partial results would be aggregated automatically, but
// the caller needs to guarantee it's called on the same sequence.
void InspectResult(const camera3_capture_result_t* result, size_t position);
// Whether a position should be inspected (see |inspect_positions_| comments
// for details).
bool IsPositionInspected(size_t position) const;
private:
enum class Kind { kRequest, kResult, kNumberOfKinds };
// The private constructor used in the factory function.
CameraMetadataInspector(int partial_result_count,
base::File output_file,
std::unique_ptr<RE2> allowlist,
std::unique_ptr<RE2> denylist,
std::set<size_t> inspect_positions,
std::unique_ptr<base::Thread> thread);
// Writes and flushes |msg| to |output_file_|.
void Write(base::StringPiece msg);
// Returns true if |key| should be ignored according to |allowlist_| and
// |denylist_|.
bool ShouldIgnoreKey(const std::string& key);
// Converts a metadata into the stringified DataMap.
DataMap MapFromMetadata(const camera_metadata_t* metadata);
// Compares two maps and returns a list of differences.
std::vector<DiffData> Compare(const DataMap& old_map, const DataMap& new_map);
// Compares the metadata with the previous one, and writes the formatted
// difference into |output_file_|.
void InspectOnThread(size_t position,
Kind kind,
const std::string& kind_tag,
int color,
base::Time time,
int frame_number,
camera_metadata_t* metadata);
// How many sub-components a result will be composed of at most.
int partial_result_count_;
// The output file for the inspector. Could be a special file such as
// /dev/stdout.
base::File output_file_;
// If specified, only metadata with keys matching the regular expression
// filter would be logged.
std::unique_ptr<RE2> allowlist_;
// If specified, only metadata with keys not matching the regular expression
// filter would be logged. Denylist could be used with allowlist, and only
// keys (in allowlist && not in the denylist) would be logged.
std::unique_ptr<RE2> denylist_;
// Specifies the positions to inspect metadata between the client, stream
// manipulators (SM), and the HAL. If there are N SMs, the values mean:
// 0 - between the client and the 1st SM;
// i - between the i-th SM and the (i+1)-th SM (0 < i < N);
// N - between the last SM and the HAL.
// If not specified, every position is inspected by default.
std::set<size_t> inspect_positions_;
// The latest DataMap for each kind of metadata for each position.
std::map<size_t,
std::array<DataMap, static_cast<size_t>(Kind::kNumberOfKinds)>>
latest_map_;
// The aggregated capture result for all current partial results.
base::Lock pending_result_lock_;
android::CameraMetadata pending_result_ GUARDED_BY(pending_result_lock_);
// The real work such as InspectOnThread() is running on |thread_|, so the
// capture flow won't be blocked by InspectRequest() and InspectResult().
std::unique_ptr<base::Thread> thread_;
};
} // namespace cros
#endif // CAMERA_HAL_ADAPTER_CAMERA_METADATA_INSPECTOR_H_