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

Commit ca3b6609 authored by Yifan Hong's avatar Yifan Hong
Browse files

lshal: fix file streams for testing.

* If a file is specified for list, the file is opened and
  closed within the ListCommand::dump() function.

* Add a missing break in ListCommand::parseArgs, case
  for '--init-vintf'

Test: lshal_test
Test: lshal --init-vintf
Test: lshal --init-vintf=/data/data/a.xml ; adb shell cat \
      /data/data/a.xml
Test: lshal -d
Test: lshal --debug=/data/data/d.txt ; adb shell cat \
      /data/data/d.txt

Change-Id: I1acee5878638d25257a13244713dc416e9d8d6b2
parent 76ac14a1
Loading
Loading
Loading
Loading
+46 −53
Original line number Diff line number Diff line
@@ -212,6 +212,18 @@ void ListCommand::postprocess() {
            }
        }
    }

    mServicesTable.setDescription(
            "All binderized services (registered services through hwservicemanager)");
    mPassthroughRefTable.setDescription(
            "All interfaces that getService() has ever return as a passthrough interface;\n"
            "PIDs / processes shown below might be inaccurate because the process\n"
            "might have relinquished the interface or might have died.\n"
            "The Server / Server CMD column can be ignored.\n"
            "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
            "the library and successfully fetched the passthrough implementation.");
    mImplementationsTable.setDescription(
            "All available passthrough implementations (all -impl.so files)");
}

static inline bool findAndBumpVersion(vintf::ManifestHal* hal, const vintf::Version& version) {
@@ -224,9 +236,9 @@ static inline bool findAndBumpVersion(vintf::ManifestHal* hal, const vintf::Vers
    return false;
}

void ListCommand::dumpVintf() const {
void ListCommand::dumpVintf(const NullableOStream<std::ostream>& out) const {
    using vintf::operator|=;
    mOut << "<!-- " << std::endl
    out << "<!-- " << std::endl
         << "    This is a skeleton device manifest. Notes: " << std::endl
         << "    1. android.hidl.*, android.frameworks.*, android.system.* are not included." << std::endl
         << "    2. If a HAL is supported in both hwbinder and passthrough transport, " << std::endl
@@ -334,7 +346,7 @@ void ListCommand::dumpVintf() const {
            }
        }
    });
    mOut << vintf::gHalManifestConverter(manifest);
    out << vintf::gHalManifestConverter(manifest);
}

static Architecture fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo::Architecture a) {
@@ -349,26 +361,14 @@ static Architecture fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo:
    }
}

