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

Commit 18b07a42 authored by Alex Buynytskyy's avatar Alex Buynytskyy
Browse files

Dumpsys support for IncrementalService.

Test: atest PackageManagerShellCommandTest
Test: adb shell dumpsys incremental
Bug: b/136132412 b/133435829
Change-Id: I8a91eddb850c68da87f56a82ca14fdf9ac5d3ce5
parent dea8db3d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -32,7 +32,10 @@ import android.os.ShellCallback;
import android.os.incremental.IIncrementalManager;
import android.util.Slog;

import com.android.internal.util.DumpUtils;

import java.io.FileDescriptor;
import java.io.PrintWriter;

/**
 * This service has the following purposes:
@@ -71,6 +74,13 @@ public class IncrementalManagerService extends IIncrementalManager.Stub {
        mNativeInstance = nativeStartService();
    }

    @SuppressWarnings("resource")
    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
        nativeDump(mNativeInstance, fd.getInt$());
    }

    /**
     * Notifies native IIncrementalManager service that system is ready.
     */
@@ -158,4 +168,6 @@ public class IncrementalManagerService extends IIncrementalManager.Stub {
    private static native long nativeStartService();

    private static native void nativeSystemReady(long nativeInstance);

    private static native void nativeDump(long nativeInstance, int fd);
}
+5 −0
Original line number Diff line number Diff line
@@ -33,9 +33,14 @@ static void nativeSystemReady(JNIEnv* env, jclass klass, jlong self) {
    Incremental_IncrementalService_OnSystemReady(self);
}

static void nativeDump(JNIEnv* env, jclass klass, jlong self, jint fd) {
    Incremental_IncrementalService_OnDump(self, fd);
}

static const JNINativeMethod method_table[] = {
        {"nativeStartService", "()J", (void*)nativeStartService},
        {"nativeSystemReady", "(J)V", (void*)nativeSystemReady},
        {"nativeDump", "(JI)V", (void*)nativeDump},
};

