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

Commit 52d0b67f authored by Josh Gao's avatar Josh Gao
Browse files

adbd: add runtime-configurable logging.

Add some requested logging options that can be turned on at runtime
without having to restart adbd.

Bug: http://b/141959374
Test: manual
Change-Id: Ib97acc6d199e0b91238a6758e18b7cb75f8688d9
parent e3d34e1f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -375,6 +375,7 @@ cc_library_static {
    srcs: libadb_srcs + libadb_linux_srcs + libadb_posix_srcs + [
        "daemon/auth.cpp",
        "daemon/jdwp_service.cpp",
        "daemon/logging.cpp",
        "daemon/adb_wifi.cpp",
    ],

+6 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <condition_variable>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>
#include <vector>

@@ -61,6 +62,8 @@
#include <sys/mount.h>
#include <android-base/properties.h>
using namespace std::chrono_literals;

#include "daemon/logging.h"
#endif

std::string adb_version() {
@@ -312,6 +315,9 @@ static void handle_new_connection(atransport* t, apacket* p) {
#if ADB_HOST
    handle_online(t);
#else
    ADB_LOG(Connection) << "received CNXN: version=" << p->msg.arg0 << ", maxdata = " << p->msg.arg1
                        << ", banner = '" << banner << "'";

    if (t->use_tls) {
        // We still handshake in TLS mode. If auth_required is disabled,
        // we'll just not verify the client's certificate. This should be the

adb/daemon/logging.cpp

0 → 100644
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 "daemon/logging.h"

#include <mutex>
#include <optional>
#include <string_view>

#include <android-base/no_destructor.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/thread_annotations.h>

#if defined(__ANDROID__)
struct LogStatus {
    bool enabled[static_cast<size_t>(adb::LogType::COUNT)];

    bool& operator[](adb::LogType type) { return enabled[static_cast<size_t>(type)]; }
};

using android::base::CachedProperty;
using android::base::NoDestructor;

static NoDestructor<std::mutex> log_mutex;
static NoDestructor<CachedProperty> log_property GUARDED_BY(log_mutex)("debug.adbd.logging");
static std::optional<LogStatus> cached_log_status GUARDED_BY(log_mutex);

static NoDestructor<CachedProperty> persist_log_property
        GUARDED_BY(log_mutex)("persist.debug.adbd.logging");
static std::optional<LogStatus> cached_persist_log_status GUARDED_BY(log_mutex);

static LogStatus ParseLogStatus(std::string_view str) {
    LogStatus result = {};
    for (const auto& part : android::base::Split(std::string(str), ",")) {
        if (part == "cnxn") {
            result[adb::LogType::Connection] = true;
        } else if (part == "service") {
            result[adb::LogType::Service] = true;
        } else if (part == "shell") {
            result[adb::LogType::Shell] = true;
        } else if (part == "all") {
            result[adb::LogType::Connection] = true;
            result[adb::LogType::Service] = true;
            result[adb::LogType::Shell] = true;
        }
    }
    return result;
}

static LogStatus GetLogStatus(android::base::CachedProperty* property,
                              std::optional<LogStatus>* cached_status) REQUIRES(log_mutex) {
    bool changed;
    const char* value = property->Get(&changed);
    if (changed || !*cached_status) {
        **cached_status = ParseLogStatus(value);
    }
    return **cached_status;
}

namespace adb {
bool is_logging_enabled(LogType type) {
    std::lock_guard<std::mutex> lock(*log_mutex);
    return GetLogStatus(log_property.get(), &cached_log_status)[type] ||
           GetLogStatus(persist_log_property.get(), &cached_persist_log_status)[type];
}
}  // namespace adb

#else

namespace adb {
bool is_logging_enabled(LogType type) {
    return false;
}
}  // namespace adb
#endif

adb/daemon/logging.h

0 → 100644
+33 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 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.
 */

#pragma once

#include <android-base/logging.h>

namespace adb {
enum class LogType {
    Connection,
    Service,
    Shell,
    COUNT,
};

bool is_logging_enabled(LogType type);

#define ADB_LOG(type) ::adb::is_logging_enabled(::adb::LogType::type) && LOG(INFO)

}  // namespace adb
+3 −1
Original line number Diff line number Diff line
@@ -54,10 +54,10 @@

#include "daemon/file_sync_service.h"
#include "daemon/framebuffer_service.h"
#include "daemon/logging.h"
#include "daemon/restart_service.h"
#include "daemon/shell_service.h"


void reconnect_service(unique_fd fd, atransport* t) {
    WriteFdExactly(fd.get(), "done");
    kick_transport(t);
@@ -259,6 +259,8 @@ asocket* daemon_service_to_socket(std::string_view name) {
}

unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
    ADB_LOG(Service) << "transport " << transport->serial_name() << " opening service " << name;

#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
    if (name.starts_with("abb:") || name.starts_with("abb_exec:")) {
        return execute_abb_command(name);
Loading