void ListCommand::dumpTable() {
void ListCommand::dumpTable(const NullableOStream<std::ostream>& out) const {
    if (mNeat) {
        MergedTable({&mServicesTable, &mPassthroughRefTable, &mImplementationsTable})
            .createTextTable().dump(mOut.buf());
            .createTextTable().dump(out.buf());
        return;
    }

    mServicesTable.setDescription(
            "All binderized services (registered services through hwservicemanager)");
    mPassthroughRefTable.setDescription(
            "All interfaces that getService() has ever return as a passthrough interface;\n"
            "PIDs / processes shown below might be inaccurate because the process\n"
            "might have relinquished the interface or might have died.\n"
            "The Server / Server CMD column can be ignored.\n"
            "The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
            "the library and successfully fetched the passthrough implementation.");
    mImplementationsTable.setDescription(
            "All available passthrough implementations (all -impl.so files)");

    forEachTable([this](const Table &table) {
    forEachTable([this, &out](const Table &table) {

        // We're only interested in dumping debug info for already
        // instantiated services. There's little value in dumping the
@@ -377,30 +377,38 @@ void ListCommand::dumpTable() {
        std::function<std::string(const std::string&)> emitDebugInfo = nullptr;
        if (mEmitDebugInfo && &table == &mServicesTable) {
            emitDebugInfo = [this](const auto& iName) {
                std::stringstream out;
                std::stringstream ss;
                auto pair = splitFirst(iName, '/');
                mLshal.emitDebugInfo(pair.first, pair.second, {}, out,
                mLshal.emitDebugInfo(pair.first, pair.second, {}, ss,
                                     NullableOStream<std::ostream>(nullptr));
                return out.str();
                return ss.str();
            };
        }
        table.createTextTable(mNeat, emitDebugInfo).dump(mOut.buf());
        mOut << std::endl;
        table.createTextTable(mNeat, emitDebugInfo).dump(out.buf());
        out << std::endl;
    });
}

void ListCommand::dump() {
    if (mVintf) {
        dumpVintf();
        if (!!mFileOutput) {
            mFileOutput.buf().close();
            delete &mFileOutput.buf();
            mFileOutput = nullptr;
Status ListCommand::dump() {
    auto dump = mVintf ? &ListCommand::dumpVintf : &ListCommand::dumpTable;

    if (mFileOutputPath.empty()) {
        (*this.*dump)(out());
        return OK;
    }
        mOut = std::cout;
    } else {
        dumpTable();

    std::ofstream fileOutput(mFileOutputPath);
    if (!fileOutput.is_open()) {
        err() << "Could not open file '" << mFileOutputPath << "'." << std::endl;
        return IO_ERROR;
    }
    chown(mFileOutputPath.c_str(), AID_SHELL, AID_SHELL);

    (*this.*dump)(NullableOStream<std::ostream>(fileOutput));

    fileOutput.flush();
    fileOutput.close();
    return OK;
}

void ListCommand::putEntry(TableEntrySource source, TableEntry &&entry) {
@@ -647,15 +655,9 @@ Status ListCommand::parseArgs(const std::string &command, const Arg &arg) {
            break;
        }
        case 'v': {
            if (optarg) {
                mFileOutput = new std::ofstream{optarg};
                mOut = mFileOutput;
                if (!mFileOutput.buf().is_open()) {
                    mErr << "Could not open file '" << optarg << "'." << std::endl;
                    return IO_ERROR;
                }
            }
            mVintf = true;
            if (optarg) mFileOutputPath = optarg;
            break;
        }
        case 'i': {
            selectedColumns.push_back(TableColumnType::INTERFACE_NAME);
@@ -691,16 +693,7 @@ Status ListCommand::parseArgs(const std::string &command, const Arg &arg) {
        }
        case 'd': {
            mEmitDebugInfo = true;

            if (optarg) {
                mFileOutput = new std::ofstream{optarg};
                mOut = mFileOutput;
                if (!mFileOutput.buf().is_open()) {
                    mErr << "Could not open file '" << optarg << "'." << std::endl;
                    return IO_ERROR;
                }
                chown(optarg, AID_SHELL, AID_SHELL);
            }
            if (optarg) mFileOutputPath = optarg;
            break;
        }
        case 'n': {
@@ -756,7 +749,7 @@ Status ListCommand::main(const std::string &command, const Arg &arg) {
    }
    status = fetch();
    postprocess();
    dump();
    status |= dump();
    return status;
}

+4 −4
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ private:
    Status parseArgs(const std::string &command, const Arg &arg);
    Status fetch();
    void postprocess();
    void dump();
    Status dump();
    void putEntry(TableEntrySource source, TableEntry &&entry);
    Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
    Status fetchBinderized(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
@@ -57,8 +57,8 @@ private:
    };
    bool getPidInfo(pid_t serverPid, PidInfo *info) const;

    void dumpTable();
    void dumpVintf() const;
    void dumpTable(const NullableOStream<std::ostream>& out) const;
    void dumpVintf(const NullableOStream<std::ostream>& out) const;
    void addLine(TextTable *table, const std::string &interfaceName, const std::string &transport,
                 const std::string &arch, const std::string &threadUsage, const std::string &server,
                 const std::string &serverCmdline, const std::string &address,
@@ -81,7 +81,7 @@ private:
    Table mPassthroughRefTable{};
    Table mImplementationsTable{};

    NullableOStream<std::ofstream> mFileOutput = nullptr;
    std::string mFileOutputPath;
    TableEntryCompare mSortColumn = nullptr;

    bool mEmitDebugInfo = false;