int register_android_server_incremental_IncrementalManagerService(JNIEnv* env) {
+16 −2
Original line number Diff line number Diff line
@@ -17,12 +17,14 @@
#include "BinderIncrementalService.h"

#include <binder/IResultReceiver.h>
#include <binder/PermissionCache.h>
#include <incfs.h>

#include "ServiceWrappers.h"
#include "jni.h"
#include "nativehelper/JNIHelp.h"
#include "path.h"
#include <android-base/logging.h>

using namespace std::literals;
using namespace android::incremental;
@@ -90,8 +92,13 @@ BinderIncrementalService* BinderIncrementalService::start() {
    return self.get();
}

status_t BinderIncrementalService::dump(int fd, const Vector<String16>& args) {
    return OK;
status_t BinderIncrementalService::dump(int fd, const Vector<String16>&) {
    static const String16 kDump("android.permission.DUMP");
    if (!PermissionCache::checkCallingPermission(kDump)) {
        return PERMISSION_DENIED;
    }
    mImpl.onDump(fd);
    return NO_ERROR;
}

void BinderIncrementalService::onSystemReady() {
@@ -280,3 +287,10 @@ void Incremental_IncrementalService_OnSystemReady(jlong self) {
        ((android::os::incremental::BinderIncrementalService*)self)->onSystemReady();
    }
}
void Incremental_IncrementalService_OnDump(jlong self, jint fd) {
    if (self) {
        ((android::os::incremental::BinderIncrementalService*)self)->dump(fd, {});
    } else {
        dprintf(fd, "BinderIncrementalService is stopped.");
    }
}
+63 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <uuid/uuid.h>
#include <zlib.h>

#include <ctime>
#include <iterator>
#include <span>
#include <stack>
@@ -256,6 +257,68 @@ FileId IncrementalService::idFromMetadata(std::span<const uint8_t> metadata) {

IncrementalService::~IncrementalService() = default;

inline const char* toString(TimePoint t) {
    using SystemClock = std::chrono::system_clock;
    time_t time = SystemClock::to_time_t(SystemClock::now() + std::chrono::duration_cast<SystemClock::duration>(t - Clock::now()));
    return std::ctime(&time);
}

inline const char* toString(IncrementalService::BindKind kind) {
    switch (kind) {
    case IncrementalService::BindKind::Temporary:
        return "Temporary";
    case IncrementalService::BindKind::Permanent:
        return "Permanent";
    }
}

void IncrementalService::onDump(int fd) {
    dprintf(fd, "Incremental is %s\n", incfs::enabled() ? "ENABLED" : "DISABLED");
    dprintf(fd, "Incremental dir: %s\n", mIncrementalDir.c_str());

    std::unique_lock l(mLock);

    dprintf(fd, "Mounts (%d):\n", int(mMounts.size()));
    for (auto&& [id, ifs] : mMounts) {
        const IncFsMount& mnt = *ifs.get();
        dprintf(fd, "\t[%d]:\n", id);
        dprintf(fd, "\t\tmountId: %d\n", mnt.mountId);
        dprintf(fd, "\t\tnextStorageDirNo: %d\n", mnt.nextStorageDirNo.load());
        dprintf(fd, "\t\tdataLoaderStatus: %d\n", mnt.dataLoaderStatus.load());
        dprintf(fd, "\t\tconnectionLostTime: %s\n", toString(mnt.connectionLostTime));
        if (mnt.savedDataLoaderParams) {
            const auto& params = mnt.savedDataLoaderParams.value();
            dprintf(fd, "\t\tsavedDataLoaderParams:\n");
            dprintf(fd, "\t\t\ttype: %s\n", toString(params.type).c_str());
            dprintf(fd, "\t\t\tpackageName: %s\n", params.packageName.c_str());
            dprintf(fd, "\t\t\tclassName: %s\n", params.className.c_str());
            dprintf(fd, "\t\t\targuments: %s\n", params.arguments.c_str());
            dprintf(fd, "\t\t\tdynamicArgs: %d\n", int(params.dynamicArgs.size()));
        }
        dprintf(fd, "\t\tstorages (%d):\n", int(mnt.storages.size()));
        for (auto&& [storageId, storage] : mnt.storages) {
            dprintf(fd, "\t\t\t[%d] -> [%s]\n", storageId, storage.name.c_str());
        }

        dprintf(fd, "\t\tbindPoints (%d):\n", int(mnt.bindPoints.size()));
        for (auto&& [target, bind] : mnt.bindPoints) {
            dprintf(fd, "\t\t\t[%s]->[%d]:\n", target.c_str(), bind.storage);
            dprintf(fd, "\t\t\t\tsavedFilename: %s\n", bind.savedFilename.c_str());
            dprintf(fd, "\t\t\t\tsourceDir: %s\n", bind.sourceDir.c_str());
            dprintf(fd, "\t\t\t\tkind: %s\n", toString(bind.kind));
        }
    }

    dprintf(fd, "Sorted binds (%d):\n", int(mBindsByPath.size()));
    for (auto&& [target, mountPairIt] : mBindsByPath) {
        const auto& bind = mountPairIt->second;
        dprintf(fd, "\t\t[%s]->[%d]:\n", target.c_str(), bind.storage);
        dprintf(fd, "\t\t\tsavedFilename: %s\n", bind.savedFilename.c_str());
        dprintf(fd, "\t\t\tsourceDir: %s\n", bind.sourceDir.c_str());
        dprintf(fd, "\t\t\tkind: %s\n", toString(bind.kind));
    }
}

std::optional<std::future<void>> IncrementalService::onSystemReady() {
    std::promise<void> threadFinished;
    if (mSystemReady.exchange(true)) {
+2 −0
Original line number Diff line number Diff line
@@ -90,6 +90,8 @@ public:
        return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
    }

    void onDump(int fd);

    std::optional<std::future<void>> onSystemReady();

    StorageId createStorage(std::string_view mountPoint,
Loading