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

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

servicedispatcher: exit when adb debugging is turned off.

Test: manual by doing the following:

1. cd /data/local/tmp
   nohup servicedispatcher &
   bg
   # Now disconnects cable and reconnect, confirm that servicedispatcher
   #  still exists
   # Turn USB debugging off, confirm that servicedispatcher does not
   # exist. Though, servicedispatcher does not leave any logs, indicating
   # that it may be killed by other processes, e.g. adbd, because it is
   # spawned from shell.

2. Add an rc file that starts servicedispatcher on property trigger.
After setting the property, confirm that it is started.
Now disconnects cable and reconnect, confirm that servicedispatcher
still exists.
Turn USB debugging off, confirm that servicedispatcher does not
exist. Logcat suggests that servicedispatcher receives callback from
AdbService and exit()s.

Note: this change does NOT prevent servicedispatcher from starting up
when USB debugging is already turned off. This is because AdbService
cannot provide the state about USB debugging.

Fixes: 190867939
Change-Id: I887e51f814a24d05f26cc8d756f30e150c43b423
parent 506048be
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -357,5 +357,6 @@ cc_binary {
        "libbinder",
        "liblog",
        "libutils",
        "android.debug_aidl-cpp",
    ],
}
+27 −0
Original line number Diff line number Diff line
@@ -23,9 +23,12 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android/debug/BnAdbCallback.h>
#include <android/debug/IAdbManager.h>
#include <android/os/BnServiceManager.h>
#include <android/os/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/RpcServer.h>

using android::BBinder;
@@ -48,6 +51,7 @@ using std::string_view_literals::operator""sv;
namespace {

using ServiceRetriever = decltype(&android::IServiceManager::checkService);
using android::debug::IAdbManager;

int Usage(const char* program) {
    auto basename = Basename(program);
@@ -211,6 +215,25 @@ int wrapServiceManager(const ServiceRetriever& serviceRetriever) {
    __builtin_unreachable();
}

class AdbCallback : public android::debug::BnAdbCallback {
public:
    android::binder::Status onDebuggingChanged(bool enabled,
                                               android::debug::AdbTransportType) override {
        if (!enabled) {
            LOG(ERROR) << "ADB debugging disabled, exiting.";
            exit(EX_SOFTWARE);
        }
        return android::binder::Status::ok();
    }
};

void exitOnAdbDebuggingDisabled() {
    auto adb = android::waitForService<IAdbManager>(String16("adb"));
    CHECK(adb != nullptr) << "Unable to retrieve service adb";
    auto status = adb->registerCallback(sp<AdbCallback>::make());
    CHECK(status.isOk()) << "Unable to call IAdbManager::registerCallback: " << status;
}

// Log to logd. For warning and more severe messages, also log to stderr.
class ServiceDispatcherLogger {
public:
@@ -251,6 +274,10 @@ int main(int argc, char* argv[]) {
        }
    }

    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
    android::ProcessState::self()->startThreadPool();
    exitOnAdbDebuggingDisabled();

    if (optind + 1 != argc) return Usage(argv[0]);
    auto name = argv[optind];