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

Commit e69d2ec5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes Ib576b7e3,Ie8bdc6b3

* changes:
  leaudio: Add history logs
  leaudio: Add implementation of LeAudioHistory
parents 65936719 c4a6ed59
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ cc_library_static {
        "le_audio/client_parser.cc",
        "le_audio/audio_hal_client/audio_sink_hal_client.cc",
        "le_audio/audio_hal_client/audio_source_hal_client.cc",
        "le_audio/le_audio_log_history.cc",
        "le_audio/le_audio_utils.cc",
        "le_audio/le_audio_set_configuration_provider.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
@@ -585,6 +586,7 @@ cc_test {
        "le_audio/content_control_id_keeper_test.cc",
        "le_audio/devices.cc",
        "le_audio/devices_test.cc",
        "le_audio/le_audio_log_history.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
        "le_audio/le_audio_types.cc",
        "le_audio/le_audio_types_test.cc",
@@ -655,6 +657,7 @@ cc_test {
        "le_audio/client_parser.cc",
        "le_audio/content_control_id_keeper.cc",
        "le_audio/devices.cc",
        "le_audio/le_audio_log_history.cc",
        "le_audio/le_audio_utils.cc",
        "le_audio/le_audio_client_test.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
+1 −0
Original line number Diff line number Diff line
@@ -5177,6 +5177,7 @@ void LeAudioClient::DebugDump(int fd) {
  LeAudioSourceAudioHalClient::DebugDump(fd);
  le_audio::AudioSetConfigurationProvider::DebugDump(fd);
  IsoManager::GetInstance()->Dump(fd);
  LeAudioLogHistory::DebugDump(fd);
  dprintf(fd, "\n");
}

+5 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "btm_iso_api_types.h"
#include "device/include/controller.h"
#include "gd/common/strings.h"
#include "le_audio_log_history.h"
#include "le_audio_set_configuration_provider.h"
#include "metrics_collector.h"
#include "osi/include/log.h"
@@ -2168,6 +2169,10 @@ void LeAudioDevice::SetConnectionState(DeviceConnectState state) {
  LOG_DEBUG("%s, %s --> %s", ADDRESS_TO_LOGGABLE_CSTR(address_),
            bluetooth::common::ToString(connection_state_).c_str(),
            bluetooth::common::ToString(state).c_str());
  LeAudioLogHistory::Get()->AddLogHistory(
      kLogConnectionTag, group_id_, address_,
      bluetooth::common::ToString(connection_state_) + " -> ",
      "->" + bluetooth::common::ToString(state));
  connection_state_ = state;
}

+11 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@
#include "bta_groups.h"
#include "btm_iso_api_types.h"
#include "gatt_api.h"
#include "gd/common/strings.h"
#include "le_audio_log_history.h"
#include "le_audio_types.h"
#include "osi/include/alarm.h"
#include "osi/include/properties.h"
@@ -353,6 +355,10 @@ class LeAudioDeviceGroup {
  void SetState(types::AseState state) {
    LOG(INFO) << __func__ << " current state: " << current_state_
              << " new state: " << state;
    LeAudioLogHistory::Get()->AddLogHistory(
        kLogStateMachineTag, group_id_, RawAddress::kEmpty, kLogStateChangedOp,
        bluetooth::common::ToString(current_state_) + "->" +
            bluetooth::common::ToString(state));
    current_state_ = state;
  }

@@ -360,6 +366,11 @@ class LeAudioDeviceGroup {
  void SetTargetState(types::AseState state) {
    LOG(INFO) << __func__ << " target state: " << target_state_
              << " new target state: " << state;
    LeAudioLogHistory::Get()->AddLogHistory(
        kLogStateMachineTag, group_id_, RawAddress::kEmpty,
        kLogTargetStateChangedOp,
        bluetooth::common::ToString(target_state_) + "->" +
            bluetooth::common::ToString(state));
    target_state_ = state;
  }

+147 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "le_audio_log_history.h"

#include <base/logging.h>

#include <cstdint>
#include <memory>
#include <string>

#include "gd/common/circular_buffer.h"
#include "gd/common/strings.h"
#include "main/shim/dumpsys.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"

constexpr size_t kMaxLogSize = 255;
constexpr size_t kLeAudioLogHistoryBufferSize = 200;

class TimestampedStringCircularBuffer
    : public bluetooth::common::TimestampedCircularBuffer<std::string> {
 public:
  explicit TimestampedStringCircularBuffer(size_t size)
      : bluetooth::common::TimestampedCircularBuffer<std::string>(size) {}

  void Push(const std::string& s) {
    bluetooth::common::TimestampedCircularBuffer<std::string>::Push(
        s.substr(0, kMaxLogSize));
  }

  template <typename... Args>
  void Push(Args... args) {
    char buf[kMaxLogSize];
    std::snprintf(buf, sizeof(buf), args...);
    bluetooth::common::TimestampedCircularBuffer<std::string>::Push(
        std::string(buf));
  }
};

class LeAudioLogHistoryImpl;
LeAudioLogHistoryImpl* instance;

constexpr size_t kMaxLogHistoryTagLength = 14;
constexpr size_t kMaxLogHistoryMsgLength = 44;
const std::string kTimeFormat("%Y-%m-%d %H:%M:%S");

using Record = bluetooth::common::TimestampedEntry<std::string>;

class LeAudioLogHistoryImpl : public LeAudioLogHistory {
 public:
  ~LeAudioLogHistoryImpl(void) { history_.reset(); }

  LeAudioLogHistoryImpl(void) {
    history_ = std::make_shared<TimestampedStringCircularBuffer>(
        kLeAudioLogHistoryBufferSize);
    CHECK(history_ != nullptr);
    history_->Push(std::string("Initialized le_audio history"));
  }

  void Dump(int fd) {
#define DUMPSYS_TAG "::le_audio"

    LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
    if (history_ == nullptr) {
      return;
    }
    std::vector<Record> history = history_->Pull();
    for (auto& record : history) {
      time_t then = record.timestamp / 1000;
      struct tm tm;
      localtime_r(&then, &tm);
      auto s2 = bluetooth::common::StringFormatTime(kTimeFormat, tm);
      LOG_DUMPSYS(fd, " %s.%03u %s", s2.c_str(),
                  static_cast<unsigned int>(record.timestamp % 1000),
                  record.entry.c_str());
    }
#undef DUMPSYS_TAG
  }

  void AddLogHistory(const std::string& tag, int group_id,
                     const RawAddress& addr, const std::string& msg,
                     const std::string& extra) {
    add_logs_history_common(tag, group_id, addr, msg, extra);
  }

  void AddLogHistory(const std::string& tag, int group_id,
                     const RawAddress& addr, const std::string& msg) {
    AddLogHistory(tag, group_id, addr, msg, std::string());
  }

 private:
  void add_logs_history_common(const std::string& tag, int group_id,
                               const RawAddress& addr, const std::string& msg,
                               const std::string& extra) {
    if (history_ == nullptr) {
      LOG_ERROR(
          "LeAudioLogHistory has not been constructed or already destroyed !");
      return;
    }

    history_->Push("%-*s GID %-3d  %-*s: %-22s %s", kMaxLogHistoryTagLength,
                   tag.substr(0, kMaxLogHistoryTagLength).c_str(), group_id,
                   kMaxLogHistoryMsgLength,
                   msg.substr(0, kMaxLogHistoryMsgLength).c_str(),
                   ADDRESS_TO_LOGGABLE_CSTR(addr), extra.c_str());
  }

  std::shared_ptr<TimestampedStringCircularBuffer> history_{nullptr};
};

LeAudioLogHistory* LeAudioLogHistory::Get(void) {
  if (instance) {
    return instance;
  }
  instance = new LeAudioLogHistoryImpl();
  return instance;
}

void LeAudioLogHistory::DebugDump(int fd) {
  if (instance) {
    instance->Dump(fd);
  }
}

void LeAudioLogHistory::Cleanup(void) {
  if (!instance) {
    return;
  }
  auto ptr = instance;
  instance = nullptr;
  delete ptr;
}
 No newline at end of file
Loading