dbus-top: remove dbus-top from openbmc-tools

dbus-top has "graduated" from openbmc-tools and existing code has been
migrated to https://github.com/openbmc/dbus-top, so removing its folder
from openbmc-tools.

Signed-off-By: Sui Chen <suichen@google.com>
Change-Id: I1bccd8c01aa24f26b9904d5d5e7ae14205df5a84
diff --git a/dbus-top/.clang-format b/dbus-top/.clang-format
deleted file mode 100644
index 3652c56..0000000
--- a/dbus-top/.clang-format
+++ /dev/null
@@ -1,113 +0,0 @@
----
-Language:        Cpp
-# BasedOnStyle:  LLVM
-AccessModifierOffset: -2
-AlignAfterOpenBracket: Align
-AlignConsecutiveAssignments: false
-AlignConsecutiveDeclarations: false
-AlignEscapedNewlines: Right
-AlignOperands:   true
-AlignTrailingComments: true
-AllowAllParametersOfDeclarationOnNextLine: true
-AllowShortBlocksOnASingleLine: false
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: None
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: false
-AlwaysBreakTemplateDeclarations: Yes
-BinPackArguments: true
-BinPackParameters: true
-BraceWrapping:
-  AfterCaseLabel:  true
-  AfterClass:      true
-  AfterControlStatement: true
-  AfterEnum:       true
-  AfterFunction:   true
-  AfterNamespace:  true
-  AfterObjCDeclaration: true
-  AfterStruct:     true
-  AfterUnion:      true
-  AfterExternBlock: true
-  BeforeCatch:     true
-  BeforeElse:      true
-  IndentBraces:    false
-  SplitEmptyFunction:   false
-  SplitEmptyRecord:     false
-  SplitEmptyNamespace:  false
-BreakBeforeBinaryOperators: None
-BreakBeforeBraces: Custom
-BreakBeforeTernaryOperators: true
-BreakConstructorInitializers: AfterColon
-BreakInheritanceList: AfterColon
-BreakStringLiterals: true
-ColumnLimit:     80
-CommentPragmas:  '^ IWYU pragma:'
-CompactNamespaces: false
-ConstructorInitializerAllOnOneLineOrOnePerLine: false
-ConstructorInitializerIndentWidth: 4
-ContinuationIndentWidth: 4
-Cpp11BracedListStyle: true
-DerivePointerAlignment: false
-PointerAlignment: Left
-DisableFormat:   false
-ExperimentalAutoDetectBinPacking: false
-FixNamespaceComments: true
-ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
-IncludeBlocks: Regroup
-IncludeCategories:
-  - Regex:           '^[<"](gtest|gmock)'
-    Priority:        7
-  - Regex:           '^"config.h"'
-    Priority:        -1
-  - Regex:           '^".*\.h"'
-    Priority:        1
-  - Regex:           '^".*\.hpp"'
-    Priority:        2
-  - Regex:           '^<.*\.h>'
-    Priority:        3
-  - Regex:           '^<.*\.hpp>'
-    Priority:        4
-  - Regex:           '^<.*'
-    Priority:        5
-  - Regex:           '.*'
-    Priority:        6
-IndentCaseLabels: true
-IndentWidth:     4
-IndentWrappedFunctionNames: true
-KeepEmptyLinesAtTheStartOfBlocks: true
-MacroBlockBegin: ''
-MacroBlockEnd:   ''
-MaxEmptyLinesToKeep: 1
-NamespaceIndentation: None
-ObjCBlockIndentWidth: 2
-ObjCSpaceAfterProperty: false
-ObjCSpaceBeforeProtocolList: true
-PenaltyBreakBeforeFirstCallParameter: 19
-PenaltyBreakComment: 300
-PenaltyBreakFirstLessLess: 120
-PenaltyBreakString: 1000
-PenaltyExcessCharacter: 1000000
-PenaltyReturnTypeOnItsOwnLine: 60
-ReflowComments:  true
-SortIncludes:    true
-SortUsingDeclarations: true
-SpaceAfterCStyleCast: false
-SpaceAfterTemplateKeyword: true
-SpaceBeforeAssignmentOperators: true
-SpaceBeforeCpp11BracedList: false
-SpaceBeforeCtorInitializerColon: true
-SpaceBeforeInheritanceColon: true
-SpaceBeforeParens: ControlStatements
-SpaceBeforeRangeBasedForLoopColon: true
-SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 1
-SpacesInAngles:  false
-SpacesInContainerLiterals: true
-SpacesInCStyleCastParentheses: false
-SpacesInParentheses: false
-SpacesInSquareBrackets: false
-Standard:        Latest
-TabWidth:        4
-UseTab:          Never
diff --git a/dbus-top/.gitignore b/dbus-top/.gitignore
deleted file mode 100644
index a2ae220..0000000
--- a/dbus-top/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-oe-logs
-oe-workdir
-.vscode
diff --git a/dbus-top/README.md b/dbus-top/README.md
deleted file mode 100644
index b7be655..0000000
--- a/dbus-top/README.md
+++ /dev/null
@@ -1,214 +0,0 @@
-# Design Doc for dbus-top
-
-Author: Adedeji Adebisi (ziniblessed@google.com)
-
-Primary Assignee: Adedeji Adebisi
-
-Other contributors: Sui Chen (suichen@google.com) Alex Qiu (xqiu@google.com)
-
-Created: May 17, 2021
-
-## Problem Description
-
-Design and Implementation of a top-like tool for DBus. This tool shows metrics
-related to dbus connections such as message throughput, as well as system
-information available through DBus such as the list of sensors, in an attempt to
-understand some performance related issues on the BMC. The sensor information is
-extracted from well-known DBus services such as the Object Mapper, Inventory
-Manager, and Entity Manager. DBus-top shows the information conveniently that
-might otherwise require the user to type long commands or scripts.
-
-## Background and References
-
-This tool adds to the set of command-line based tools that run directly on the
-BMC. Using a tool that directly runs on the BMC, a user can debug problems
-in-situ, without needing to extract data from the BMC to the host for offline
-analysis. This tool resembles a typical top-like user interface, giving the user
-a top-down view of various DBus states. This tool is designed in the same logic
-as similarly-purposed, existing tools, each focusing on one particular field
-such as ctop (for containers), htop (for viewing process stats), iotop (for I/O
-throughput), iftop (for network traffic).
-
-## Requirements
-
-Constraints:
-
-1. BMC consoles may not be capable of displaying all text styles supported in
-   ncurses Dependency on libncurses which might add ~130KB overhead to the BMC’s
-   Flash space.
-2. Monitoring DBus should not incur so much performance overhead as to distort
-   measured values.
-3. Users are OpenBMC users and developers: This tool should help beginners learn
-   the basics of OpenBMC, as well as help seasoned developers quickly locate a
-   problem.
-
-Scope:
-
-1. This tool is standalone, self-sufficient, with minimum dependency on existing
-   software packages (only depends on basic packages like systemd, libdbus,
-   sdbus, sdbusplus, and libncurses.) Data size, transaction rates, bandwidth:
-   We will be looking at typically hundreds of DBus messages per second and
-   around 1 MB/s data throughput. The BMC’s processing power and memory capacity
-   are sufficient for the scale of the data this tool is processing.
-2. This tool should work on a live DBus as well as on a capture file (a pcap
-   file).
-3. This tool should work both on the host or the BMC. The UI design is scaled to
-   work with large numbers of sensors and different console sizes.
-
-## Proposed Design
-
-The proposed design is to layout a multi-window UI similar to how a tiled window
-manager does:
-
-```text
-+----------------------------------------------------------------------------+
-|Message Type          | msg/s        History                 (Total msg/s)  |
-|Method Call             45.00        -  .       .       .       .    -2300  |
-|Method Return           45.00        -  :       :       :       :    -1750  |
-|Signal                  53.00        -  :       :       :       :    -1200  |
-|Error                    0.00        -  :       :       :       :    -650   |
-|Total                  142.99        -:::.....:::.....:::.....:::....-100   |
-+-------------------------------------+--------------------------------------+
-| Columns 1-2 of 6      84 sensors    |   Msg/s   Sender  Destination        |
-|   vddq_efgh_out     vddcr_cpu1_in   |   7.50    :1.14   :1.48              |
-|   vddcr_cpu0_out    vddcr_soc1_out  |   7.50    :1.14   org.freedesktop.DB>|
-|   vddq_mnop_out     vddq_efgh_in    |   7.50    :1.48   :1.52              |
-|   vddcr_soc0_out    vddq_abcd_in    |   7.50    :1.48   org.freedesktop.DB>|
-|   vddq_ijkl_in      vddq_efgh_out   |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddcr_soc0_in     hotswap_pout    |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddcr_cpu0_in     vddcr_cpu1_in   |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddq_ijkl_out     vddq_efgh_in    |   5.00    :1.48   xyz.openbmc_projec>|
-|   vddcr_soc1_in     vddq_ijkl_out   |   5.00    :1.48   xyz.openbmc_projec>|
-|   hotswap_iout      vddcr_soc0_out  |   1.00    :1.48   xyz.openbmc_projec>|
-|   vddq_abcd_in      vddcr_soc1_in   |   7.50    :1.48   xyz.openbmc_projec>|
-|   vddq_mnop_in      vddq_mnop_in    |   7.50    :1.52   xyz.openbmc_projec>|
-|   vddcr_cpu1_out    vddcr_cpu1_out  |   1.00    :1.70   (null)             |
-|   vddq_abcd_out     vddcr_cpu0_out  |   1.00    :1.70   :1.48              |
-+-------------------------------------+--------------------------------------+
- Fri Jul  2 15:50:08 2021                                    PRESS ? FOR HELP
-```
-
-The UI has 3 windows:
-
-### Top, summary window
-
-This window is divided into two sections:
-
-- The dbus traffic dump that shows the method calls, method returns,signals and
-  errors in every dbus callback. This is significant because it shows the
-  latency between every call back and the other section that shows the graph can
-  benefit from this.
-- The other part shows a history graph of these corresponding data and it is
-  designed this way to show users a pictorial representation of the callback
-  metrics.
-
-### Bottom-left, sensor detail window
-
-This window has two states:
-
-- The window shows the list of all sensors (as defined by DBus objects
-  implementing the xyz.openbmc_project.Sensor.Value) by default
-- When a sensor is selected, it shows the corresponding details including sensor
-  name, the dbus connection, PID and the dbus service associated with the
-  sensor. This will be helpful in understanding what is connected to the sensor
-  in a case of performance related to the sensor.
-
-The following is how the window might look once a sensor has been selected:
-
-```text
-+-------------------------------------------------+
-| Details for sensor cputemp0        Sensor 1/192 |
-| [DBus Info]                                     |
-| DBus Connection :  :1.234                       |
-| DBus Service    :  xyz.openbmc_project...       |
-| DBus Object Path:  /path/to/object              |
-|                                                 |
-| [Inventory Info]                                |
-| Association:                                    |
-|  - chassis: all_sensors                         |
-|                                                 |
-| [Visibility]                                    |
-|  - IPMI SEL: Yes                                |
-|  - Object Mapper: Yes                           |
-|  - Sensor Daemon: Yes                           |
-+-------------------------------------------------+
-```
-
-### Bottom-right, DBus stats list view window
-
-This window shows the stats of DBus connections in a list, aggregated by the
-fields of the user’s choice. These fields include sender, destination, path,
-interface, and message type.
-
-A menu is available that allows the user to select what fields to use to
-aggregate the entries in the window.
-
-```text
-+----------------------------------------+
-|Available Fields          Active Fields |
-|                                        |
-|Interface                 Sender        |
-|Path                 ---> Destination   |
-|Message Type         <---               |
-|Sender Process Name                     |
-+----------------------------------------+
-```
-
-The windows can be resized, or shown/hidden individually.
-
-Overview of the Program Structure:
-
-```text
-      UI Thread               Analysis Thread          Capture Thread
-     _______^_______        _________^__________      _________^______
-    /               \      /                    \    /                \
-
-          +-+-------+     +----------+   +-------+      +-----------+
-+-----+   | |User   |     | Call     | ,-|Message|<-.   |Become     |
-|User |   | |Setting|-. S | ObjMapper| | |Handler|  |M  |DBus       |
-|Input|   | `-------+ | o | Inv.Mgr  | | +-------+  |eD |Monitor    |
-+-----+   |         | |Kr | EntityMgr| |     |      |sB +-----------+
-   |      |Frontend | |et +----------+ |     V      |su       |
-   `----->|   UI    | |y    |          | +-------+  |as       V
-   Key    |         | |s    `----------->|Method |  |g  +------------+
-   Stroke |         | `-->+---------+  | |Call   |  |e  |DBus Capture|
-          |         |<-.  |Aggregate|  | |Tracker|  |s  +------------+
-          +---------+  |  |         |<-' +-------+  |      |
-           |     |     |  +---------+        |      +------'
-           V     V     |       |             |      |
-   +--------+ +-----+  |       V             V      |
-   |ncurses-| |Text-|  |   +-------+     +-------+  |   +-----------+
-   |based   | |based|  +---|Sensor |     |Sensor |  `---|PCAP Replay|
-   |UI      | |UI   |  |   |Stats  |     |Details|      +-----------+
-   +--------+ +-----+  |   +-------+     +-------+
-                       |                     |
-                       `---------------------'
-```
-
-## Alternatives Considered
-
-Non-Curses UI: This would help avoid dependence on libncurses, which some BMCs
-might not have. However, we expect libncurses to be present on most BMCs because
-it is widely used in most TUIs.
-
-## Impacts
-
-API impact: none
-
-Security impact: Being confirmed.
-
-Performance impact: Will only have a small impact when the program is running.
-No impact when it’s not running.
-
-Developer impact: For machines that do not install libncurses by default, adding
-this tool might incur a ~130KB overhead due to the libncurses library. No space
-overhead if the machine already includes libncurses.
-
-## Testing
-
-Individual functionalities will be tested with unit tests.
-
-Functional tests will be done using PCAP files.
-
-CI testing is not affected since it doesn’t modify the build process of any
-other package.
diff --git a/dbus-top/analyzer.cpp b/dbus-top/analyzer.cpp
deleted file mode 100644
index f31868c..0000000
--- a/dbus-top/analyzer.cpp
+++ /dev/null
@@ -1,624 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "analyzer.hpp"
-#include "histogram.hpp"
-#include "main.hpp"
-#include "sensorhelper.hpp"
-#include "views.hpp"
-#include "xmlparse.hpp"
-
-#include <unistd.h>
-#include <atomic>
-#include <filesystem>
-#include <fstream>
-#include <functional>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-extern SensorSnapshot* g_sensor_snapshot;
-extern DBusConnectionSnapshot* g_connection_snapshot;
-extern sd_bus* g_bus;
-extern SensorDetailView* g_sensor_detail_view;
-
-static std::unordered_map<uint64_t, uint64_t>
-    in_flight_methodcalls; // serial => microseconds
-uint64_t Microseconds()
-{
-    long us;  // usec
-    time_t s; // Seconds
-    struct timespec spec;
-    clock_gettime(CLOCK_REALTIME, &spec);
-    s = spec.tv_sec;
-    us = round(spec.tv_nsec / 1000); // Convert nanoseconds to milliseconds
-    if (us > 999999)
-    {
-        s++;
-        us = 0;
-    }
-    return s * 1000000 + us;
-}
-
-int g_update_interval_millises = 2000;
-int GetSummaryIntervalInMillises()
-{
-    return g_update_interval_millises;
-}
-
-bool DBusTopSortFieldIsNumeric(DBusTopSortField field)
-{
-    switch (field)
-    {
-        case kSender:
-        case kDestination:
-        case kInterface:
-        case kPath:
-        case kMember:
-        case kSenderCMD:
-            return false;
-        case kSenderPID:
-        case kMsgPerSec:
-        case kAverageLatency:
-            return true;
-    }
-    return false;
-}
-
-namespace dbus_top_analyzer
-{
-    DBusTopStatistics g_dbus_statistics;
-    Histogram<float> g_mc_time_histogram;
-    std::unordered_map<uint32_t, uint64_t> in_flight_methodcalls;
-    std::atomic<bool> g_program_done = false;
-    std::chrono::time_point<std::chrono::steady_clock> g_last_update;
-    DBusTopStatisticsCallback g_callback;
-    void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb)
-    {
-        g_callback = cb;
-    }
-
-    int UserInputThread()
-    {
-        return 0;
-    }
-
-    std::string g_dbus_top_conn = " ";
-    void SetDBusTopConnectionForMonitoring(const std::string& conn)
-    {
-        g_dbus_top_conn = conn;
-    }
-
-    // Performs one step of analysis
-    void Process()
-    {
-        std::chrono::time_point<std::chrono::steady_clock> t =
-            std::chrono::steady_clock::now();
-        std::chrono::time_point<std::chrono::steady_clock> next_update =
-            g_last_update + std::chrono::milliseconds(g_update_interval_millises);
-        if (t >= next_update)
-        {
-            float seconds_since_last_sample =
-                std::chrono::duration_cast<std::chrono::microseconds>(t -
-                                                                    g_last_update)
-                    .count() /
-                1000000.0f;
-            g_dbus_statistics.seconds_since_last_sample_ =
-                seconds_since_last_sample;
-            // Update snapshot
-            if (g_callback)
-            {
-                g_callback(&g_dbus_statistics, &g_mc_time_histogram);
-            }
-            g_dbus_statistics.Reset();
-            g_last_update = t;
-        }
-    }
-
-    void Finish()
-    {
-        g_program_done = true;
-    }
-
-    std::vector<std::string> FindAllObjectPathsForService(
-        const std::string& service,
-        std::function<void(const std::string&, const std::vector<std::string>&)>
-            on_interface_cb)
-    {
-        sd_bus_error err = SD_BUS_ERROR_NULL;
-        sd_bus_message *m, *reply;
-        std::vector<std::string> paths; // Current iteration
-        std::vector<std::string>
-            all_obj_paths; // All object paths under the supervision of ObjectMapper
-        paths.push_back("/");
-        // busctl call xyz.openbmc_project.ObjectMapper        /
-        // org.freedesktop.DBus.Introspectable        Introspect
-        while (!paths.empty())
-        {
-            // printf("%d paths to explore, total %d paths so far\n",
-            // int(paths.size()), int(all_obj_paths.size()));
-            std::vector<std::string> new_paths;
-            for (const std::string& obj_path : paths)
-            {
-                all_obj_paths.push_back(obj_path);
-                int r = sd_bus_message_new_method_call(
-                    g_bus, &m, service.c_str(), obj_path.c_str(),
-                    "org.freedesktop.DBus.Introspectable", "Introspect");
-                if (r < 0)
-                {
-                    printf("Oh! Cannot create new method call. r=%d, strerror=%s\n",
-                        r, strerror(-r));
-                    continue;
-                }
-                r = sd_bus_call(g_bus, m, 0, &err, &reply);
-                if (r < 0)
-                {
-                    printf("Could not execute method call, r=%d, strerror=%s\n", r,
-                        strerror(-r));
-                }
-                const char* sig = sd_bus_message_get_signature(reply, 0);
-                if (!strcmp(sig, "s"))
-                {
-                    const char* s;
-                    int r = sd_bus_message_read(reply, "s", &s);
-                    std::string s1(s);
-                    if (r < 0)
-                    {
-                        printf("Could not read string payload, r=%d, strerror=%s\n",
-                            r, strerror(-r));
-                    }
-                    else
-                    {
-                        XMLNode* t = ParseXML(s1);
-                        std::vector<std::string> ch = t->GetChildNodeNames();
-                        if (on_interface_cb != nullptr)
-                        {
-                            on_interface_cb(obj_path, t->GetInterfaceNames());
-                        }
-                        DeleteTree(t);
-                        for (const std::string& cn : ch)
-                        {
-                            std::string ch_path = obj_path;
-                            if (obj_path.back() == '/')
-                            {}
-                            else
-                                ch_path.push_back('/');
-                            ch_path += cn;
-                            new_paths.push_back(ch_path);
-                        }
-                    }
-                }
-            }
-            paths = new_paths;
-        }
-        return all_obj_paths;
-    }
-
-    void ListAllSensors()
-    {
-        g_connection_snapshot = new DBusConnectionSnapshot();
-        printf("1. Getting names\n");
-        char** names;
-        int r = sd_bus_list_names(g_bus, &names, nullptr);
-        std::vector<std::string> services;
-        std::vector<int> pids;
-        std::vector<std::string> comms;
-        for (char** ptr = names; ptr && *ptr; ++ptr)
-        {
-            services.push_back(*ptr);
-            free(*ptr);
-        }
-        free(names);
-        printf("2. Getting creds of each name\n");
-        for (int i = 0; i < static_cast<int>(services.size()); i++)
-        {
-            const std::string& service = services[i];
-            sd_bus_creds* creds = nullptr;
-            r = sd_bus_get_name_creds(g_bus, services[i].c_str(),
-                                    SD_BUS_CREDS_AUGMENT | SD_BUS_CREDS_EUID |
-                                        SD_BUS_CREDS_PID | SD_BUS_CREDS_COMM |
-                                        SD_BUS_CREDS_UNIQUE_NAME |
-                                        SD_BUS_CREDS_UNIT | SD_BUS_CREDS_SESSION |
-                                        SD_BUS_CREDS_DESCRIPTION,
-                                    &creds);
-            // PID
-            int pid = INVALID;
-            if (r < 0)
-            {
-                printf("Oh! Cannot get creds for %s\n", services[i].c_str());
-            }
-            else
-            {
-                r = sd_bus_creds_get_pid(creds, &pid);
-            }
-            pids.push_back(pid);
-            // comm
-            std::string comm;
-            if (pid != INVALID)
-            {
-                std::ifstream ifs("/proc/" + std::to_string(pid) + "/cmdline");
-                std::string line;
-                std::getline(ifs, line);
-                for (char c : line)
-                {
-                    if (c < 32 || c >= 127)
-                        c = ' ';
-                    comm.push_back(c);
-                }
-            }
-            comms.push_back(comm);
-            // unique name, also known as "Connection"
-            std::string connection;
-            const char* u;
-            r = sd_bus_creds_get_unique_name(creds, &u);
-            if (r >= 0)
-            {
-                connection = u;
-            }
-            else
-            {
-                printf("Oh! Could not get unique name for %s\n", service.c_str());
-            }
-            std::string unit;
-            r = sd_bus_creds_get_unit(creds, &u);
-            if (r >= 0)
-            {
-                unit = u;
-            }
-            else
-            {
-                printf("Oh! Could not get unit name for %s\n", unit.c_str());
-            }
-            printf("AddConnection    %s    %s    %s    %s    %d\n", service.c_str(),
-                connection.c_str(), comm.c_str(), unit.c_str(), pid);
-            g_connection_snapshot->AddConnection(service, connection, comm, unit,
-                                                pid);
-        }
-        printf("There are %d DBus names.\n", int(services.size()));
-        for (int i = 0; i < int(services.size()); i++)
-        {
-            printf("    %d: %s [%s]\n", i, services[i].c_str(), comms[i].c_str());
-        }
-        g_sensor_snapshot = new SensorSnapshot(g_connection_snapshot);
-        // busctl call xyz.openbmc_project.ObjectMapper /
-        // org.freedesktop.DBus.Introspectable Introspect
-        printf("3. See which sensors are visible from Object Mapper\n");
-        printf("3.1. Introspect Object Mapper for object paths\n");
-        std::vector<std::string> all_obj_paths = FindAllObjectPathsForService(
-            "xyz.openbmc_project.ObjectMapper", nullptr);
-        sd_bus_error err = SD_BUS_ERROR_NULL;
-        sd_bus_message *m, *reply;
-        printf("%d paths found while introspecting ObjectMapper.\n",
-            int(all_obj_paths.size()));
-        printf("3.2. Call ObjectMapper's GetObject method against the sensor "
-            "object paths that represent sensors\n");
-        for (const std::string& p : all_obj_paths)
-        {
-            if (IsSensorObjectPath(p))
-            {
-                err = SD_BUS_ERROR_NULL;
-                r = sd_bus_message_new_method_call(
-                    g_bus, &m, "xyz.openbmc_project.ObjectMapper",
-                    "/xyz/openbmc_project/object_mapper",
-                    "xyz.openbmc_project.ObjectMapper", "GetObject");
-                if (r < 0)
-                {
-                    printf("Cannot create new method call. r=%d, strerror=%s\n", r,
-                        strerror(-r));
-                    continue;
-                }
-                r = sd_bus_message_append_basic(m, 's', p.c_str());
-                if (r < 0)
-                {
-                    printf("Could not append a string parameter to m\n");
-                    continue;
-                }
-                // empty array
-                r = sd_bus_message_open_container(m, 'a', "s");
-                if (r < 0)
-                {
-                    printf("Could not open a container for m\n");
-                    continue;
-                }
-                r = sd_bus_message_close_container(m);
-                if (r < 0)
-                {
-                    printf("Could not close container for m\n");
-                    continue;
-                }
-                r = sd_bus_call(g_bus, m, 0, &err, &reply);
-                if (r < 0)
-                {
-                    printf("Error performing dbus method call\n");
-                }
-                const char* sig = sd_bus_message_get_signature(reply, 0);
-                if (!strcmp(sig, "a{sas}"))
-                {
-                    r = sd_bus_message_enter_container(reply, 'a', "{sas}");
-                    if (r < 0)
-                    {
-                        printf("Could not enter the level 0 array container\n");
-                        continue;
-                    }
-                    while (true)
-                    {
-                        r = sd_bus_message_enter_container(
-                            reply, SD_BUS_TYPE_DICT_ENTRY, "sas");
-                        if (r < 0)
-                        {
-                            // printf("Could not enter the level 1 dict
-                            // container\n");
-                            goto DONE;
-                        }
-                        else if (r == 0)
-                        {}
-                        else
-                        {
-                            // The following 2 correspond to `interface_map` in
-                            // phosphor-mapper
-                            const char* interface_map_first;
-                            r = sd_bus_message_read_basic(reply, 's',
-                                                        &interface_map_first);
-                            if (r < 0)
-                            {
-                                printf("Could not read interface_map_first\n");
-                                goto DONE;
-                            }
-                            r = sd_bus_message_enter_container(reply, 'a', "s");
-                            if (r < 0)
-                            {
-                                printf("Could not enter the level 2 array "
-                                    "container\n");
-                                goto DONE;
-                            }
-                            bool has_value_interface = false;
-                            while (true)
-                            {
-                                const char* interface_map_second;
-                                r = sd_bus_message_read_basic(
-                                    reply, 's', &interface_map_second);
-                                if (r < 0)
-                                {
-                                    printf("Could not read interface_map_second\n");
-                                }
-                                else if (r == 0)
-                                    break;
-                                else
-                                {
-                                    // printf("    %s\n", interface_map_second);
-                                    if (!strcmp(interface_map_second,
-                                                "xyz.openbmc_project.Sensor.Value"))
-                                    {
-                                        has_value_interface = true;
-                                    }
-                                }
-                            }
-                            if (has_value_interface)
-                            {
-                                g_sensor_snapshot->SerSensorVisibleFromObjectMapper(
-                                    std::string(interface_map_first), p);
-                            }
-                            r = sd_bus_message_exit_container(reply);
-                        }
-                        r = sd_bus_message_exit_container(reply);
-                    }
-                    r = sd_bus_message_exit_container(reply);
-                }
-            DONE:
-            {}
-            }
-        }
-        printf("4. Check Hwmon's DBus objects\n");
-        for (int i = 0; i < int(comms.size()); i++)
-        {
-            const std::string& comm = comms[i];
-            const std::string& service = services[i];
-            if (comm.find("phosphor-hwmon-readd") != std::string::npos &&
-                !IsUniqueName(service))
-            {
-                // printf("Should introspect %s\n", service.c_str());
-                std::vector<std::string> objpaths =
-                    FindAllObjectPathsForService(service, nullptr);
-                for (const std::string& op : objpaths)
-                {
-                    if (IsSensorObjectPath(op))
-                    {
-                        g_sensor_snapshot->SetSensorVisibleFromHwmon(service, op);
-                    }
-                }
-            }
-        }
-        // Call `ipmitool sdr list` and see which sensors exist.
-        printf("5. Checking ipmitool SDR List\n");
-        std::string out;
-        bool skip_sdr_list = false;
-        if (getenv("SKIP"))
-        {
-            skip_sdr_list = true;
-        }
-        if (!skip_sdr_list)
-        {
-            constexpr int MAX_BUFFER = 255;
-            char buffer[MAX_BUFFER];
-            FILE* stream = popen("ipmitool sdr list", "r");
-            while (fgets(buffer, MAX_BUFFER, stream) != NULL)
-            {
-                out.append(buffer);
-            }
-            pclose(stream);
-        }
-        std::stringstream ss(out);
-        while (true)
-        {
-            std::string sensor_id, reading, status;
-            std::getline(ss, sensor_id, '|');
-            std::getline(ss, reading, '|');
-            std::getline(ss, status);
-            // printf("%s %s %s\n", sensor_id.c_str(), reading.c_str(),
-            // status.c_str());
-            if (sensor_id.size() > 0 && reading.size() > 0 && status.size() > 0)
-            {
-                g_sensor_snapshot->SetSensorVisibleFromIpmitoolSdr(Trim(sensor_id));
-            }
-            else
-                break;
-        }
-        printf("=== Sensors snapshot summary: ===\n");
-        g_sensor_snapshot->PrintSummary();
-    }
-} // namespace dbus_top_analyzer
-
-void DBusTopStatistics::OnNewDBusMessage(const char* sender,
-                                         const char* destination,
-                                         const char* interface,
-                                         const char* path, const char* member,
-                                         const char type, sd_bus_message* m)
-{
-    num_messages_++;
-    std::vector<std::string> keys;
-
-    std::string sender_orig = CheckAndFixNullString(sender);
-    std::string dest_orig = CheckAndFixNullString(destination);
-    // For method return messages, we actually want to show the sender
-    // and destination of the original method call, so we swap the
-    // sender and destination
-    if (type == 2)
-    { // DBUS_MESSAGE_TYPE_METHOD_METHOD_RETURN
-        std::swap(sender_orig, dest_orig);
-    }
-
-    // Special case: when PID == 1 (init), the DBus unit would be systemd.
-    // It seems it was not possible to obtain the connection name of systemd
-    // so we manually set it here.
-    const int sender_orig_pid =
-        g_connection_snapshot->GetConnectionPIDFromNameOrUniqueName(
-            sender_orig);
-
-    if (sender_orig_pid == 1)
-    {
-        sender_orig = "systemd";
-    }
-    const int dest_orig_pid =
-        g_connection_snapshot->GetConnectionPIDFromNameOrUniqueName(dest_orig);
-    if (dest_orig_pid == 1)
-    {
-        dest_orig = "systemd";
-    }
-
-    for (DBusTopSortField field : fields_)
-    {
-        switch (field)
-        {
-            case kSender:
-                keys.push_back(sender_orig);
-                break;
-            case kDestination:
-                keys.push_back(dest_orig);
-                break;
-            case kInterface:
-                keys.push_back(CheckAndFixNullString(interface));
-                break;
-            case kPath:
-                keys.push_back(CheckAndFixNullString(path));
-                break;
-            case kMember:
-                keys.push_back(CheckAndFixNullString(member));
-                break;
-            case kSenderPID:
-            {
-                if (sender_orig_pid != INVALID)
-                {
-                    keys.push_back(std::to_string(sender_orig_pid));
-                }
-                else
-                {
-                    keys.push_back("(unknown)");
-                }
-                break;
-            }
-            case kSenderCMD:
-            {
-                keys.push_back(
-                    g_connection_snapshot->GetConnectionCMDFromNameOrUniqueName(
-                        sender_orig));
-                break;
-            }
-            case kMsgPerSec:
-            case kAverageLatency:
-                break; // Don't populate "keys" using these 2 fields
-        }
-    }
-    // keys = combination of fields of user's choice
-
-    if (stats_.count(keys) == 0)
-    {
-        stats_[keys] = DBusTopComputedMetrics();
-    }
-    // Need to update msg/s regardless
-    switch (type)
-    {
-        case 1: // DBUS_MESSAGE_TYPE_METHOD_CALL
-            stats_[keys].num_method_calls++;
-            break;
-        case 2: // DBUS_MESSAGE_TYPE_METHOD_METHOD_RETURN
-            stats_[keys].num_method_returns++;
-            break;
-        case 3: // DBUS_MESSAGE_TYPE_ERROR
-            stats_[keys].num_errors++;
-            break;
-        case 4: // DBUS_MESSAGE_TYPE_SIGNAL
-            stats_[keys].num_signals++;
-            break;
-    }
-    // Update global latency histogram
-    // For method call latency
-    if (type == 1) // DBUS_MESSAGE_TYPE_METHOD_CALL
-    {
-        uint64_t serial; // serial == cookie
-        sd_bus_message_get_cookie(m, &serial);
-        in_flight_methodcalls[serial] = Microseconds();
-    }
-    else if (type == 2) // DBUS_MESSAGE_TYPE_MEHOTD_RETURN
-    {
-        uint64_t reply_serial = 0; // serial == cookie
-        sd_bus_message_get_reply_cookie(m, &reply_serial);
-        if (in_flight_methodcalls.count(reply_serial) > 0)
-        {
-            float dt_usec =
-                Microseconds() - in_flight_methodcalls[reply_serial];
-            in_flight_methodcalls.erase(reply_serial);
-            dbus_top_analyzer::g_mc_time_histogram.AddSample(dt_usec);
-
-            // Add method call count and total latency to the corresponding key
-            stats_[keys].total_latency_usec += dt_usec;
-        }
-    }
-    // For meaning of type see here
-    // https://dbus.freedesktop.org/doc/api/html/group__DBusProtocol.html#ga4a9012edd7f22342f845e98150aeb858
-    switch (type)
-    {
-        case 1:
-            num_mc_++;
-            break;
-        case 2:
-            num_mr_++;
-            break;
-        case 3:
-            num_error_++;
-            break;
-        case 4:
-            num_sig_++;
-            break;
-    }
-}
diff --git a/dbus-top/analyzer.hpp b/dbus-top/analyzer.hpp
deleted file mode 100644
index 2284c7f..0000000
--- a/dbus-top/analyzer.hpp
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "histogram.hpp"
-
-#include <systemd/sd-bus.h>
-
-#include <atomic>
-#include <map>
-#include <mutex>
-#include <string>
-#include <vector>
-
-enum DBusTopSortField
-{
-    // DBus Message properties
-    kSender,
-    kDestination,
-    kInterface,
-    kPath,
-    kMember,
-    kSenderPID,
-    kSenderCMD,
-    // Computed metrics
-    kMsgPerSec,
-    kAverageLatency,
-};
-
-const std::string FieldNames[] = {"Sender",     "Destination", "Interface",
-                                  "Path",       "Member",      "Sender PID",
-                                  "Sender CMD", "Msg/s",       "Avg Latency"};
-const int FieldPreferredWidths[] = {18, 20, 12, 10, 10, 10, 25, 8, 12};
-bool DBusTopSortFieldIsNumeric(DBusTopSortField field);
-
-struct DBusTopComputedMetrics
-{
-    DBusTopComputedMetrics()
-    {
-        num_signals = 0;
-        num_errors = 0;
-        num_method_returns = 0;
-        num_method_calls = 0;
-        total_latency_usec = 0;
-    }
-    int num_method_returns = 0;
-    int num_errors = 0;
-    int num_signals = 0;
-    int num_method_calls;
-    uint64_t total_latency_usec;
-};
-
-class DBusTopStatistics
-{
-  public:
-    int num_messages_;
-    int num_mc_, num_mr_, num_sig_, num_error_;
-    float seconds_since_last_sample_;
-    std::vector<DBusTopSortField> fields_;
-    std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_;
-    DBusTopStatistics() :
-        num_messages_(0), num_mc_(0), num_mr_(0), num_sig_(0), num_error_(0),
-        seconds_since_last_sample_(0)
-    {
-        fields_ = {kSender, kDestination, kSenderPID, kSenderCMD};
-        stats_.clear();
-    }
-
-    std::vector<DBusTopSortField> GetFields()
-    {
-        return fields_;
-    }
-
-    std::vector<std::string> GetFieldNames()
-    {
-        const int N = fields_.size();
-        std::vector<std::string> ret(N);
-        for (int i = 0; i < static_cast<int>(fields_.size()); i++)
-        {
-            ret[i] = FieldNames[static_cast<int>(fields_[i])];
-        }
-        return ret;
-    }
-
-    std::vector<int> GetFieldPreferredWidths()
-    {
-        const int N = fields_.size();
-        std::vector<int> ret(N);
-        for (int i = 0; i < static_cast<int>(fields_.size()); i++)
-        {
-            ret[i] = FieldPreferredWidths[static_cast<int>(fields_[i])];
-        }
-        return ret;
-    }
-
-    void Reset()
-    {
-        num_messages_ = 0;
-        num_mc_ = 0;
-        num_mr_ = 0;
-        num_sig_ = 0;
-        num_error_ = 0;
-        stats_.clear();
-    }
-    
-    void SetSortFieldsAndReset(const std::vector<DBusTopSortField>& f)
-    {
-        num_messages_ = 0;
-        num_mc_ = 0;
-        num_mr_ = 0;
-        num_sig_ = 0;
-        num_error_ = 0;
-        stats_.clear();
-        fields_ = f;
-    }
-
-    void Assign(DBusTopStatistics* out)
-    {
-        out->num_messages_ = this->num_messages_;
-        out->num_mc_ = this->num_mc_;
-        out->num_mr_ = this->num_mr_;
-        out->num_sig_ = this->num_sig_;
-        out->num_error_ = this->num_error_;
-        out->seconds_since_last_sample_ = this->seconds_since_last_sample_;
-        out->fields_ = this->fields_;
-        out->stats_ = this->stats_;
-    }
-
-    void OnNewDBusMessage(const char* sender, const char* destination,
-                          const char* interface, const char* path,
-                          const char* message, const char type,
-                          sd_bus_message* m);
-    std::string CheckAndFixNullString(const char* x)
-    {
-        if (x == nullptr)
-            return "(null)";
-        else
-            return std::string(x);
-    }
-
-    std::map<std::vector<std::string>, DBusTopComputedMetrics> StatsSnapshot()
-    {
-        std::map<std::vector<std::string>, DBusTopComputedMetrics> ret;
-        ret = stats_;
-        return ret;
-    }
-
-  private:
-    std::mutex mtx_;
-};
-
-int GetSummaryIntervalInMillises();
-// Monitor sensor details-related DBus method calls/replies
-// typedef void (*SetDBusTopConnection)(const char* conn);
-namespace dbus_top_analyzer
-{
-    void Process();
-    void Finish();
-    typedef void (*DBusTopStatisticsCallback)(DBusTopStatistics*,
-                                            Histogram<float>*);
-    void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb);
-    void AnalyzerThread();
-    // Methods for sending Object Mapper queries
-    void ListAllSensors();
-} // namespace dbus_top_analyzer
diff --git a/dbus-top/bargraph.hpp b/dbus-top/bargraph.hpp
deleted file mode 100644
index 36f34a1..0000000
--- a/dbus-top/bargraph.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 <stdio.h>
-
-#include <vector>
-
-template <typename ValueType>
-class BarGraph
-{
-  public:
-    std::vector<ValueType> history_; // is actually a ring buffer.
-    int next_;   // index to the slot where the next insertion will go
-    int length_; // total # of data points that have ever been added
-    explicit BarGraph(int capacity) : next_(0), length_(0)
-    {
-        history_.resize(capacity);
-        std::fill(history_.begin(), history_.end(), 0);
-    }
-
-    // The last value is in [0], so on and so forth
-    // Note: if there are not enough data, this function will return as much
-    // as is available
-    std::vector<float> GetLastNValues(int x)
-    {
-        std::vector<float> ret;
-        const int N = static_cast<int>(history_.size());
-        int imax = x;
-        imax = std::min(imax, length_);
-        imax = std::min(imax, N);
-        int idx = (next_ - 1 + N) % N;
-        for (int i = 0; i < imax; i++)
-        {
-            ret.push_back(history_[idx]);
-            idx = (idx - 1 + N) % N;
-        }
-        return ret;
-    }
-
-    void AddValue(ValueType x)
-    {
-        history_[next_] = x;
-        next_ = (next_ + 1) % history_.size();
-        length_++;
-    }
-};
diff --git a/dbus-top/dbus_capture.cpp b/dbus-top/dbus_capture.cpp
deleted file mode 100644
index 715fd41..0000000
--- a/dbus-top/dbus_capture.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "analyzer.hpp"
-#include "histogram.hpp"
-#include "sensorhelper.hpp"
-#include "main.hpp"
-
-#include <ncurses.h>
-#include <stdlib.h>
-#include <systemd/sd-bus.h>
-
-#include <unordered_map>
-
-bool IS_USER_BUS = false; // User bus or System bus?
-extern sd_bus* g_bus;
-extern DBusConnectionSnapshot* g_connection_snapshot;
-static std::unordered_map<uint64_t, uint64_t> in_flight_methodcalls;
-
-namespace dbus_top_analyzer
-{
-    extern DBusTopStatistics g_dbus_statistics;
-    extern Histogram<float> g_mc_time_histogram;
-} // namespace dbus_top_analyzer
-
-static void TrackMessage(sd_bus_message* m)
-{}
-// Obtain a Monitoring DBus connection
-int AcquireBus(sd_bus** ret)
-{
-    int r;
-    r = sd_bus_new(ret);
-    if (r < 0)
-    {
-        printf("Could not allocate bus: %s\n", strerror(-r));
-        return 0;
-    }
-    r = sd_bus_set_monitor(*ret, true);
-    if (r < 0)
-    {
-        printf("Could not set monitor mode: %s\n", strerror(-r));
-        return 0;
-    }
-    r = sd_bus_negotiate_creds(*ret, true, _SD_BUS_CREDS_ALL);
-    if (r < 0)
-    {
-        printf("Could not enable credentials: %s\n", strerror(-r));
-        return 0;
-    }
-    r = sd_bus_negotiate_timestamp(*ret, true);
-    if (r < 0)
-    {
-        printf("Could not enable timestamps: %s\n", strerror(-r));
-        return 0;
-    }
-    r = sd_bus_negotiate_fds(*ret, true);
-    if (r < 0)
-    {
-        printf("Could not enable fds: %s\n", strerror(-r));
-        return 0;
-    }
-    r = sd_bus_set_bus_client(*ret, true);
-    if (r < 0)
-    {
-        printf("Could not enable bus client: %s\n", strerror(-r));
-        return 0;
-    }
-    if (IS_USER_BUS)
-    {
-        r = sd_bus_set_address(*ret, "haha");
-        if (r < 0)
-        {
-            printf("Could not set user bus: %s\n", strerror(-r));
-            return 0;
-        }
-    }
-    else
-    {
-        r = sd_bus_set_address(*ret, "unix:path=/run/dbus/system_bus_socket");
-        if (r < 0)
-        {
-            printf("Could not set system bus: %s\n", strerror(-r));
-            return 0;
-        }
-    }
-    r = sd_bus_start(*ret);
-    if (r < 0)
-    {
-        printf("Could not connect to bus: %s\n", strerror(-r));
-        return 0;
-    }
-    return r;
-}
-
-void DbusCaptureThread()
-{
-    int r;
-    // Become Monitor
-    uint32_t flags = 0;
-    sd_bus_message* message;
-    sd_bus_error error = SD_BUS_ERROR_NULL;
-    r = sd_bus_message_new_method_call(
-        g_bus, &message, "org.freedesktop.DBus", "/org/freedesktop/DBus",
-        "org.freedesktop.DBus.Monitoring", "BecomeMonitor");
-    if (r < 0)
-    {
-        printf("Could not create the BecomeMonitor function call\n");
-        exit(0);
-    }
-    // Match conditions
-    r = sd_bus_message_open_container(message, 'a', "s");
-    if (r < 0)
-    {
-        printf("Could not open container\n");
-        exit(0);
-    }
-    r = sd_bus_message_close_container(message);
-    if (r < 0)
-    {
-        printf("Could not close container\n");
-        exit(0);
-    }
-    r = sd_bus_message_append_basic(message, 'u', &flags);
-    if (r < 0)
-    {
-        printf("Could not append flags\n");
-        exit(0);
-    }
-    r = sd_bus_call(g_bus, message, 0, &error, nullptr);
-    if (r < 0)
-    {
-        printf("Could not call org.freedesktop.DBus.Monitoring.BecomeMonitor "
-               "%d, %s\n",
-               r, strerror(-r));
-        exit(0);
-    }
-    const char* unique_name;
-    r = sd_bus_get_unique_name(g_bus, &unique_name);
-    if (r < 0)
-    {
-        printf("Could not get unique name: %s\n", strerror(-r));
-        exit(0);
-    }
-    // Enter packet processing loop
-    while (true)
-    {
-        struct sd_bus_message* m = nullptr;
-        r = sd_bus_process(g_bus, &m);
-        if (m != nullptr)
-        {
-            if (r < 0)
-            {
-                printf("Failed to call sd_bus_process: %s\n", strerror(-r));
-            }
-            uint8_t type;
-            r = sd_bus_message_get_type(m, &type);
-            const char* path = sd_bus_message_get_path(m);
-            // const char* iface = sd_bus_message_get_interface(m);
-            const char* sender = sd_bus_message_get_sender(m);
-            const char* destination = sd_bus_message_get_destination(m);
-            const char* interface = sd_bus_message_get_interface(m);
-            const char* member = sd_bus_message_get_member(m);
-            // TODO: This is for the bottom-left window
-            TrackMessage(m);
-
-            // Look up the unique connection name for sender and destination
-            std::string sender_uniq, dest_uniq;
-            if (sender != nullptr)
-            {
-                sender_uniq =
-                    g_connection_snapshot->GetUniqueNameIfExists(sender);
-            }
-            if (destination != nullptr)
-            {
-                dest_uniq =
-                    g_connection_snapshot->GetUniqueNameIfExists(destination);
-            }
-            // This is for the bottom-right window
-            dbus_top_analyzer::g_dbus_statistics.OnNewDBusMessage(
-            sender_uniq.c_str(), dest_uniq.c_str(), interface, path, member,
-                type, m);
-            sd_bus_message_unref(m);
-        }
-        r = sd_bus_wait(g_bus,
-                        (uint64_t)(GetSummaryIntervalInMillises() * 1000));
-        if (r < 0)
-        {
-            printf("Failed to wait on bus: %s\n", strerror(-r));
-            abort();
-        }
-        // Perform one analysis step
-        dbus_top_analyzer::Process();
-    }
-}
\ No newline at end of file
diff --git a/dbus-top/dbus_capture.hpp b/dbus-top/dbus_capture.hpp
deleted file mode 100644
index 825a519..0000000
--- a/dbus-top/dbus_capture.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 <systemd/sd-bus.h>
-
-int AcquireBus(sd_bus** ret);
-void DbusCaptureThread();
diff --git a/dbus-top/dbus_top_recipe.bb b/dbus-top/dbus_top_recipe.bb
deleted file mode 100644
index 4de4f0e..0000000
--- a/dbus-top/dbus_top_recipe.bb
+++ /dev/null
@@ -1,23 +0,0 @@
-HOMEPAGE = "http://github.com/openbmc/openbmc-tools"
-PR = "r1"
-PV = "1.0+git${SRCPV}"
-
-LICENSE = "Apache-2.0"
-LIC_FILES_CHKSUM = "file://../LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
-
-SRC_URI += "git://github.com/openbmc-tools"
-SRCREV = "4a0e2e3c10327dac1c923d263929be9a20478b24"
-
-S = "${WORKDIR}/git/"
-inherit meson
-
-SUMMARY = "DBus-Top"
-DESCRIPTION = "DBUs-Top."
-GOOGLE_MISC_PROJ = "dbus-top"
-
-DEPENDS += "systemd"
-DEPENDS += "sdbusplus"
-DEPENDS += "phosphor-mapper"
-DEPENDS += "ncurses"
-
-inherit systemd
diff --git a/dbus-top/histogram.hpp b/dbus-top/histogram.hpp
deleted file mode 100644
index 750a9f4..0000000
--- a/dbus-top/histogram.hpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 <math.h>
-#include <stdio.h>
-
-#include <vector>
-template <typename ValueType>
-class Histogram
-{
-  public:
-    Histogram()
-    {
-        num_entries_ = 0;
-        num_low_outliers_ = 0;
-        num_high_outliers_ = 0;
-        low_percentile_ = 0;
-        high_percentile_ = 0;
-        SetWindowSize(10000);
-        SetCumulativeDensityThresholds(0.01f, 0.99f);
-    }
-
-    void AddSample(ValueType s)
-    {
-        int N = static_cast<int>(samples_.size());
-        samples_[num_entries_ % N] = s;
-        num_entries_++;
-    }
-
-    void SetBucketCount(int bc)
-    {
-        buckets_.resize(bc);
-    }
-
-    void SetWindowSize(int s)
-    {
-        samples_.resize(s);
-    }
-
-    void SetCumulativeDensityThresholds(float low_cd, float high_cd)
-    {
-        low_cum_density_ = low_cd;
-        high_cum_density_ = high_cd;
-    }
-
-    void ComputeHistogram()
-    {
-        const int NS = static_cast<int>(samples_.size());
-        int N = NS;
-        if (num_entries_ < N)
-        {
-            N = num_entries_;
-        }
-        if (N <= 0)
-        {
-            return;
-        }
-        std::vector<ValueType> sorted;
-        if (N == NS)
-            sorted = samples_;
-        else
-            sorted.insert(sorted.end(), samples_.begin(), samples_.begin() + N);
-        sort(sorted.begin(), sorted.end());
-        int idx_low = static_cast<int>(N * low_cum_density_);
-        int idx_high = static_cast<int>(N * high_cum_density_);
-        if (idx_high - idx_low + 1 < 1)
-        {
-            return; // No entries can be shown, quit
-        }
-        max_bucket_height_ = 0;
-        ValueType value_low = sorted[idx_low];
-        ValueType value_high = sorted[idx_high];
-        low_percentile_ = value_low;
-        high_percentile_ = value_high;
-        const int NB = static_cast<int>(buckets_.size()); // Number of Bins
-        float bucket_width = (value_high - value_low) / NB;
-        // If all values are the same, manually extend the range to
-        // (value-1, value+1)
-        const float EPS = 1e-4;
-        if (fabs(value_high - value_low) <= EPS)
-        {
-            value_low = value_low - 1;
-            value_high = value_high + 1;
-            bucket_width = (value_high - value_low) / NB;
-        }
-        else
-        {}
-        buckets_.assign(NB, 0);
-        num_low_outliers_ = 0;
-        num_high_outliers_ = 0;
-        for (int i = idx_low; i <= idx_high; i++)
-        {
-            ValueType v = sorted[i];
-            ValueType dist = (v - value_low);
-            int bucket_idx = dist / bucket_width;
-            if (bucket_idx < 0)
-            {
-                num_low_outliers_++;
-            }
-            else if (bucket_idx >= NB)
-            {
-                num_high_outliers_++;
-            }
-            else
-            {
-                buckets_[bucket_idx]++;
-                max_bucket_height_ =
-                    std::max(max_bucket_height_, buckets_[bucket_idx]);
-            }
-        }
-    }
-
-    int BucketHeight(int idx)
-    {
-        if (idx < 0 || idx >= static_cast<int>(buckets_.size()))
-            return 0;
-        return buckets_[idx];
-    }
-    
-    void Assign(Histogram<ValueType>* out)
-    {
-        out->num_entries_ = num_entries_;
-        out->samples_ = samples_;
-        out->num_low_outliers_ = num_low_outliers_;
-        out->num_high_outliers_ = num_high_outliers_;
-        out->buckets_ = buckets_;
-        out->low_cum_density_ = low_cum_density_;
-        out->high_cum_density_ = high_cum_density_;
-        out->low_percentile_ = low_percentile_;
-        out->high_percentile_ = high_percentile_;
-        out->max_bucket_height_ = max_bucket_height_;
-    }
-
-    int MaxBucketHeight()
-    {
-        return max_bucket_height_;
-    }
-
-    ValueType LowPercentile()
-    {
-        return low_percentile_;
-    }
-
-    ValueType HighPercentile()
-    {
-        return high_percentile_;
-    }
-
-    float LowCumDensity()
-    {
-        return low_cum_density_;
-    }
-
-    float HighCumDensity()
-    {
-        return high_cum_density_;
-    }
-
-    bool Empty()
-    {
-        return num_entries_ == 0;
-    }
-    
-    int num_entries_;
-    std::vector<ValueType> samples_;
-    int num_low_outliers_, num_high_outliers_;
-    std::vector<int> buckets_;
-    float low_cum_density_, high_cum_density_;
-    // "1% percentile" means "1% of the samples are below this value"
-    ValueType low_percentile_, high_percentile_;
-    int max_bucket_height_;
-};
\ No newline at end of file
diff --git a/dbus-top/main.cpp b/dbus-top/main.cpp
deleted file mode 100644
index 5293f9b..0000000
--- a/dbus-top/main.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "main.hpp"
-
-#include "analyzer.hpp"
-#include "bargraph.hpp"
-#include "dbus_capture.hpp"
-#include "histogram.hpp"
-#include "menu.hpp"
-#include "sensorhelper.hpp"
-#include "views.hpp"
-
-#include <fmt/printf.h>
-#include <ncurses.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <iomanip>
-#include <sstream>
-#include <thread>
-
-DBusTopWindow* g_current_active_view;
-SummaryView* g_summary_window;
-SensorDetailView* g_sensor_detail_view;
-DBusStatListView* g_dbus_stat_list_view;
-FooterView* g_footer_view;
-BarGraph<float>* g_bargraph = nullptr;
-Histogram<float>* g_histogram;
-std::vector<DBusTopWindow*> g_views;
-int g_highlighted_view_index = INVALID;
-sd_bus* g_bus = nullptr;
-SensorSnapshot* g_sensor_snapshot;
-DBusConnectionSnapshot* g_connection_snapshot;
-DBusTopStatistics* g_dbus_statistics; // At every update interval,
-                                      // dbus_top_analyzer::g_dbus_statistics's
-                                      // value is copied to this one for display
-void ReinitializeUI();
-int maxx, maxy, halfx, halfy;
-
-void ActivateWindowA()
-{
-    g_views[0]->visible_=true;
-    g_views[0]->maximize_=true;
-    g_views[1]->visible_=false;
-    g_views[2]->visible_=false;
-}
-
-void ActivateWindowB()
-{
-    g_views[1]->visible_=true;
-    g_views[1]->maximize_=true;
-    g_views[0]->visible_=false;
-    g_views[2]->visible_=false;
-}
-void ActivateWindowC()
-{
-    g_views[2]->visible_=true;
-    g_views[2]->maximize_=true;
-    g_views[0]->visible_=false;
-    g_views[1]->visible_=false;
-}
-void ActivateAllWindows()
-{
-    g_views[0]->maximize_ = false;
-    g_views[1]->maximize_=false;
-    g_views[2]->maximize_=false;
-    g_views[0]->visible_=true;
-    g_views[1]->visible_=true;
-    g_views[2]->visible_= true;
-}
-
-void InitColorPairs()
-{
-    init_pair(1, COLOR_WHITE, COLOR_BLACK); // Does not work on actual machine
-    init_pair(2, COLOR_BLACK, COLOR_WHITE);
-}
-
-// Returns number of lines drawn
-int DrawTextWithWidthLimit(WINDOW* win, std::string txt, int y, int x,
-                           int width, const std::string& delimiters)
-{
-    int ret = 0;
-    std::string curr_word, curr_line;
-    while (txt.empty() == false)
-    {
-        ret++;
-        if (static_cast<int>(txt.size()) > width)
-        {
-            mvwaddstr(win, y, x, txt.substr(0, width).c_str());
-            txt = txt.substr(width);
-        }
-        else
-        {
-            mvwaddstr(win, y, x, txt.c_str());
-            break;
-        }
-        y++;
-    }
-    return ret;
-}
-
-void UpdateWindowSizes()
-{
-    /* calculate window sizes and locations */
-    if (getenv("FIXED_TERMINAL_SIZE"))
-    {
-        maxx = 100;
-        maxy = 30;
-    }
-    else
-    {
-        getmaxyx(stdscr, maxy, maxx);
-        halfx = maxx >> 1;
-        halfy = maxy >> 1;
-    }
-    for (DBusTopWindow* v : g_views)
-    {
-        v->OnResize(maxx, maxy);
-        if(v->maximize_){
-            v->rect={0,0,maxx,maxy-MARGIN_BOTTOM};
-            v->UpdateWindowSizeAndPosition();
-        }
-    }
-}
-
-std::string FloatToString(float value)
-{
-    return fmt::sprintf("%.2f", value);
-}
-
-void DBusTopRefresh()
-{
-    UpdateWindowSizes();
-    for (DBusTopWindow* v : g_views)
-    {
-        v->Render();
-    }
-    DBusTopWindow* focused_view = g_current_active_view;
-    if (focused_view)
-    {
-        focused_view->DrawBorderIfNeeded(); // focused view border: on top
-    }
-    refresh();
-}
-
-// This function is called by the Capture thread
-void DBusTopStatisticsCallback(DBusTopStatistics* stat, Histogram<float>* hist)
-{
-    if (stat == nullptr)
-        return;
-    // Makes a copy for display
-    // TODO: Add a mutex here for safety
-    stat->Assign(g_dbus_statistics);
-    hist->Assign(g_histogram);
-    float interval_secs = stat->seconds_since_last_sample_;
-    if (interval_secs == 0)
-    {
-        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
-    }
-    g_summary_window->UpdateDBusTopStatistics(stat);
-    stat->SetSortFieldsAndReset(g_dbus_stat_list_view->GetSortFields());
-    // ReinitializeUI(); // Don't do it here, only when user presses [R]
-    DBusTopRefresh();
-}
-
-void CycleHighlightedView()
-{
-    int new_index = 0;
-    if (g_highlighted_view_index == INVALID)
-    {
-        new_index = 0;
-    }
-    else
-    {
-        new_index = g_highlighted_view_index + 1;
-    }
-    while (new_index < static_cast<int>(g_views.size()) &&
-           g_views[new_index]->selectable_ == false)
-    {
-        new_index++;
-    }
-    if (new_index >= static_cast<int>(g_views.size()))
-    {
-        new_index = INVALID;
-    }
-    // Un-highlight all
-    for (DBusTopWindow* v : g_views)
-    {
-        v->focused_ = false;
-    }
-    if (new_index != INVALID)
-    {
-        g_views[new_index]->focused_ = true;
-        g_current_active_view = g_views[new_index];
-    }
-    else
-    {
-        g_current_active_view = nullptr;
-    }
-    g_highlighted_view_index = new_index;
-    DBusTopRefresh();
-}
-
-int UserInputThread()
-{
-    while (true)
-    {
-        int c = getch();
-        DBusTopWindow* curr_view = g_current_active_view;
-        // If a view is currently focused on
-        if (curr_view)
-        {
-            switch (c)
-            {
-                case '\e': // 27 in dec, 0x1B in hex, escape key
-                {
-                    getch();
-                    c = getch();
-                    switch (c)
-                    {
-                        case 'A':
-                            curr_view->OnKeyDown("up");
-                            break;
-                        case 'B':
-                            curr_view->OnKeyDown("down");
-                            break;
-                        case 'C':
-                            curr_view->OnKeyDown("right");
-                            break;
-                        case 'D':
-                            curr_view->OnKeyDown("left");
-                            break;
-                        case '\e':
-                            curr_view->OnKeyDown("escape");
-                            break;
-                    }
-                    break;
-                }
-                case '\n': // 10 in dec, 0x0A in hex, line feed
-                {
-                    curr_view->OnKeyDown("enter");
-                    break;
-                }
-                case 'q':
-                case 'Q': // Q key
-                {
-                    curr_view->OnKeyDown("escape");
-                    break;
-                }
-                case 'a':
-                case 'A': // A key
-                {
-                    curr_view->OnKeyDown("a");
-                    break;
-                }
-                case 'd':
-                case 'D': // D key
-                {
-                    curr_view->OnKeyDown("d");
-                    break;
-                }
-                case 33: // Page up
-                {
-                    curr_view->OnKeyDown("pageup");
-                    break;
-                }
-                case 34: // Page down
-                {
-                    curr_view->OnKeyDown("pagedown");
-                    break;
-                }
-                case ' ': // Spacebar
-                {
-                    curr_view->OnKeyDown("space");
-                    break;
-                }
-            }
-        }
-        // The following keys are registered both when a view is selected and
-        // when it is not
-        switch (c)
-        {
-            case '\t': // 9 in dec, 0x09 in hex, tab
-            {
-                CycleHighlightedView();
-                break;
-            }
-            case 'r':
-            case 'R':
-            {
-                ReinitializeUI();
-                DBusTopRefresh();
-                break;
-            }
-            case 'x':
-            case 'X':
-            {
-                clear();
-                ActivateWindowA();
-                break;
-            }
-            case 'y':
-            case 'Y':
-            {
-                clear();
-                ActivateWindowB();
-                break;
-            }
-            case 'z':
-            case 'Z':
-            {
-                clear();
-                ActivateWindowC();
-                break;
-            }
-            case 'h':
-            case 'H':
-            {
-                ActivateAllWindows();
-                DBusTopRefresh();
-            }
-            default:
-                break;
-        }
-    }
-    exit(0);
-}
-
-void ReinitializeUI()
-{
-    endwin();
-    initscr();
-    use_default_colors();
-    noecho();
-    for (int i = 0; i < static_cast<int>(g_views.size()); i++)
-    {
-        g_views[i]->RecreateWindow();
-    }
-}
-
-int main(int argc, char** argv)
-{
-    int r = AcquireBus(&g_bus);
-    if (r <= 0)
-    {
-        printf("Error acquiring bus for monitoring\n");
-        exit(0);
-    }
-
-    printf("Listing all sensors for display\n");
-    // ListAllSensors creates connection snapshot and sensor snapshot
-    dbus_top_analyzer::ListAllSensors();
-    g_bargraph = new BarGraph<float>(300);
-    g_histogram = new Histogram<float>();
-
-    initscr();
-    use_default_colors();
-    start_color();
-    noecho();
-
-    clear();
-    g_dbus_statistics = new DBusTopStatistics();
-    g_summary_window = new SummaryView();
-    g_sensor_detail_view = new SensorDetailView();
-    g_dbus_stat_list_view = new DBusStatListView();
-    g_footer_view = new FooterView();
-    g_views.push_back(g_summary_window);
-    g_views.push_back(g_sensor_detail_view);
-    g_views.push_back(g_dbus_stat_list_view);
-    g_views.push_back(g_footer_view);
-
-    g_sensor_detail_view->UpdateSensorSnapshot(g_sensor_snapshot);
-    UpdateWindowSizes();
-    dbus_top_analyzer::SetDBusTopStatisticsCallback(&DBusTopStatisticsCallback);
-    std::thread capture_thread(DbusCaptureThread);
-    std::thread user_input_thread(UserInputThread);
-    capture_thread.join();
-
-    return 0;
-}
diff --git a/dbus-top/main.hpp b/dbus-top/main.hpp
deleted file mode 100644
index 91c07da..0000000
--- a/dbus-top/main.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "bargraph.hpp"
-
-#include <ncurses.h>
-
-#include <string>
-
-const int INVALID = -999; // Constant indicating invalid indices
-struct Rect
-{
-    int x, y, w, h; // X, Y, Width, Height
-    Rect(int _x, int _y, int _w, int _h) : x(_x), y(_y), w(_w), h(_h)
-    {}
-    Rect() : x(0), y(0), w(1), h(1)
-    {}
-};
-
-int DrawTextWithWidthLimit(WINDOW* win, std::string txt, int y, int x,
-                           int width, const std::string& delimiters);
-std::string FloatToString(float value);
-template <typename T>
-void HistoryBarGraph(WINDOW* win, const Rect& rect, BarGraph<T>* bargraph);
diff --git a/dbus-top/menu.cpp b/dbus-top/menu.cpp
deleted file mode 100644
index 47d1f57..0000000
--- a/dbus-top/menu.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "menu.hpp"
-
-#include "views.hpp"
-
-ArrowKeyNavigationMenu::ArrowKeyNavigationMenu(DBusTopWindow* view) :
-    win_(view->win), parent_(view), idx0_(INVALID), idx1_(INVALID),
-    h_padding_(2), col_width_(15), h_spacing_(2), choice_(INVALID)
-{}
-
-void ArrowKeyNavigationMenu::do_Render(bool is_column_major)
-{
-    const int nrows = DispEntriesPerColumn();
-    const int ncols = DispEntriesPerRow();
-    const int items_per_page = nrows * ncols;
-    if (items_per_page < 1)
-        return;
-    int tot_num_items = items_.size();
-    // int tot_num_columns = (tot_num_items - 1) / nrows + 1;
-    // Determine whether cursor is outside the current rectangular viewport
-    bool is_cursor_out_of_view = false;
-    if (idx0_ > choice_ || idx1_ <= choice_)
-    {
-        is_cursor_out_of_view = true;
-    }
-    if (idx0_ == INVALID || idx1_ == INVALID)
-    {
-        is_cursor_out_of_view = true;
-    }
-    // Scroll the viewport such that it contains the cursor
-    if (is_cursor_out_of_view)
-    {
-        idx0_ = 0;
-        idx1_ = items_per_page;
-    }
-    while (idx1_ <= choice_)
-    {
-        if (is_column_major)
-        {
-            idx0_ += nrows;
-            idx1_ += nrows;
-        }
-        else
-        {
-            idx0_ += ncols;
-            idx1_ += ncols;
-        }
-    }
-    int y0 = rect_.y, x0 = rect_.x;
-    int y = y0, x = x0;
-    for (int i = 0; i < items_per_page; i++)
-    {
-        int idx = idx0_ + i;
-        if (idx < tot_num_items)
-        {
-            if (idx == choice_)
-            {
-                wattrset(win_, A_REVERSE);
-            }
-            std::string s = items_[idx];
-            while (s.size() < col_width_)
-            {
-                s.push_back(' ');
-            }
-            mvwaddstr(win_, y, x, s.c_str());
-            wattrset(win_, 0);
-        }
-        else
-        {
-            break;
-        }
-        if (is_column_major)
-        {
-            y++;
-            if (i % nrows == nrows - 1)
-            {
-                y = y0;
-                x += col_width_ + h_spacing_;
-            }
-        }
-        else
-        {
-            x += col_width_ + h_spacing_;
-            if (i % ncols == ncols - 1)
-            {
-                x = x0;
-                y++;
-            }
-        }
-    }
-}
-
-void ArrowKeyNavigationMenu::Render()
-{
-    do_Render(order == ColumnMajor);
-}
-
-void ArrowKeyNavigationMenu::OnKeyDown(const std::string& key)
-{
-    switch (order)
-    {
-        case ColumnMajor:
-            if (key == "up")
-            {
-                MoveCursorAlongPrimaryAxis(-1);
-            }
-            else if (key == "down")
-            {
-                MoveCursorAlongPrimaryAxis(1);
-            }
-            else if (key == "left")
-            {
-                MoveCursorAlongSecondaryAxis(-1);
-            }
-            else if (key == "right")
-            {
-                MoveCursorAlongSecondaryAxis(1);
-            }
-            break;
-        case RowMajor:
-            if (key == "up")
-            {
-                MoveCursorAlongSecondaryAxis(-1);
-            }
-            else if (key == "down")
-            {
-                MoveCursorAlongSecondaryAxis(1);
-            }
-            else if (key == "left")
-            {
-                MoveCursorAlongPrimaryAxis(-1);
-            }
-            else if (key == "right")
-            {
-                MoveCursorAlongPrimaryAxis(1);
-            }
-            break;
-            break;
-    }
-}
-
-void ArrowKeyNavigationMenu::MoveCursorAlongPrimaryAxis(int delta)
-{
-    const int N = items_.size();
-    if (N < 1)
-        return;
-    // If the cursor is inactive, activate it
-    if (choice_ == INVALID)
-    {
-        if (delta > 0)
-        {
-            choice_ = 0;
-        }
-        else
-        {
-            choice_ = N - 1;
-        }
-        return;
-    }
-    int choice_next = choice_ + delta;
-    while (choice_next >= N)
-    {
-        choice_next -= N;
-    }
-    while (choice_next < 0)
-    {
-        choice_next += N;
-    }
-    choice_ = choice_next;
-}
-
-void ArrowKeyNavigationMenu::MoveCursorAlongSecondaryAxis(int delta)
-{
-    if (delta != 0 && delta != 1 && delta != -1)
-        return;
-    const int N = items_.size();
-    if (N < 1)
-        return;
-    // If the cursor is inactive, activate it
-    if (choice_ == INVALID)
-    {
-        if (delta > 0)
-        {
-            choice_ = 0;
-        }
-        else
-        {
-            choice_ = N - 1;
-        }
-        return;
-    }
-    const int nrows =
-        (order == ColumnMajor) ? DispEntriesPerColumn() : DispEntriesPerRow();
-    const int tot_columns = (N - 1) / nrows + 1;
-    const int num_rows_last_column = N - nrows * (tot_columns - 1);
-    int y = choice_ % nrows, x = choice_ / nrows;
-    if (delta == 1)
-    {
-        x++;
-    }
-    else
-    {
-        x--;
-    }
-    bool overflow_to_right = false;
-    if (y < num_rows_last_column && x >= tot_columns)
-    {
-        overflow_to_right = true;
-    }
-    if (y >= num_rows_last_column && x >= tot_columns - 1)
-    {
-        overflow_to_right = true;
-    }
-    bool overflow_to_left = false;
-    if (x < 0)
-    {
-        overflow_to_left = true;
-    }
-    if (overflow_to_right)
-    {
-        y++;
-        if (y >= nrows)
-        {
-            choice_ = 0;
-            return;
-        }
-        else
-        {
-            choice_ = y;
-            return;
-        }
-    }
-    else if (overflow_to_left)
-    {
-        y--;
-        if (y < 0)
-        {
-            if (num_rows_last_column == nrows)
-            {
-                choice_ = N - 1;
-            }
-            else
-            {
-                choice_ = N - num_rows_last_column - 1;
-            }
-            return;
-        }
-        else
-        {
-            if (y < num_rows_last_column)
-            {
-                choice_ = nrows * (tot_columns - 1) + y;
-            }
-            else
-            {
-                choice_ = nrows * (tot_columns - 2) + y;
-            }
-        }
-    }
-    else
-    {
-        choice_ = y + x * nrows;
-    }
-}
-
-void ArrowKeyNavigationMenu::SetChoiceAndConstrain(int c)
-{
-    if (Empty())
-    {
-        choice_ = INVALID;
-        return;
-    }
-    if (c < 0)
-        c = 0;
-    if (c >= static_cast<int>(items_.size()))
-    {
-        c = static_cast<int>(items_.size() - 1);
-    }
-    choice_ = c;
-}
-
-void ArrowKeyNavigationMenu::AddItem(const std::string& s)
-{
-    items_.push_back(s);
-}
-
-bool ArrowKeyNavigationMenu::RemoveHighlightedItem(std::string* ret)
-{
-    if (choice_ < 0 || choice_ >= items_.size())
-        return false;
-    std::string r = items_[choice_];
-    items_.erase(items_.begin() + choice_);
-    if (items_.empty())
-    {
-        Deselect();
-    }
-    else
-    {
-        if (choice_ >= items_.size())
-        {
-            choice_ = items_.size() - 1;
-        }
-    }
-    if (ret)
-    {
-        *ret = r;
-    }
-    return true;
-}
diff --git a/dbus-top/menu.hpp b/dbus-top/menu.hpp
deleted file mode 100644
index afb4110..0000000
--- a/dbus-top/menu.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "main.hpp"
-
-#include <ncurses.h>
-
-#include <string>
-#include <vector>
-class DBusTopWindow;
-class ArrowKeyNavigationMenu
-{
-  public:
-    explicit ArrowKeyNavigationMenu(WINDOW* win) :
-        win_(win), h_padding_(2), col_width_(15), h_spacing_(2), idx0_(INVALID),
-        idx1_(INVALID), choice_(INVALID), parent_(nullptr)
-    {}
-    explicit ArrowKeyNavigationMenu(DBusTopWindow* view);
-    void LoadDummyValues()
-    {
-        items_.clear();
-        items_.push_back("Sender");
-        items_.push_back("Destination");
-        items_.push_back("Interface");
-        items_.push_back("Path");
-        items_.push_back("Member");
-    }
-
-    void OnKeyDown(const std::string& key);
-    void Render();
-    void MoveCursorAlongSecondaryAxis(int delta);
-    void MoveCursorAlongPrimaryAxis(int delta);
-    int DispEntriesPerRow()
-    {
-        int ncols = 0;
-        while (true)
-        {
-            int next = ncols + 1;
-            int w = 2 * h_padding_ + col_width_ * next;
-            if (next > 1)
-                w += (next - 1) * h_spacing_;
-            if (w <= rect_.w - 2)
-            {
-                ncols = next;
-            }
-            else
-            {
-                break;
-            }
-        }
-        return ncols;
-    }
-
-    int DispEntriesPerColumn()
-    {
-        return rect_.h;
-    }
-
-    void SetRect(const Rect& rect)
-    {
-        rect_ = rect;
-    }
-
-    enum Order
-    {
-        ColumnMajor,
-        RowMajor,
-    };
-
-    void SetOrder(Order o)
-    {
-        order = o;
-    }
-
-    int Choice()
-    {
-        return choice_;
-    }
-
-    void Deselect()
-    {
-        choice_ = INVALID;
-    }
-
-    bool Empty()
-    {
-        return items_.empty();
-    }
-
-    void SetChoiceAndConstrain(int c);
-    Rect rect_;
-    void AddItem(const std::string& s);
-    bool RemoveHighlightedItem(std::string* ret); // returns true if successful
-    std::vector<std::string> Items()
-    {
-        return items_;
-    }
-
-    void do_Render(bool is_column_major);
-    std::vector<std::string> items_;
-    WINDOW* win_;
-    int h_padding_;
-    int col_width_;
-    int h_spacing_;
-    int idx0_, idx1_;
-    int choice_;
-    DBusTopWindow* parent_;
-    Order order;
-};
-
diff --git a/dbus-top/meson.build b/dbus-top/meson.build
deleted file mode 100644
index 60d4641..0000000
--- a/dbus-top/meson.build
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# 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.
-
-project('dbus-top', 'cpp',
-    version: '0.1',
-    default_options: 
-    [
-        'cpp_std=c++17',
-    ],
-)
-
-cmake = import('cmake')
-fmt_proj = cmake.subproject('fmt')
-fmt_dep = fmt_proj.dependency('fmt')
-
-bindir = get_option('prefix') / get_option('bindir')
-executable('dbus-top',
-    [
-        'menu.cpp',
-        'analyzer.cpp',
-        'dbus_capture.cpp',
-        'sensorhelper.cpp',
-        'xmlparse.cpp',
-        'views.cpp',
-        'main.cpp',
-    ],
-    dependencies:
-    [
-        dependency('systemd'),
-        dependency('sdbusplus'),
-        dependency('ncurses'),
-        dependency('threads'),
-        fmt_dep
-    ],
-    install: true,
-    install_dir: bindir
-)
diff --git a/dbus-top/rect.hpp b/dbus-top/rect.hpp
deleted file mode 100644
index aa7bf89..0000000
--- a/dbus-top/rect.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2021 Google LLC
- *
- * 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
-
-struct Rect
-{
-    int x, y, w, h; // X, Y, Width, Height
-    Rect(int _x, int _y, int _w, int _h) : x(_x), y(_y), w(_w), h(_h)
-    {}
-    Rect() : x(0), y(0), w(1), h(1)
-    {}
-};
\ No newline at end of file
diff --git a/dbus-top/sensorhelper.cpp b/dbus-top/sensorhelper.cpp
deleted file mode 100644
index 3f8bba6..0000000
--- a/dbus-top/sensorhelper.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "sensorhelper.hpp"
-#include "main.hpp"
-
-#include <unistd.h>
-
-#include <cassert>
-#include <fstream>
-#include <functional>
-#include <sstream>
-#include <string>
-#include <vector>
-
-extern SensorSnapshot* g_sensor_snapshot;
-extern DBusConnectionSnapshot* g_connection_snapshot;
-
-std::vector<std::string> MySplit(const std::string& s)
-{
-    int idx = 0, prev_idx = 0;
-    std::vector<std::string> ret;
-    while (idx <= static_cast<int>(s.size()))
-    {
-        if (idx == static_cast<int>(s.size()) || s[idx] == '/')
-        {
-            if (idx > prev_idx)
-            {
-                ret.push_back(s.substr(prev_idx, idx - prev_idx));
-            }
-            prev_idx = idx + 1;
-        }
-        idx++;
-    }
-    return ret;
-}
-
-// Example: /xyz/openbmc_project/sensors/temperature/powerseq_temp
-bool IsSensorObjectPath(const std::string& s)
-{
-    std::vector<std::string> sections = MySplit(s);
-    if (sections.size() == 5 && sections[0] == "xyz" &&
-        sections[1] == "openbmc_project" && sections[2] == "sensors")
-    {
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-// Example: /xyz/openbmc_project/sensors/temperature/powerseq_temp/chassis
-bool IsSensorObjectPathWithAssociation(const std::string& s,
-                                       std::string* sensor_obj_path)
-{
-    std::vector<std::string> sections = MySplit(s);
-    if (sections.size() == 6)
-    {
-        size_t idx = s.rfind('/');
-        return IsSensorObjectPath(s.substr(0, idx));
-    }
-    else
-    {
-        return false;
-    }
-}
-
-bool IsUniqueName(const std::string& x)
-{
-    if (x.empty())
-        return false;
-    if (x[0] != ':')
-        return false;
-    if (x[0] == ':')
-    {
-        for (int i = 1; i < int(x.size()); i++)
-        {
-            const char ch = x[i];
-            if (ch >= '0' || ch <= '9')
-                continue;
-            else if (ch == '.')
-                continue;
-            else
-                return false;
-        }
-    }
-    return true;
-}
-
-std::vector<std::string> FindAllObjectPathsForService(
-    const std::string& service,
-    std::function<void(const std::string&, const std::vector<std::string>&)>
-        on_interface_cb)
-{
-    // Not available for PCAP replay, only valid with actual DBus capture
-    assert(false);
-}
-
-bool IsWhitespace(const char c)
-{
-    if (c == ' ' || c == '\r' || c == '\n')
-        return true;
-    else
-        return false;
-}
-
-std::string Trim(const std::string& s)
-{
-    const int N = int(s.size());
-    int idx0 = 0, idx1 = int(N - 1);
-    while (idx0 < N && IsWhitespace(s[idx0]))
-        idx0++;
-    while (idx1 >= 0 && IsWhitespace(s[idx1]))
-        idx1--;
-    if (idx0 >= N || idx1 < 0)
-        return "";
-    return s.substr(idx0, idx1 - idx0 + 1);
-}
diff --git a/dbus-top/sensorhelper.hpp b/dbus-top/sensorhelper.hpp
deleted file mode 100644
index a619c4a..0000000
--- a/dbus-top/sensorhelper.hpp
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "main.hpp"
-// This is the form a sensor assumes on DBus.
-// Aggregates their view from all other daemons.
-#include <bitset>
-#include <optional>
-#include <set>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-// Where is this sensor seen?
-constexpr int VISIBILITY_OBJECT_MAPPER = 0;
-constexpr int VISIBILITY_HWMON = 1;
-constexpr int VISIBILITY_IPMITOOL_SDR = 2;
-class DBusConnection
-{
-  public:
-    std::string service;    // example: "systemd-resolved"
-    std::string connection; // example: ":1.1"
-    std::string cmd;        // the comm line
-    std::string unit;       // example: "systemd-resolved.service"
-    int pid;
-    // For actual DBus capture: service name, connection name, command line,
-    //                          systmed unit and PID are all known
-    DBusConnection(const std::string& _s, const std::string& _c,
-                   const std::string& _cmd, const std::string& _u, int _pid)
-    {
-        service = _s;
-        connection = _c;
-        cmd = _cmd;
-        unit = _u;
-        pid = _pid;
-    }
-
-    // During PCap replay: only service name, connection name, and PID are known
-    //                     cmd and unit are not known since they are not
-    //                     stored in the PCap file
-    DBusConnection(const std::string& _s, const std::string& _c, int _pid)
-    {
-        service = _s;
-        connection = _c;
-        pid = _pid;
-    }
-};
-
-class DBusConnectionSnapshot
-{
-  public:
-    std::vector<DBusConnection*> connections_;
-    std::unordered_map<std::string, DBusConnection*> unique_name_to_cxn;
-    DBusConnection* FindDBusConnectionByService(const std::string& service)
-    {
-        for (DBusConnection* cxn : connections_)
-        {
-            if (cxn->service == service)
-                return cxn;
-        }
-        return nullptr;
-    }
-
-    void SetConnectionPID(const std::string& connection, int pid)
-    {
-        DBusConnection* cxn = FindDBusConnectionByService(connection);
-        if (cxn != nullptr)
-        {
-            cxn->pid = pid;
-            unique_name_to_cxn[connection] = cxn; // Just to make sure
-        }
-    }
-
-    void SetConnectionUniqueName(const std::string& service,
-                                 const std::string& unique_name)
-    {
-        DBusConnection* cxn = FindDBusConnectionByService(service);
-        if (cxn != nullptr)
-        {
-            cxn->connection = unique_name;
-            unique_name_to_cxn[unique_name] = cxn;
-        }
-    }
-
-    DBusConnection* FindDBusConnectionByConnection(const std::string& conn)
-    {
-        for (DBusConnection* cxn : connections_)
-        {
-            if (cxn->connection == conn)
-                return cxn;
-        }
-        return nullptr;
-    }
-
-
-    // Only when service is known (during playback)
-    void AddConnection(const std::string& _s)
-    {
-        connections_.push_back(new DBusConnection(_s, "", "", "", INVALID));
-    }
-
-    // When all 5 pieces of details are known (during actual capture)
-    void AddConnection(const std::string& _s, const std::string& _connection,
-                       const std::string& _cmd, const std::string& _unit,
-                       int _pid)
-    {
-        DBusConnection* cxn =
-            new DBusConnection(_s, _connection, _cmd, _unit, _pid);
-        connections_.push_back(cxn);
-        unique_name_to_cxn[_connection] = cxn;
-    }
-
-    int GetConnectionPIDFromNameOrUniqueName(const std::string& key)
-    {
-        if (unique_name_to_cxn.find(key) == unique_name_to_cxn.end())
-        {
-            return INVALID;
-        }
-        else
-        {
-            return unique_name_to_cxn[key]->pid;
-        }
-    }
-
-    std::string GetConnectionCMDFromNameOrUniqueName(const std::string& key)
-    {
-        if (unique_name_to_cxn.find(key) == unique_name_to_cxn.end())
-        {
-            return "(unknown)";
-        }
-        else
-        {
-            return unique_name_to_cxn[key]->cmd;
-        }
-    }
-
-    std::string GetUniqueNameIfExists(const std::string service)
-    {
-        for (DBusConnection* cxn : connections_)
-        {
-            if (cxn->service == service)
-                return cxn->connection;
-        }
-        return service;
-    }
-
-};
-
-// Each sensor might have different units, for example current and voltage
-class Sensor
-{
-  public:
-    DBusConnection* connection_;
-    // Example: "/xyz/openbmc_project/sensors/temperature/powerseq_temp"
-    std::string object_path_;
-    std::string SensorID()
-    {
-        const size_t idx = object_path_.rfind('/');
-        if (idx != std::string::npos)
-        {
-            return object_path_.substr(idx + 1);
-        }
-        else
-            return ("unknown sensor");
-    }
-
-    std::string ServiceName()
-    {
-        if (connection_ == nullptr)
-            return "";
-        else
-            return connection_->service;
-    }
-
-    std::string ConnectionName()
-    {
-        if (connection_ == nullptr)
-            return "";
-        else
-            return connection_->connection;
-    }
-
-    std::string ObjectPath()
-    {
-        return object_path_;
-    }
-
-    // Should contain the following:
-    // 1. "org.freedesktop.DBus.Introspectable"
-    // 2. "org.freedesktop.DBus.Peer"
-    // 3. "org.freedesktop.DBus.Properties"
-    // 4. "xyz.openbmc_project.Sensor.Value"
-    // 5. "xyz.openbmc_project.State.Decorator.OperationalStatus"
-    std::set<std::string> interfaces_;
-    std::bitset<4> visibility_flags_;
-    std::set<std::string> associations_;
-};
-
-class SensorSnapshot
-{
-  public:
-    std::vector<std::string> GetDistinctSensorNames()
-    {
-        std::unordered_set<std::string> seen;
-        std::vector<std::string> ret;
-        for (Sensor* s : sensors_)
-        {
-            std::string sn = s->SensorID();
-            if (seen.find(sn) == seen.end())
-            {
-                ret.push_back(sn);
-                seen.insert(sn);
-            }
-        }
-        return ret;
-    }
-
-    explicit SensorSnapshot(DBusConnectionSnapshot* cs)
-    {
-        connection_snapshot_ = cs;
-    }
-
-    ~SensorSnapshot()
-    {
-        for (Sensor* s : sensors_)
-        {
-            delete s;
-        }
-    }
-
-    int SensorCount()
-    {
-        return int(sensors_.size());
-    }
-
-    Sensor* FindOrCreateSensorByServiceAndObject(const std::string& service,
-                                                 const std::string& object)
-    {
-        Sensor* ret = nullptr;
-        for (Sensor* s : sensors_)
-        {
-            if (s->ServiceName() == service && s->object_path_ == object)
-            {
-                ret = s;
-                break;
-            }
-        }
-        if (ret == nullptr)
-        {
-            DBusConnection* cxn =
-                connection_snapshot_->FindDBusConnectionByService(service);
-            ret = new Sensor();
-            ret->connection_ = cxn;
-            ret->object_path_ = object;
-            sensors_.push_back(ret);
-        }
-        return ret;
-    }
-
-    // Note: one sensor_id might correspond to multiple sensors.
-    // Example: "VDD" can have all 3 of power, current and voltage.
-    std::vector<Sensor*> FindSensorsBySensorID(const std::string& sensor_id)
-    {
-        std::vector<Sensor*> ret;
-        for (Sensor* s : sensors_)
-        {
-            const std::string& p = s->object_path_;
-            if (p.find(sensor_id) == p.size() - sensor_id.size())
-            {
-                ret.push_back(s);
-            }
-        }
-        return ret;
-    }
-
-    // This sensor is visible from Object Mapper
-    void SerSensorVisibleFromObjectMapper(const std::string& service,
-                                          const std::string& object)
-    {
-        Sensor* s = FindOrCreateSensorByServiceAndObject(service, object);
-        s->visibility_flags_.set(VISIBILITY_OBJECT_MAPPER);
-    }
-    
-    // This sensor is visible from Hwmon
-    void SetSensorVisibleFromHwmon(const std::string& service,
-                                   const std::string& object)
-    {
-        Sensor* s = FindOrCreateSensorByServiceAndObject(service, object);
-        s->visibility_flags_.set(VISIBILITY_HWMON);
-    }
-
-    // This sensor is visible from `ipmitool sdr`
-    // The first column is referred to as "sensorid".
-    void SetSensorVisibleFromIpmitoolSdr(const std::string& sensor_id)
-    {
-        std::vector<Sensor*> sensors = FindSensorsBySensorID(sensor_id);
-        for (Sensor* s : sensors)
-            s->visibility_flags_.set(VISIBILITY_IPMITOOL_SDR);
-    }
-
-    void PrintSummary()
-    {
-        for (Sensor* s : sensors_)
-        {
-            printf("%50s %50s %9s\n", s->ServiceName().c_str(),
-                   s->object_path_.c_str(),
-                   s->visibility_flags_.to_string().c_str());
-        }
-    }
-
-    Sensor* FindSensorByDBusUniqueNameOrServiceName(const std::string& key)
-    {
-        for (Sensor* s : sensors_)
-        {
-            if (s->ConnectionName() == key || s->ServiceName() == key)
-                return s;
-        }
-        return nullptr;
-    }
-
-  private:
-    std::vector<Sensor*> sensors_;
-    std::unordered_map<std::string, int> conn2pid_;
-    DBusConnectionSnapshot* connection_snapshot_;
-};
-
-bool IsSensorObjectPath(const std::string& s);
-bool IsUniqueName(const std::string& x);
-std::string Trim(const std::string& s);
diff --git a/dbus-top/subprojects/fmt.wrap b/dbus-top/subprojects/fmt.wrap
deleted file mode 100644
index 6847ae5..0000000
--- a/dbus-top/subprojects/fmt.wrap
+++ /dev/null
@@ -1,3 +0,0 @@
-[wrap-git]
-url = https://github.com/fmtlib/fmt
-revision = HEAD
diff --git a/dbus-top/subprojects/sdbusplus.wrap b/dbus-top/subprojects/sdbusplus.wrap
deleted file mode 100644
index 7b076d0..0000000
--- a/dbus-top/subprojects/sdbusplus.wrap
+++ /dev/null
@@ -1,6 +0,0 @@
-[wrap-git]
-url = https://github.com/openbmc/sdbusplus.git
-revision = HEAD
-
-[provide]
-sdbusplus = sdbusplus_dep
diff --git a/dbus-top/views.cpp b/dbus-top/views.cpp
deleted file mode 100644
index fdbf85d..0000000
--- a/dbus-top/views.cpp
+++ /dev/null
@@ -1,1236 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "views.hpp"
-#include "bargraph.hpp"
-#include "histogram.hpp"
-#include "menu.hpp"
-#include <string.h>
-#include <algorithm>
-
-extern SensorSnapshot* g_sensor_snapshot;
-extern BarGraph<float>* g_bargraph;
-extern DBusTopStatistics* g_dbus_statistics;
-extern Histogram<float>* g_histogram;
-extern DBusTopWindow* g_current_active_view;
-extern const std::string FieldNames[];
-extern const int FieldPreferredWidths[];
-
-namespace dbus_top_analyzer
-{
-    extern DBusTopStatistics g_dbus_statistics;
-}
-
-// Linear interpolation
-float Lerp(float a, float b, float t)
-{
-    return a + t * (b - a);
-}
-
-// Linear map
-float Map(float value, float start1, float stop1, float start2, float stop2,
-          bool within_bounds)
-{
-    float t = (value - start1) / (stop1 - start1);
-    float ret = Lerp(start2, stop2, t);
-    if (within_bounds)
-    {
-        if (ret < start2)
-            ret = start2;
-        if (ret > stop2)
-            ret = stop2;
-    }
-    return ret;
-}
-
-template <typename T>
-void HistoryBarGraph(WINDOW* win, const Rect& rect, BarGraph<T>* bargraph)
-{
-    const int RIGHT_MARGIN = 5;
-    const int x0 = rect.x, y0 = 2;
-    const int w = rect.w - 2 - RIGHT_MARGIN;
-    const int h = rect.h - 3; // height of content
-    wattrset(win, 0);
-    wattron(win, A_BOLD | A_UNDERLINE);
-    mvwaddstr(win, 1, x0, "History     (Total msg/s)");
-    wattrset(win, 0);
-    // 1. Obtain data, determine Y range
-    std::vector<float> data = bargraph->GetLastNValues(w - RIGHT_MARGIN - 1);
-    float ymax = -1e20, ymin = 1e20;
-    if (data.empty())
-    {
-        data.push_back(0);
-        ymin = 0;
-        ymax = 10;
-    }
-    else
-    {
-        for (const float x : data)
-        {
-            ymax = std::max(ymax, x);
-            ymin = std::min(ymin, x);
-        }
-    }
-    // Fix edge case for both == 0
-    float diff = ymax - ymin;
-    if (diff < 0)
-    {
-        diff = -diff;
-    }
-    const float EPS = 1e-4;
-    if (diff < EPS)
-    {
-        ymax += 10;
-        ymin -= 10;
-    }
-    // Choose a suitable round-up unit to snap the grid labels to
-    int snap = 1;
-    if (ymax < 100)
-    {
-        snap = 10;
-    }
-    else if (ymax < 10000)
-    {
-        snap = 100;
-    }
-    else
-    {
-        snap = 1000;
-    }
-    const float eps = snap / 100.0f;
-    int label_ymax =
-        (static_cast<int>((ymax - eps) / snap) + 1) * snap; // round up
-    int label_ymin = static_cast<int>(ymin / snap) * snap;  // round down
-    float y_per_row = (label_ymax - label_ymin) * 1.0f / (h - 1);
-    int actual_ymax = label_ymax + static_cast<int>(y_per_row / 2);
-    int actual_ymin = label_ymin - static_cast<int>(y_per_row / 2);
-    // 2. Print Y axis ticks
-    for (int i = 0; i < h; i++)
-    {
-        char buf[10];
-        snprintf(
-            buf, sizeof(buf), "%-6d",
-            static_cast<int>(Lerp(label_ymax, label_ymin, i * 1.0f / (h - 1))));
-        mvwaddstr(win, i + y0, x0 + w - RIGHT_MARGIN + 1, buf);
-        mvwaddch(win, i + y0, x0, '-');
-        mvwaddch(win, i + y0, x0 + w - RIGHT_MARGIN, '-');
-    }
-    // 3. Go through the historical data and draw on the canvas
-    for (int i = 0;
-         i < std::min(static_cast<int>(data.size()), w - RIGHT_MARGIN - 1); i++)
-    {
-        float value = data[i];
-        // antialiasing: todo for now
-        // float value1 = value; // value1 is 1 column to the right
-        // if (i > 0) value1 = data[i-1];
-        int x = x0 + w - i - RIGHT_MARGIN - 1;
-        float t = Map(value, actual_ymin, actual_ymax, 0, h, true);
-        int row = static_cast<int>(t);
-        float remaining = t - row;
-        char ch; // Last filling character
-        if (remaining >= 0.66f)
-        {
-            ch = ':';
-        }
-        else if (remaining >= 0.33f)
-        {
-            ch = '.';
-        }
-        else
-        {
-            ch = ' ';
-        }
-        int y = y0 + h - row - 1;
-        mvwaddch(win, y, x, ch);
-        for (int j = 0; j < row; j++)
-        {
-            mvwaddch(win, y + j + 1, x, ':');
-        }
-    }
-}
-
-template <typename T>
-void DrawHistogram(WINDOW* win, const Rect& rect, Histogram<T>* histogram)
-{
-    // const int MARGIN = 7;  // 5 digits margin
-    const int LEFT_MARGIN = 7;
-    // const int max_bucket_h = histogram->MaxBucketHeight();
-    const int H_PAD = 0, V_PAD = 1;
-    // x0, x1, y0 and y1 are the bounding box of the contents to be printed
-    const int x0 = rect.x + H_PAD;
-    const int x1 = rect.x + rect.w - H_PAD;
-    const int y0 = rect.y + V_PAD;
-    const int y1 = rect.y + rect.h - 1 - V_PAD;
-    // Title
-    wattron(win, A_BOLD | A_UNDERLINE);
-    mvwaddstr(win, y0, x0, "Method Call Time (us) Histogram");
-    wattrset(win, 0);
-    // x2 is the beginning X of the histogram itself (not containing the margin)
-    const int x2 = x0 + LEFT_MARGIN;
-    if (histogram->Empty())
-    {
-        mvwaddstr(win, (y1 + y0) / 2, (x0 + x1) / 2, "(Empty)");
-        return;
-    }
-    histogram->SetBucketCount(x1 - x2 + 1);
-    histogram->ComputeHistogram();
-    // Draw X axis labels
-    char buf[22];
-    snprintf(buf, sizeof(buf), "%.2f",
-             static_cast<float>(histogram->LowPercentile()));
-    mvwaddstr(win, y1, x0 + LEFT_MARGIN, buf);
-    snprintf(buf, sizeof(buf), "%.2f",
-             static_cast<float>(histogram->HighPercentile()));
-    mvwaddstr(win, y1, x1 + 1 - strlen(buf), buf);
-    snprintf(buf, sizeof(buf), "%d%%-%d%%",
-             static_cast<int>(histogram->LowCumDensity() * 100),
-             static_cast<int>(histogram->HighCumDensity() * 100));
-    mvwaddstr(win, y1, x0, buf);
-    // Draw Y axis labels
-    const float hist_ymax = y1 - 1;
-    const float hist_ymin = y0 + 1;
-    const int max_histogram_h = histogram->MaxBucketHeight();
-    if (hist_ymax <= hist_ymin)
-        return; // Not enough space for rendering
-    if (max_histogram_h <= 0)
-        return;
-    bool LOG_TRANSFORM = true;
-    float lg_maxh = 0;
-    if (LOG_TRANSFORM)
-    {
-        lg_maxh = log(max_histogram_h);
-    }
-    for (int y = hist_ymin; y <= hist_ymax; y++)
-    {
-        // There are (hist_ymax - hist_ymin + 1) divisions
-        float fullness;
-        fullness = (hist_ymax - y + 1) * 1.0f / (hist_ymax - hist_ymin + 1);
-        int h;
-        if (!LOG_TRANSFORM)
-        {
-            h = static_cast<int>(max_histogram_h * fullness);
-        }
-        else
-        {
-            h = static_cast<int>(exp(fullness * lg_maxh));
-        }
-        snprintf(buf, sizeof(buf), "%6d-", h);
-        mvwaddstr(win, y, x0 + LEFT_MARGIN - strlen(buf), buf);
-    }
-    const int bar_height = hist_ymax - hist_ymin + 1; // Height of a full bar
-    for (int x = x2, bidx = 0; x <= x1; x++, bidx++)
-    {
-        int h = histogram->BucketHeight(bidx);
-        float lines_visible;
-        if (!LOG_TRANSFORM)
-        {
-            lines_visible = h * 1.0f / max_histogram_h * bar_height;
-        }
-        else
-        {
-            if (h <= 0)
-                lines_visible = 0;
-            else
-                lines_visible = log(h) * 1.0f / lg_maxh * bar_height;
-        }
-        // The histogram's top shall start from this line
-        int y = hist_ymax - static_cast<int>(lines_visible);
-        float y_frac = lines_visible - static_cast<int>(lines_visible);
-        char ch; // Last filling character
-        if (y >= hist_ymin)
-        { // At the maximum bucket the Y overflows, so skip
-            if (y_frac >= 0.66f)
-            {
-                ch = ':';
-            }
-            else if (y_frac >= 0.33f)
-            {
-                ch = '.';
-            }
-            else
-            {
-                if (y < hist_ymax)
-                {
-                    ch = ' ';
-                }
-                else
-                {
-                    if (y_frac > 0)
-                    {
-                        ch =
-                            '.'; // Makes long-tailed distribution easier to see
-                    }
-                }
-            }
-            mvwaddch(win, y, x, ch);
-        }
-        y++;
-        for (; y <= hist_ymax; y++)
-        {
-            mvwaddch(win, y, x, ':');
-        }
-    }
-}
-
-void SummaryView::UpdateDBusTopStatistics(DBusTopStatistics* stat)
-{
-    if (!stat)
-        return;
-    float interval_secs = stat->seconds_since_last_sample_;
-    if (interval_secs == 0)
-    {
-        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
-    }
-    // Per-second
-    method_call_ = stat->num_mc_ / interval_secs;
-    method_return_ = stat->num_mr_ / interval_secs;
-    signal_ = stat->num_sig_ / interval_secs;
-    error_ = stat->num_error_ / interval_secs;
-    total_ = stat->num_messages_ / interval_secs;
-    g_bargraph->AddValue(total_);
-}
-
-std::string Ellipsize(const std::string& s, int len_limit)
-{
-    if (len_limit <= 3)
-        return s.substr(0, len_limit);
-    if (static_cast<int>(s.size()) < len_limit)
-    {
-        return s;
-    }
-    else
-    {
-        return s.substr(0, len_limit - 3) + "...";
-    }
-}
-
-void SummaryView::Render()
-{
-    // Draw text
-    werase(win);
-    if (!visible_)
-        return;
-    wattron(win, A_BOLD | A_UNDERLINE);
-    mvwaddstr(win, 1, 1, "Message Type          | msg/s");
-    wattrset(win, 0);
-    const int xend = 30;
-    std::string s;
-    s = FloatToString(method_call_);
-    mvwaddstr(win, 2, 1, "Method Call");
-    mvwaddstr(win, 2, xend - s.size(), s.c_str());
-    s = FloatToString(method_return_);
-    mvwaddstr(win, 3, 1, "Method Return ");
-    mvwaddstr(win, 3, xend - s.size(), s.c_str());
-    s = FloatToString(signal_);
-    mvwaddstr(win, 4, 1, "Signal");
-    mvwaddstr(win, 4, xend - s.size(), s.c_str());
-    s = FloatToString(error_);
-    mvwaddstr(win, 5, 1, "Error ");
-    mvwaddstr(win, 5, xend - s.size(), s.c_str());
-    wattron(win, A_UNDERLINE);
-    s = FloatToString(total_);
-    mvwaddstr(win, 6, 1, "Total");
-    mvwaddstr(win, 6, xend - s.size(), s.c_str());
-    wattroff(win, A_UNDERLINE);
-    wattrset(win, 0);
-    // Draw history bar graph
-    Rect bargraph_rect = rect;
-    const int bargraph_x = 64;
-    bargraph_rect.x += bargraph_x;
-    bargraph_rect.w -= bargraph_x;
-    HistoryBarGraph(win, bargraph_rect, g_bargraph);
-    // Draw histogram
-    Rect histogram_rect = rect;
-    histogram_rect.x += 32;
-    histogram_rect.w = bargraph_rect.x - histogram_rect.x - 3;
-    DrawHistogram(win, histogram_rect, g_histogram);
-    // Draw border between summary and histogram
-    for (int y = bargraph_rect.y; y <= bargraph_rect.y + bargraph_rect.h; y++)
-    {
-        mvwaddch(win, y, histogram_rect.x - 1, '|');
-        mvwaddch(win, y, bargraph_rect.x - 1, '|');
-    }
-    DrawBorderIfNeeded();
-    wrefresh(win);
-}
-
-void SensorDetailView::Render()
-{
-    werase(win);
-    if (!visible_)
-        return;
-    // If some sensor is focused, show details regarding that sensor
-    if (state == SensorList)
-    { // Otherwise show the complete list
-        const int ncols = DispSensorsPerRow(); // Number of columns in viewport
-        const int nrows = DispSensorsPerColumn(); // # rows in viewport
-        int sensors_per_page = nrows * ncols;
-        // Just in case the window gets invisibly small
-        if (sensors_per_page < 1)
-            return;
-        int num_sensors = sensor_ids_.size();
-        int total_num_columns = (num_sensors - 1) / nrows + 1;
-        bool is_cursor_out_of_view = false;
-        if (idx0 > choice_ || idx1 <= choice_)
-        {
-            is_cursor_out_of_view = true;
-        }
-        if (idx0 == INVALID || idx1 == INVALID)
-        {
-            is_cursor_out_of_view = true;
-        }
-        if (is_cursor_out_of_view)
-        {
-            idx0 = 0, idx1 = sensors_per_page;
-        }
-        while (idx1 <= choice_)
-        {
-            idx0 += nrows;
-            idx1 += nrows;
-        }
-        const int y0 = 2; // to account for the border and info line
-        const int x0 = 4; // to account for the left overflow marks
-        int y = y0, x = x0;
-        for (int i = 0; i < sensors_per_page; i++)
-        {
-            int idx = idx0 + i;
-            if (idx < static_cast<int>(sensor_ids_.size()))
-            {
-                if (idx == choice_)
-                {
-                    wattrset(win, A_REVERSE);
-                }
-                std::string s = sensor_ids_[idx];
-                if (static_cast<int>(s.size()) > col_width) {
-                    s = s.substr(0, col_width - 2) + "..";
-                } else {
-                    while (static_cast<int>(s.size()) < col_width)
-                    {
-                        s.push_back(' ');
-                    }
-                }
-                mvwaddstr(win, y, x, s.c_str());
-                wattrset(win, 0);
-            }
-            else
-                break;
-            y++;
-            if (i % nrows == nrows - 1)
-            {
-                y = y0;
-                x += col_width + h_spacing;
-            }
-        }
-        // Print overflow marks to the right of the screen
-        for (int i = 0; i < nrows; i++)
-        {
-            int idx = idx0 + sensors_per_page + i;
-            if (idx < num_sensors)
-            {
-                mvwaddch(win, y0 + i, x, '>');
-            }
-        }
-        // Print overflow marks to the left of the screen
-        for (int i = 0; i < nrows; i++)
-        {
-            int idx = idx0 - nrows + i;
-            if (idx >= 0)
-            {
-                mvwaddch(win, y0 + i, 2, '<');
-            }
-        }
-        // idx1 is one past the visible range, so no need to +1
-        const int col0 = idx0 / nrows + 1, col1 = idx1 / nrows;
-        mvwprintw(win, 1, 2, "Columns %d-%d of %d", col0, col1,
-                  total_num_columns);
-        mvwprintw(win, 1, rect.w - 15, "%d sensors", sensor_ids_.size());
-    }
-    else if (state == SensorDetail)
-    {
-        // sensor_ids_ is the cached list of sensors, it should be the same size
-        // as the actual number of sensors in the snapshot
-        mvwprintw(win, 1, 2, "Details of sensor %s", curr_sensor_id_.c_str());
-        mvwprintw(win, 1, rect.w - 15, "Sensor %d/%u", choice_ + 1,
-                  sensor_ids_.size()); // 1-based
-        std::vector<Sensor*> sensors =
-            g_sensor_snapshot->FindSensorsBySensorID(curr_sensor_id_);
-        const int N = static_cast<int>(sensors.size());
-        const int w = rect.w - 5;
-        mvwprintw(win, 3, 2, "There are %d sensors with the name %s", N,
-                  curr_sensor_id_.c_str());
-        int y = 5;
-        int x = 2;
-        if (N > 0)
-        {
-            for (int j = 0; j < N; j++)
-            {
-                Sensor* sensor = sensors[j];
-                mvwprintw(win, y, x, "%d/%d", j + 1, N);
-                char buf[200];
-                snprintf(buf, sizeof(buf), "DBus Service    : %s",
-                         sensor->ServiceName().c_str());
-                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
-                snprintf(buf, sizeof(buf), "DBus Connection : %s",
-                         sensor->ConnectionName().c_str());
-                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
-                snprintf(buf, sizeof(buf), "DBus Object Path: %s",
-                         sensor->ObjectPath().c_str());
-                y += DrawTextWithWidthLimit(win, buf, y, x, w, "/");
-                y++;
-            }
-        }
-        else
-        {
-            mvwaddstr(win, y, x, "Sensor details not found");
-        }
-    }
-    DrawBorderIfNeeded();
-    wrefresh(win);
-}
-
-std::string SensorDetailView::GetStatusString()
-{
-    if (state == SensorList)
-    {
-        return "[Arrow Keys]=Move Cursor [Q]=Deselect [Enter]=Show Sensor "
-               "Detail";
-    }
-    else
-    {
-        return "[Arrow Keys]=Cycle Through Sensors [Esc/Q]=Exit";
-    }
-}
-
-DBusStatListView::DBusStatListView() : DBusTopWindow()
-{
-    highlight_col_idx_ = 0;
-    sort_col_idx_ = 0;
-    sort_order_ = SortOrder::Ascending;
-    horizontal_pan_ = 0;
-    row_idx_ = INVALID;
-    disp_row_idx_ = 0;
-    horizontal_pan_ = 0;
-    menu1_ = new ArrowKeyNavigationMenu(this);
-    menu2_ = new ArrowKeyNavigationMenu(this);
-    // Load all available field names
-    std::set<std::string> inactive_fields;
-    std::set<std::string> active_fields;
-
-    // Default choice of field names
-    const int N = static_cast<int>(sizeof(FieldNames) / sizeof(FieldNames[0]));
-    for (int i = 0; i < N; i++)
-    {
-        inactive_fields.insert(FieldNames[i]);
-    }
-    for (const std::string& s :
-         dbus_top_analyzer::g_dbus_statistics.GetFieldNames())
-    {
-        inactive_fields.erase(s);
-        active_fields.insert(s);
-    }
-    for (int i = 0; i < N; i++)
-    {
-    const std::string s = FieldNames[i];
-        if (inactive_fields.count(s) > 0)
-        {
-            menu1_->AddItem(s);
-        }
-        else
-        {
-            menu2_->AddItem(s);
-        }
-    }
-    
-    curr_menu_state_ = LeftSide;
-    menu_h_ = 5;
-    menu_w_ = 24; // Need at least 2*padding + 15 for enough space, see menu.hpp
-    menu_margin_ = 6;
-    // Populate preferred column widths
-    for (int i = 0; i < N; i++)
-    {
-        column_widths_[FieldNames[i]] = FieldPreferredWidths[i];
-    }
-}
-
-std::pair<int, int> DBusStatListView::GetXSpanForColumn(const int col_idx)
-{
-    std::vector<int> cw = ColumnWidths();
-    if (col_idx < 0 || col_idx >= static_cast<int>(cw.size()))
-    {
-        return std::make_pair(INVALID, INVALID);
-    }
-    int x0 = 0, x1 = 0;
-    for (int i = 0; i < col_idx; i++)
-    {
-        if (i > 0)
-        {
-            x0 += cw[i];
-        }
-    }
-    x1 = x0 + cw[col_idx] - 1;
-    return std::make_pair(x0, x1);
-}
-
-// If tolerance > 0, consider overlap before 2 intervals intersect
-// If tolerance ==0, consider overlap if 2 intervals exactly intersect
-// If tolerance < 0, consider overlap if Minimal Translate Distance is >=
-// -threshold
-bool IsSpansOverlap(const std::pair<int, int>& s0,
-                    const std::pair<int, int>& s1, int tolerance)
-{
-    if (tolerance >= 0)
-    {
-        if (s0.second < s1.first - tolerance)
-            return false;
-        else if (s1.second < s0.first - tolerance)
-            return false;
-        else
-            return true;
-    }
-    else
-    {
-        // Compute overlapping distance
-        std::vector<std::pair<int, int>> tmp(
-            4); // [x, 1] means the start of interval
-                // [x,-1] means the end of interval
-        tmp[0] = std::make_pair(s0.first, 1);
-        tmp[1] = std::make_pair(s0.second, -1);
-        tmp[2] = std::make_pair(s1.first, 1);
-        tmp[3] = std::make_pair(s1.second, -1);
-        std::sort(tmp.begin(), tmp.end());
-        int overlap_x0 = -INVALID, overlap_x1 = -INVALID;
-        int idx = 0;
-        const int N = static_cast<int>(tmp.size());
-        int level = 0;
-        while (idx < N)
-        {
-            const int x = tmp[idx].first;
-            while (idx < N && x == tmp[idx].first)
-            {
-                level += tmp[idx].second;
-                idx++;
-            }
-            // The starting position of the overlap
-            if (level == 2)
-            {
-                overlap_x0 = idx - 1;
-            }
-            // The ending position of the overlap
-            if (overlap_x0 != -INVALID && level < 2 && overlap_x1 == -INVALID)
-            {
-                overlap_x1 = idx - 1;
-            }
-        }
-        const int overlap_length = overlap_x1 - overlap_x0 + 1;
-        if (overlap_length >= -tolerance)
-            return true;
-        else
-            return false;
-    }
-}
-
-bool DBusStatListView::IsXSpanVisible(const std::pair<int, int>& xs,
-                                      int tolerance)
-{
-    const std::pair<int, int> vxs = {horizontal_pan_, horizontal_pan_ + rect.w};
-    return IsSpansOverlap(xs, vxs, tolerance);
-}
-std::vector<std::string> DBusStatListView::ColumnHeaders()
-{
-    return visible_columns_;
-}
-
-std::vector<int> DBusStatListView::ColumnWidths()
-{
-    std::vector<int> widths = {8}; // for "Msg/s"
-    std::vector<std::string> agg_headers = visible_columns_;
-    std::vector<int> agg_widths(agg_headers.size(), 0);
-    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
-    {
-        agg_widths[i] = column_widths_[agg_headers[i]];
-    }
-    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
-    return widths;
-}
-
-// Coordinate systems are in world space, +x faces to the right
-// Viewport:            [horizontal_pan_,   horizontal_pan_ + rect.w]
-// Contents:  [  column_width[0]  ][  column_width[1] ][  column_width[2]  ]
-void DBusStatListView::PanViewportOrMoveHighlightedColumn(const int delta_x)
-{
-    // If the column to the left is visible, highlight it
-    const int N = static_cast<int>(ColumnHeaders().size());
-    bool col_idx_changed = false;
-    if (delta_x < 0)
-    { // Pan left
-        if (highlight_col_idx_ > 0)
-        {
-            std::pair<int, int> xs_left =
-                GetXSpanForColumn(highlight_col_idx_ - 1);
-            if (IsXSpanVisible(xs_left, -1))
-            {
-                highlight_col_idx_--;
-                col_idx_changed = true;
-            }
-        }
-        if (!col_idx_changed)
-        {
-            horizontal_pan_ += delta_x;
-        }
-    }
-    else if (delta_x > 0)
-    { // Pan right
-        if (highlight_col_idx_ < N - 1)
-        {
-            std::pair<int, int> xs_right =
-                GetXSpanForColumn(highlight_col_idx_ + 1);
-            if (IsXSpanVisible(xs_right, -1))
-            {
-                highlight_col_idx_++;
-                col_idx_changed = true;
-            }
-        }
-        if (!col_idx_changed)
-        {
-            horizontal_pan_ += delta_x;
-        }
-    }
-}
-
-void DBusStatListView::OnKeyDown(const std::string& key)
-{
-    {
-        switch (curr_menu_state_)
-        {
-            case LeftSide:
-            {
-                if (key == "up")
-                {
-                    menu1_->OnKeyDown("up");
-                }
-                else if (key == "down")
-                {
-                    menu1_->OnKeyDown("down");
-                }
-                else if (key == "right")
-                {
-                    SetMenuState(RightSide);
-                }
-                else if (key == "enter")
-                {
-                    SetMenuState(Hidden);
-                }
-                else if (key == "space")
-                {
-                    std::string ch;
-                    if (menu1_->RemoveHighlightedItem(&ch))
-                    {
-                        menu2_->AddItem(ch);
-                    }
-                }
-                break;
-            }
-            case RightSide:
-            {
-                if (key == "up")
-                {
-                    menu2_->OnKeyDown("up");
-                }
-                else if (key == "down")
-                {
-                    menu2_->OnKeyDown("down");
-                }
-                else if (key == "left")
-                {
-                    SetMenuState(LeftSide);
-                }
-                else if (key == "enter")
-                {
-                    SetMenuState(Hidden);
-                }
-                else if (key == "space")
-                {
-                    std::string ch;
-                    if (menu2_->RemoveHighlightedItem(&ch))
-                    {
-                        menu1_->AddItem(ch);
-                    }
-                }
-                break;
-            }
-            case Hidden:
-            {
-                if (key == "enter")
-                {
-                    switch (last_menu_state_)
-                    {
-                        case LeftSide:
-                        case RightSide:
-                            SetMenuState(last_menu_state_);
-                            break;
-                        default:
-                            SetMenuState(LeftSide);
-                    }
-                }
-                else if (key == "left")
-                {
-                    PanViewportOrMoveHighlightedColumn(-2);
-                }
-                else if (key == "right")
-                {
-                    PanViewportOrMoveHighlightedColumn(2);
-                }
-                else if (key == "up")
-                {
-                    disp_row_idx_--;
-                    if (disp_row_idx_ < 0)
-                    {
-                        disp_row_idx_ = 0;
-                    }
-                }
-                else if (key == "down")
-                {
-                    disp_row_idx_++;
-                    const int N = static_cast<int>(stats_snapshot_.size());
-                    if (disp_row_idx_ >= N)
-                    {
-                        disp_row_idx_ = N - 1;
-                    }
-                }
-                else if (key == "a")
-                {
-                    sort_order_ = SortOrder::Ascending;
-                    sort_col_idx_ = highlight_col_idx_;
-                    break;
-                }
-                else if (key == "d")
-                {
-                    sort_order_ = SortOrder::Descending;
-                    sort_col_idx_ = highlight_col_idx_;
-                    break;
-                }
-                break;
-            }
-        }
-    }
-    Render();
-}
-
-// Window C
-void DBusStatListView::Render()
-{
-    werase(win);
-    if (!visible_)
-        return;
-    int num_lines_shown = rect.h - 3;
-    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
-    {
-        menu1_->Render();
-        menu2_->Render();
-        num_lines_shown -= (menu_h_ + 3);
-        // Draw the arrow
-        const int x1 = menu1_->rect_.x;
-        const int h1 = menu1_->rect_.h;
-        const int x2 = menu2_->rect_.x;
-        const int w2 = menu2_->rect_.w;
-        const int y1 = menu1_->rect_.y;
-        const int arrow_x = (x1 + x2 + w2) / 2 - 2;
-        const int arrow_y = y1 + 2;
-        const int caption_x = x1;
-        const int caption_y = y1 + h1;
-        for (int x = 1; x < rect.w - 1; x++)
-        {
-            mvwaddch(win, y1 - 3, x, '-');
-        }
-        mvwaddstr(win, y1 - 3, arrow_x - 8, "Press [Enter] to show/hide");
-        mvwaddstr(win, y1 - 2, caption_x - 5,
-                  "DBus fields for aggregating and sorting results:");
-        if (curr_menu_state_ == LeftSide)
-        {
-            mvwaddstr(win, y1 - 1, x1 - 4, "--[ Available Fields ]--");
-            mvwaddstr(win, y1 - 1, x2 - 4, "--- Active Fields ---");
-        }
-        else
-        {
-            mvwaddstr(win, y1 - 1, x1 - 4, "--- Available Fields ---");
-            mvwaddstr(win, y1 - 1, x2 - 4, "--[ Active Fields ]--");
-        }
-        if (curr_menu_state_ == LeftSide)
-        {
-            mvwaddstr(win, arrow_y, arrow_x, "-->");
-            mvwaddstr(win, caption_y, caption_x,
-                      "Press [Space] to move to the right");
-        }
-        else
-        {
-            mvwaddstr(win, arrow_y, arrow_x, "<--");
-            mvwaddstr(win, caption_y, caption_x,
-                      "Press [Space] to move to the left");
-        }
-    }
-    std::vector<std::string> headers;
-    std::vector<int> widths;
-    visible_columns_ = g_dbus_statistics->GetFieldNames();
-    std::vector<std::string> agg_headers = visible_columns_;
-    std::vector<int> agg_widths(agg_headers.size(), 0);
-    for (int i = 0; i < static_cast<int>(agg_headers.size()); i++)
-    {
-        agg_widths[i] = column_widths_[agg_headers[i]];
-    }
-    headers.insert(headers.end(), agg_headers.begin(), agg_headers.end());
-    widths.insert(widths.end(), agg_widths.begin(), agg_widths.end());
-    std::vector<int> xs;
-    int curr_x = 2 - horizontal_pan_;
-    for (const int w : widths)
-    {
-        xs.push_back(curr_x);
-        curr_x += w;
-    }
-    const int N = headers.size();
-    // Bound col_idx_
-    if (highlight_col_idx_ >= N)
-    {
-        highlight_col_idx_ = N - 1;
-    }
-    // Render column headers
-    for (int i = 0; i < N; i++)
-    {
-        std::string s = headers[i];
-        // 1 char outside boundary = start printing from the second character,
-        // etc
-
-        // Print "<" for Ascending order (meaning: row 0 < row 1 < row 2 ... )
-        // Print ">" for Descending order (meaning: row 0 > row 1 > row 2 ... )
-        if (sort_col_idx_ == i)
-        {
-            if (sort_order_ == SortOrder::Ascending)
-            {
-                s.push_back('<');
-            }
-            else
-            {
-                s.push_back('>');
-            }
-        }
-
-        // Highlight the "currently-selected column"
-        if (highlight_col_idx_ == i)
-        {
-            wattrset(win, 0);
-            wattron(win, A_REVERSE);
-        }
-        else
-        {
-            wattrset(win, 0);
-            wattron(win, A_UNDERLINE);
-        }
-        int x = xs[i];
-        if (x < 0)
-        {
-            if (-x < static_cast<int>(s.size()))
-            {
-                s = s.substr(-x);
-            }
-            else
-                s = "";
-            x = 0;
-        }
-        mvwaddstr(win, 1, x, s.c_str());
-    }
-    wattrset(win, 0);
-    // Time since the last update of Window C
-    float interval_secs = g_dbus_statistics->seconds_since_last_sample_;
-    if (interval_secs == 0)
-    {
-        interval_secs = GetSummaryIntervalInMillises() / 1000.0f;
-    }
-
-    stats_snapshot_ = g_dbus_statistics->StatsSnapshot();
-    const int nrows = static_cast<int>(stats_snapshot_.size());
-    const std::vector<DBusTopSortField> fields = g_dbus_statistics->GetFields();
-    const int ncols = static_cast<int>(fields.size());
-    // Merge the list of DBus Message properties & computed metrics together
-    std::map<std::vector<std::string>, DBusTopComputedMetrics>::iterator itr =
-        stats_snapshot_.begin();
-    struct StringOrFloat
-    { // Cannot use union so using struct
-        std::string s;
-        float f;
-    };
-
-    // "Stage" the snapshot for displaying in the form of a spreadsheet
-    std::vector<std::pair<StringOrFloat, std::vector<std::string>>>
-        stats_snapshot_staged;
-    const DBusTopSortField sort_field = fields[sort_col_idx_];
-    const bool is_sort_key_numeric = DBusTopSortFieldIsNumeric(sort_field);
-
-    for (int i = 0; i < nrows; i++) // One row of cells
-    {
-        int idx0 = 0; // indexing into the std::vector<string> of each row
-        std::vector<std::string> row;
-
-        StringOrFloat sort_key; // The key used for sorting
-        for (int j = 0; j < ncols; j++) // one column in the row
-        {
-            DBusTopSortField field = fields[j];
-            // Populate the content of stats_snapshot_staged
-
-            StringOrFloat sof; // Represents this column
-            
-            // When we haven't used up all
-            if (idx0 < static_cast<int>(itr->first.size()))
-            {
-                sof.s = itr->first[idx0];
-            }
-            switch (field)
-            {
-                case kSender:      // string
-                case kDestination: // string
-                case kInterface:   // string
-                case kPath:        // string
-                case kMember:      // string
-                case kSenderPID:   // numeric
-                case kSenderCMD:   // string
-                    row.push_back(itr->first[idx0]);
-                    idx0++;
-                    if (field == kSenderPID)
-                    {
-                        // Note: attempting to std::atof("(unknown)") on the BMC
-                        // will cause hang. And GDB won't show backtrace.
-                        if (sof.s == "(unknown)")
-                        {
-                            if (sort_order_ == Ascending)
-                            {
-                                sof.f = -1;
-                            }
-                            else
-                            {
-                                sof.f = 1e20;
-                            }
-                        }
-                        else
-                        {
-                            sof.f = std::atof(sof.s.c_str());
-                        }
-                    }
-                    break;
-                case kMsgPerSec: // Compute "messages per second"
-                {
-                    int numbers[] = {
-                        itr->second.num_method_calls,
-                        itr->second.num_method_returns,
-                        itr->second.num_signals,
-                        itr->second.num_errors,
-                    };
-                    int the_sum = 0; // For sorting
-
-                    std::string s; // String representation in the form or
-                                   // "1.00/2.00/3.00/4.00"
-                    for (int i = 0; i < 4; i++)
-                    {
-                        the_sum += numbers[i];
-                        if (i > 0)
-                            s += "/";
-                        float per_sec = numbers[i] / interval_secs;
-                        s += FloatToString(per_sec);
-                    }
-
-                    row.push_back(s);
-                    sof.f = the_sum;
-                    break;
-                }
-                case kAverageLatency: // Compute "average Method Call latency"
-                    const DBusTopComputedMetrics& m = itr->second;
-                    if (m.num_method_calls == 0)
-                    {
-                        row.push_back("n/a");
-                        if (sort_order_ == Ascending)
-                        {
-                            sof.f = -1; // Put to the top
-                        }
-                        else
-                        {
-                            sof.f = 1e20; // Put to the top
-                        }
-                    }
-                    else
-                    {
-                        float avg_latency_usec =
-                            m.total_latency_usec / m.num_method_calls;
-                        row.push_back(FloatToString(avg_latency_usec));
-                        sof.f = avg_latency_usec;
-                    }
-                    break;
-            }
-            if (j == sort_col_idx_)
-            {
-                sort_key = sof;
-            }
-        }
-        stats_snapshot_staged.push_back(std::make_pair(sort_key, row));
-        itr++;
-    }
-    
-    // Sort the "staged snapshot" using the sort_key, using different functions
-    // depending on whether sort key is numeric or string
-    if (is_sort_key_numeric)
-    {
-        std::sort(
-            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
-            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
-               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
-                return a.first.f < b.first.f;
-            });
-    }
-    else
-    {
-        std::sort(
-            stats_snapshot_staged.begin(), stats_snapshot_staged.end(),
-            [](const std::pair<StringOrFloat, std::vector<std::string>>& a,
-               const std::pair<StringOrFloat, std::vector<std::string>>& b) {
-                return a.first.s < b.first.s;
-            });
-    }
-    
-    if (sort_order_ == Descending)
-    {
-        std::reverse(stats_snapshot_staged.begin(),
-                     stats_snapshot_staged.end());
-    }
-    // Minus 2 because of "msgs/s" and "+"
-    const int num_fields = N;
-    // The Y span of the area for rendering the "spreadsheet"
-    const int y0 = 2, y1 = y0 + num_lines_shown - 1;
-    // Key is sender, destination, interface, path, etc
-    for (int i = 0, shown = 0;
-        i + disp_row_idx_ < static_cast<int>(stats_snapshot_staged.size()) &&
-        shown < num_lines_shown;
-        i++, shown++)
-    {
-        std::string s;
-        int x = 0;
-        const std::vector<std::string> key =
-            stats_snapshot_staged[i + disp_row_idx_].second;
-        for (int j = 0; j < num_fields; j++)
-        {
-            x = xs[j];
-            s = key[j];
-            // Determine column width limit for this particular column
-            int col_width = 100;
-            if (j < num_fields - 1)
-            {
-                col_width = xs[j + 1] - xs[j] - 1;
-            }
-            s = Ellipsize(s, col_width);
-            if (x < 0)
-            {
-                if (-x < static_cast<int>(s.size()))
-                    s = s.substr(-x);
-                else
-                    s = "";
-                x = 0;
-            }
-            // Trim if string overflows to the right
-            if (x + static_cast<int>(s.size()) > rect.w)
-            {
-                s = s.substr(0, rect.w - x);
-            }
-            mvwaddstr(win, 2 + i, x, s.c_str());
-        }
-    }
-    // Overflows past the top ...
-    if (disp_row_idx_ > 0)
-    {
-        std::string x = " [+" + std::to_string(disp_row_idx_) + " rows above]";
-        mvwaddstr(win, y0, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
-    }
-    // Overflows past the bottom ...
-    const int last_disp_row_idx = disp_row_idx_ + num_lines_shown - 1;
-    if (last_disp_row_idx < nrows - 1)
-    {
-        std::string x = " [+" +
-                        std::to_string((nrows - 1) - last_disp_row_idx) +
-                        " rows below]";
-        mvwaddstr(win, y1, rect.w - static_cast<int>(x.size()) - 1, x.c_str());
-    }
-    DrawBorderIfNeeded();
-    wrefresh(win);
-}
-
-void DBusStatListView::OnResize(int win_w, int win_h)
-{
-    rect.y = 8 - MARGIN_BOTTOM;
-    rect.w = win_w - (win_w / 2) + 1; // Perfectly overlap on the vertical edge
-    rect.x = win_w - rect.w;
-    rect.h = win_h - rect.y - MARGIN_BOTTOM;
-    const int x0 = rect.w / 2 - menu_w_ - menu_margin_ / 2;
-    const int x1 = x0 + menu_margin_ + menu_w_;
-    const int menu_y = rect.h - menu_h_;
-    menu1_->SetRect(Rect(x0, menu_y, menu_w_, menu_h_)); // Local coordinates
-    menu1_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
-    menu2_->SetRect(Rect(x1, menu_y, menu_w_, menu_h_));
-    menu2_->SetOrder(ArrowKeyNavigationMenu::Order::ColumnMajor);
-    UpdateWindowSizeAndPosition();
-}
-
-std::vector<DBusTopSortField> DBusStatListView::GetSortFields()
-{
-    std::vector<DBusTopSortField> ret;
-    const int N = sizeof(FieldNames) / sizeof(FieldNames[0]);
-    for (const std::string& s : menu2_->Items())
-    {
-        for (int i = 0; i < N; i++)
-        {
-            if (FieldNames[i] == s)
-            {
-                ret.push_back(static_cast<DBusTopSortField>(i));
-                break;
-            }
-        }
-    }
-    return ret;
-}
-
-std::string DBusStatListView::GetStatusString()
-{
-    if (curr_menu_state_ == LeftSide || curr_menu_state_ == RightSide)
-    {
-        return "[Enter]=Hide Panel [Space]=Choose Entry [Arrow Keys]=Move "
-               "Cursor";
-    }
-    else
-    {
-        return "[Enter]=Show Column Select Panel [Arrow Keys]=Pan View";
-    }
-}
-
-void FooterView::Render()
-{
-    werase(win);
-    const time_t now = time(nullptr);
-    const char* date_time = ctime(&now);
-    wattrset(win, 0);
-    std::string help_info;
-    if (g_current_active_view == nullptr)
-    {
-        help_info = "Press [Tab] to cycle through views";
-    }
-    else
-    {
-        help_info = g_current_active_view->GetStatusString();
-    }
-    mvwaddstr(win, 0, 1, date_time);
-    mvwaddstr(win, 0, rect.w - int(help_info.size()) - 1, help_info.c_str());
-    wrefresh(win);
-}
diff --git a/dbus-top/views.hpp b/dbus-top/views.hpp
deleted file mode 100644
index d4f3779..0000000
--- a/dbus-top/views.hpp
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "analyzer.hpp"
-#include "bargraph.hpp"
-#include "main.hpp"
-#include "menu.hpp"
-#include "sensorhelper.hpp"
-
-#include <ncurses.h>
-#include <string>
-#include <vector>
-constexpr int MARGIN_BOTTOM = 1;
-class DBusTopWindow
-{
-  public:
-    DBusTopWindow()
-    {
-        win = newwin(25, 80, 0, 0); // Default to 80x25, will be updated
-        has_border_ = true;
-        focused_ = false;
-        selectable_ = true;
-        visible_ = true;
-        maximize_ = false;
-    }
-
-    virtual ~DBusTopWindow()
-    {}
-    virtual void OnKeyDown(const std::string& key) = 0;
-    virtual void Render() = 0;
-    virtual void OnResize(int win_w, int win_h) = 0;
-    void UpdateWindowSizeAndPosition()
-    {
-        mvwin(win, rect.y, rect.x);
-        wresize(win, rect.h, rect.w);
-    }
-
-    void DrawBorderIfNeeded()
-    {
-        if (focused_)
-        {
-            wborder(win, '*', '*', '*', '*', '*', '*', '*', '*');
-        }
-        else
-        {
-            wborder(win, '|', '|', '-', '-', '+', '+', '+', '+');
-        }
-        wrefresh(win);
-    }
-
-    virtual void RecreateWindow()
-    {
-        delwin(win);
-        win = newwin(25, 80, 0, 0);
-        UpdateWindowSizeAndPosition();
-    }
-
-    virtual std::string GetStatusString() = 0;
-    WINDOW* win;
-    Rect rect;
-    bool has_border_;
-    bool focused_;
-    bool selectable_;
-    bool maximize_;
-    bool visible_;
-};
-
-class SummaryView : public DBusTopWindow
-{
-  public:
-    SummaryView() : DBusTopWindow()
-    {}
-    void Render() override;
-    void OnResize(int win_w, int win_h) override
-    {
-        rect.h = 8;
-        rect.w = win_w;
-        rect.x = 0;
-        rect.y = 0;
-        UpdateWindowSizeAndPosition();
-    }
-
-    void UpdateDBusTopStatistics(DBusTopStatistics* stat);
-    void OnKeyDown(const std::string& key) override
-    {}
-    std::string GetStatusString() override
-    {
-        return "Summary View";
-    }
-
-  private:
-    float method_call_, method_return_, signal_, error_, total_;
-};
-
-class SensorDetailView : public DBusTopWindow
-{
-  public:
-    SensorDetailView() : DBusTopWindow()
-    {
-        choice_ = -999; // -999 means invalid
-        h_padding = 2;
-        h_spacing = 3;
-        col_width = 15;
-        idx0 = idx1 = -999;
-        state = SensorList;
-    }
-
-    void Render() override;
-    int DispSensorsPerColumn()
-    {
-        return rect.h - 3;
-    }
-
-    int DispSensorsPerRow()
-    {
-        int ncols = 0;
-        while (true)
-        {
-            int next = ncols + 1;
-            int w = 2 * h_padding + col_width * next;
-            if (next > 1)
-                w += (next - 1) * h_spacing;
-            if (w <= rect.w - 2)
-            {
-                ncols = next;
-            }
-            else
-            {
-                break;
-            }
-        }
-        return ncols;
-    }
-
-    void OnKeyDown(const std::string& key) override
-    {
-        if (state == SensorList)
-        { // Currently in sensor list
-            if (key == "right")
-            {
-                MoveChoiceCursorHorizontally(1);
-            }
-            else if (key == "left")
-            {
-                MoveChoiceCursorHorizontally(-1);
-            }
-            else if (key == "up")
-            {
-                MoveChoiceCursor(-1, true);
-            }
-            else if (key == "down")
-            {
-                MoveChoiceCursor(1, true);
-            }
-            else if (key == "enter")
-            {
-                if (choice_ != -999)
-                {
-                    state = SensorDetail;
-                }
-            }
-            else if (key == "escape")
-            {
-                choice_ = -999;
-            }
-        }
-        else if (state == SensorDetail)
-        { // Currently focusing on a sensor
-            if (key == "right" || key == "down")
-            {
-                MoveChoiceCursor(1, true);
-            }
-            else if (key == "left" || key == "up")
-            {
-                MoveChoiceCursor(-1, true);
-            }
-            else if (key == "escape")
-            {
-                state = SensorList;
-            }
-        }
-
-        Render(); // This window is already on top, redrawing won't corrupt
-    }
-
-    void MoveChoiceCursor(int delta, bool wrap_around = true)
-    {
-        const int ns = sensor_ids_.size();
-        if (ns < 1)
-            return;
-        // First of all, if cursor is inactive, activate it
-        if (choice_ == -999)
-        {
-            if (delta > 0)
-            {
-                choice_ = 0;
-                curr_sensor_id_ = sensor_ids_[0];
-                return;
-            }
-            else
-            {
-                choice_ = ns - 1;
-                curr_sensor_id_ = sensor_ids_.back();
-                return;
-            }
-        }
-        int choice_next = choice_ + delta;
-        while (choice_next >= ns)
-        {
-            if (wrap_around)
-            {
-                choice_next -= ns;
-            }
-            else
-            {
-                choice_next = ns - 1;
-            }
-        }
-        while (choice_next < 0)
-        {
-            if (wrap_around)
-            {
-                choice_next += ns;
-            }
-            else
-            {
-                choice_next = 0;
-            }
-        }
-        choice_ = choice_next;
-        curr_sensor_id_ = sensor_ids_[choice_];
-    }
-
-    void MoveChoiceCursorHorizontally(int delta)
-    {
-        if (delta != 0 && delta != -1 && delta != 1)
-            return;
-        const int ns = sensor_ids_.size();
-        if (ns < 1)
-            return;
-        if (choice_ == -999)
-        {
-            if (delta > 0)
-            {
-                choice_ = 0;
-                curr_sensor_id_ = sensor_ids_[0];
-                return;
-            }
-            else
-            {
-                curr_sensor_id_ = sensor_ids_.back();
-                choice_ = ns - 1;
-                return;
-            }
-        }
-        const int nrows = DispSensorsPerColumn();
-        int tot_columns = (ns - 1) / nrows + 1;
-        int num_rows_last_column = ns - nrows * (tot_columns - 1);
-        int y = choice_ % nrows, x = choice_ / nrows;
-        if (delta == 1)
-        {
-            x++;
-        }
-        else
-        {
-            x--;
-        }
-        bool overflow_to_right = false;
-        if (y < num_rows_last_column)
-        {
-            if (x >= tot_columns)
-            {
-                overflow_to_right = true;
-            }
-        }
-        else
-        {
-            if (x >= tot_columns - 1)
-            {
-                overflow_to_right = true;
-            }
-        }
-        bool overflow_to_left = false;
-        if (x < 0)
-        {
-            overflow_to_left = true;
-        }
-        {
-            if (overflow_to_right)
-            {
-                y++;
-                // overflow past the right of window
-                // Start probing next line
-                if (y >= nrows)
-                {
-                    choice_ = 0;
-                    return;
-                }
-                else
-                {
-                    choice_ = y;
-                    return;
-                }
-            }
-            else if (overflow_to_left)
-            { // overflow past the left of window
-                y--;
-                if (y < 0)
-                { // overflow past the top of window
-                    // Focus on the visually bottom-right entry
-                    if (num_rows_last_column == nrows)
-                    { // last col fully populated
-                        choice_ = ns - 1;
-                    }
-                    else
-                    { // last column is not fully populated
-                        choice_ = ns - num_rows_last_column - 1;
-                    }
-                    return;
-                }
-                else
-                {
-                    if (y < num_rows_last_column)
-                    {
-                        choice_ = nrows * (tot_columns - 1) + y;
-                    }
-                    else
-                    {
-                        choice_ = nrows * (tot_columns - 2) + y;
-                    }
-                }
-            }
-            else
-            {
-                choice_ = y + x * nrows;
-            }
-        }
-        curr_sensor_id_ = sensor_ids_[choice_];
-    }
-
-    // Cache the sensor list in the sensor snapshot
-    void UpdateSensorSnapshot(SensorSnapshot* snapshot)
-    {
-        std::string old_sensor_id = "";
-        if (choice_ != -999)
-        {
-            old_sensor_id = sensor_ids_[choice_];
-        }
-        std::vector<std::string> new_sensors =
-            snapshot->GetDistinctSensorNames();
-        if (new_sensors == sensor_ids_)
-        {
-            return; // Nothing is changed
-        }
-        // Assume changed
-        sensor_ids_ = new_sensors;
-        choice_ = -999;
-        for (int i = 0; i < static_cast<int>(new_sensors.size()); i++)
-        {
-            if (new_sensors[i] == old_sensor_id)
-            {
-                choice_ = i;
-                break;
-                curr_sensor_id_ = sensor_ids_[choice_];
-            }
-        }
-    }
-
-    void OnResize(int win_w, int win_h) override
-    {
-        rect.x = 0;
-        rect.y = 8 - MARGIN_BOTTOM;
-        rect.w = win_w / 2;
-        rect.h = win_h - rect.y - MARGIN_BOTTOM;
-        UpdateWindowSizeAndPosition();
-    }
-
-    std::vector<std::string> sensor_ids_;
-    // We need to keep track of the currently-selected sensor ID because
-    // the sensor ID might theoretically become invalidated at any moment, and
-    // we should allow the UI to show an error gracefully in that case.
-    std::string curr_sensor_id_;
-    int choice_;
-    int h_padding;
-    int h_spacing;
-    int col_width;
-    int idx0, idx1; // Range of sensors on display
-    enum State
-    {
-        SensorList,
-        SensorDetail,
-    };
-
-    State state;
-    std::string GetStatusString() override;
-};
-
-class DBusStatListView : public DBusTopWindow
-{
-  public:
-    DBusStatListView();
-    void Render() override;
-    void OnResize(int win_w, int win_h) override;
-    void OnKeyDown(const std::string& key) override;
-    int horizontal_pan_;
-    int menu_h_, menu_w_, menu_margin_;
-    ArrowKeyNavigationMenu* menu1_;
-    ArrowKeyNavigationMenu* menu2_;
-    int highlight_col_idx_; // Currently highlighted column
-    int row_idx_;           // Currently highlighted row
-
-    int sort_col_idx_; // Column used for sorting
-    enum SortOrder
-    {
-        Ascending,
-        Descending,
-    };
-    SortOrder sort_order_;
-
-    int disp_row_idx_; // From which row to start displaying? (essentially a
-                       // vertical scroll bar)
-    int last_choices_[2]; // Last choice index on either side
-    enum MenuState
-    {
-        Hidden,
-        LeftSide,  // When the user is choosing an entry on the left side
-        RightSide, // When the user is choosing an entry on the right side
-    };
-
-    std::vector<DBusTopSortField> GetSortFields();
-    MenuState curr_menu_state_, last_menu_state_;
-    std::string GetStatusString() override;
-    void RecreateWindow()
-    {
-        delwin(win);
-        win = newwin(25, 80, 0, 0);
-        menu1_->win_ = win;
-        menu2_->win_ = win;
-        UpdateWindowSizeAndPosition();
-    }
-    
-  private:
-    void SetMenuState(MenuState s)
-    {
-        last_menu_state_ = curr_menu_state_;
-        // Moving out from a certain side: save the last choice of that side
-        switch (curr_menu_state_)
-        {
-            case LeftSide:
-                if (s == RightSide)
-                {
-                    last_choices_[0] = menu1_->Choice();
-                    menu1_->Deselect();
-                }
-                break;
-            case RightSide:
-                if (s == LeftSide)
-                {
-                    last_choices_[1] = menu2_->Choice();
-                    menu2_->Deselect();
-                }
-                break;
-            default:
-                break;
-        }
-        // Moving into a certain side: save the cursor
-        switch (s)
-        {
-            case LeftSide:
-                if (!menu1_->Empty())
-                {
-                    menu1_->SetChoiceAndConstrain(last_choices_[0]);
-                }
-                break;
-            case RightSide:
-                if (!menu2_->Empty())
-                {
-                    menu2_->SetChoiceAndConstrain(last_choices_[1]);
-                }
-                break;
-            default:
-                break;
-        }
-        curr_menu_state_ = s;
-    }
-    void PanViewportOrMoveHighlightedColumn(const int delta_x);
-    // ColumnHeaders and ColumnWidths are the actual column widths used for
-    // display. They are "msg/s" or "I2c/s" prepended to the chosen set of
-    // fields.
-    std::vector<std::string> ColumnHeaders();
-    std::vector<int> ColumnWidths();
-    // X span, for checking visibility
-    std::pair<int, int> GetXSpanForColumn(const int col_idx);
-    bool IsXSpanVisible(const std::pair<int, int>& xs,
-                        const int tolerance); // uses horizontal_pan_
-    std::vector<std::string> visible_columns_;
-    std::unordered_map<std::string, int> column_widths_;
-    std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_snapshot_;
-};
-
-class FooterView : public DBusTopWindow
-{
-  public:
-    FooterView() : DBusTopWindow()
-    {
-        selectable_ = false; // Cannot be selected by the tab key
-    }
-
-    void OnKeyDown(const std::string& key) override
-    {}
-    void OnResize(int win_w, int win_h) override
-    {
-        rect.h = 1;
-        rect.w = win_w;
-        rect.x = 0;
-        rect.y = win_h - 1;
-        UpdateWindowSizeAndPosition();
-    }
-
-    void Render() override;
-    std::string GetStatusString() override
-    {
-        return "";
-    }
-
-};
diff --git a/dbus-top/xmlparse.cpp b/dbus-top/xmlparse.cpp
deleted file mode 100644
index 2e4b1a3..0000000
--- a/dbus-top/xmlparse.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 "xmlparse.hpp"
-#include "main.hpp"
-
-int Munch(const std::string& sv, int* idx, std::string* out)
-{
-    if (*idx >= static_cast<int>(sv.size()))
-        return -INVALID;
-    while (::isspace(sv[*idx]))
-    {
-        (*idx)++;
-    }
-    int ret = 0;
-    *out = "";
-    int quote_state = 0; // 0: not seen, 1: seen opening quotation, 2: ended
-    while (*idx < static_cast<int>(sv.size()))
-    {
-        const char ch = sv[*idx];
-        if (::isspace(ch) && quote_state != 1)
-        {
-            break;
-        }
-        (*idx)++;
-        if (ch == '<')
-        {
-            if (*idx < static_cast<int>(sv.size()) && sv[*idx] == '!')
-            {
-                ret = 10; // Comment
-            }
-            else if (*idx < static_cast<int>(sv.size()) && sv[*idx] == '/')
-            {
-                ret = 22; // Closing tag
-                (*idx)++; // Skip the '/'
-            }
-            else
-            {
-                ret = 1; // <
-            }
-        }
-        else if (ch == '>')
-        {
-            if (ret == 1)
-            {
-                ret = 12;
-            } // < >
-            else if (ret == 22)
-            {}
-            else
-                ret = 2; //   >
-            if (out->size() == 0)
-            {
-                (*idx)++;
-            }
-            break; // Do not consume
-        }
-        else if (ch == '\"')
-        {
-            ret = 3; //
-            switch (quote_state)
-            {
-                case 0:
-                {
-                    quote_state = 1;
-                    continue;
-                }
-                case 1:
-                {
-                    quote_state = 2;
-                    break;
-                }
-            }
-        }
-        else if (ch == '/' && *idx < static_cast<int>(sv.size()) &&
-                 sv[*idx] == '>')
-        {
-            ret = 22; // Closing tag
-            (*idx)++;
-            break;
-        }
-        else
-        {
-            out->push_back(ch);
-        }
-    }
-    return ret;
-}
-
-XMLNode* ParseXML(const std::string& sv)
-{
-    int verbose = 0;
-    char* v = getenv("VERBOSE");
-    if (v)
-    {
-        verbose = std::atoi(v);
-    }
-    int idx = 0;
-    std::string out;
-    int res;
-    std::vector<std::string> tags;
-    std::vector<XMLNode*> nodestack;
-    XMLNode* root = nullptr;
-    if (verbose > 0)
-    {
-        printf("%s\n", sv.c_str());
-    }
-    while ((res = Munch(sv, &idx, &out)) != -INVALID)
-    {
-        if (res == 1 || res == 12)
-        {
-            XMLNode* newnode = new XMLNode(out);
-            if (tags.empty())
-            {
-                root = newnode;
-            }
-            else
-            {
-                nodestack.back()->AddChild(newnode);
-            }
-            tags.push_back(out);
-            nodestack.push_back(newnode);
-        }
-
-        // Add name (has to be before pop_back)
-        if (out.find("name=") == 0)
-        {
-            nodestack.back()->SetName(out.substr(5));
-        }
-
-        if (res == 22 && tags.size() > 0)
-        {
-            tags.pop_back();
-            nodestack.pop_back();
-        }
-        if (verbose >= 2)
-        {
-            printf("Munch %d %s, tags:", res, out.c_str());
-            for (const std::string& x : tags)
-            {
-                printf(" %s", x.c_str());
-            }
-            printf("\n");
-        }
-    }
-    return root;
-}
-
-void DeleteTree(XMLNode* x)
-{
-    for (XMLNode* ch : x->children)
-    {
-        DeleteTree(ch);
-    }
-    delete x;
-}
-
-std::vector<std::string> XMLNode::GetChildNodeNames()
-{
-    std::vector<std::string> ret;
-    for (XMLNode* n : children)
-    {
-        if (n->tag == "node")
-        {
-            ret.push_back(n->fields["name"]);
-        }
-    }
-    return ret;
-}
-
-std::vector<std::string> XMLNode::GetInterfaceNames()
-{
-    std::vector<std::string> ret;
-    for (XMLNode* n : children)
-    {
-        if (n->tag == "interface")
-        {
-            ret.push_back(n->fields["name"]);
-        }
-    }
-    return ret;
-}
\ No newline at end of file
diff --git a/dbus-top/xmlparse.hpp b/dbus-top/xmlparse.hpp
deleted file mode 100644
index 3a76e9a..0000000
--- a/dbus-top/xmlparse.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 <map>
-#include <string>
-#include <vector>
-
-class XMLNode
-{
-  public:
-    std::string tag;
-    std::map<std::string, std::string> fields;
-    std::vector<XMLNode*> children;
-    std::vector<XMLNode*> interfaces;
-    XMLNode(const std::string& t) : tag(t)
-    {}
-
-    void AddChild(XMLNode* x)
-    {
-        children.push_back(x);
-    }
-
-    void do_Print(int indent)
-    {
-        for (int i = 0; i < indent; i++)
-            printf("  ");
-        printf("%s", tag.c_str());
-        if (fields["name"] != "")
-        {
-            printf(" name=[%s]", fields["name"].c_str());
-        }
-        printf("\n");
-        for (XMLNode* ch : children)
-        {
-            ch->do_Print(indent + 1);
-        }
-    }
-
-    void Print()
-    {
-        do_Print(0);
-    }
-
-    void SetName(const std::string& n)
-    {
-        fields["name"] = n;
-    }
-    
-    std::vector<std::string> GetChildNodeNames();
-    std::vector<std::string> GetInterfaceNames();
-};
-
-XMLNode* ParseXML(const std::string& sv);
-void DeleteTree(XMLNode* x);