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

Commit 86321400 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

[incfs] Fix a crash in worker thread calling JNI

Worker thread has to initialize JNI separately to be able
to call into managed binders implemented in the same
system_server process, e.g. DataLoaderManager

Bug: 153513507
Test: adb install megacity.nov4.apk; adb install megacity.v4.apk
Change-Id: I668e8664361cd2fb3353ec50efd689c7d613658f
parent da208016
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -135,7 +135,7 @@ static void android_server_SystemServer_spawnFdLeakCheckThread(JNIEnv*, jobject)


static jlong android_server_SystemServer_startIncrementalService(JNIEnv* env, jclass klass,
static jlong android_server_SystemServer_startIncrementalService(JNIEnv* env, jclass klass,
                                                                 jobject self) {
                                                                 jobject self) {
    return Incremental_IncrementalService_Start();
    return Incremental_IncrementalService_Start(env);
}
}


static void android_server_SystemServer_setIncrementalServiceSystemReady(JNIEnv* env, jclass klass,
static void android_server_SystemServer_setIncrementalServiceSystemReady(JNIEnv* env, jclass klass,
+2 −0
Original line number Original line Diff line number Diff line
@@ -410,6 +410,8 @@ private:


    // Installation.
    // Installation.
    bool onPrepareImage(dataloader::DataLoaderInstallationFiles addedFiles) final {
    bool onPrepareImage(dataloader::DataLoaderInstallationFiles addedFiles) final {
        ALOGE("onPrepareImage: start.");

        JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
        JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
        const auto& jni = jniIds(env);
        const auto& jni = jniIds(env);


+6 −6
Original line number Original line Diff line number Diff line
@@ -58,10 +58,10 @@ static bool incFsValid(const sp<IVold>& vold) {
    return true;
    return true;
}
}


BinderIncrementalService::BinderIncrementalService(const sp<IServiceManager>& sm)
BinderIncrementalService::BinderIncrementalService(const sp<IServiceManager>& sm, JNIEnv* env)
      : mImpl(RealServiceManager(sm), getIncrementalDir()) {}
      : mImpl(RealServiceManager(sm, env), getIncrementalDir()) {}


BinderIncrementalService* BinderIncrementalService::start() {
BinderIncrementalService* BinderIncrementalService::start(JNIEnv* env) {
    if (!incFsEnabled()) {
    if (!incFsEnabled()) {
        return nullptr;
        return nullptr;
    }
    }
@@ -81,7 +81,7 @@ BinderIncrementalService* BinderIncrementalService::start() {
        return nullptr;
        return nullptr;
    }
    }


    sp<BinderIncrementalService> self(new BinderIncrementalService(sm));
    sp<BinderIncrementalService> self(new BinderIncrementalService(sm, env));
    status_t ret = sm->addService(String16{getServiceName()}, self);
    status_t ret = sm->addService(String16{getServiceName()}, self);
    if (ret != android::OK) {
    if (ret != android::OK) {
        return nullptr;
        return nullptr;
@@ -290,8 +290,8 @@ binder::Status BinderIncrementalService::waitForNativeBinariesExtraction(int sto


} // namespace android::os::incremental
} // namespace android::os::incremental


jlong Incremental_IncrementalService_Start() {
jlong Incremental_IncrementalService_Start(JNIEnv* env) {
    return (jlong)android::os::incremental::BinderIncrementalService::start();
    return (jlong)android::os::incremental::BinderIncrementalService::start(env);
}
}
void Incremental_IncrementalService_OnSystemReady(jlong self) {
void Incremental_IncrementalService_OnSystemReady(jlong self) {
    if (self) {
    if (self) {
+3 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@


#include <binder/BinderService.h>
#include <binder/BinderService.h>
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <jni.h>


#include "IncrementalService.h"
#include "IncrementalService.h"
#include "android/os/incremental/BnIncrementalService.h"
#include "android/os/incremental/BnIncrementalService.h"
@@ -28,9 +29,9 @@ namespace android::os::incremental {
class BinderIncrementalService : public BnIncrementalService,
class BinderIncrementalService : public BnIncrementalService,
                                 public BinderService<BinderIncrementalService> {
                                 public BinderService<BinderIncrementalService> {
public:
public:
    BinderIncrementalService(const sp<IServiceManager>& sm);
    BinderIncrementalService(const sp<IServiceManager>& sm, JNIEnv* env);


    static BinderIncrementalService* start();
    static BinderIncrementalService* start(JNIEnv* env);
    static const char16_t* getServiceName() { return u"incremental"; }
    static const char16_t* getServiceName() { return u"incremental"; }
    status_t dump(int fd, const Vector<String16>& args) final;
    status_t dump(int fd, const Vector<String16>& args) final;


+14 −4
Original line number Original line Diff line number Diff line
@@ -237,6 +237,7 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v
        mDataLoaderManager(sm.getDataLoaderManager()),
        mDataLoaderManager(sm.getDataLoaderManager()),
        mIncFs(sm.getIncFs()),
        mIncFs(sm.getIncFs()),
        mAppOpsManager(sm.getAppOpsManager()),
        mAppOpsManager(sm.getAppOpsManager()),
        mJni(sm.getJni()),
        mIncrementalDir(rootDir) {
        mIncrementalDir(rootDir) {
    if (!mVold) {
    if (!mVold) {
        LOG(FATAL) << "Vold service is unavailable";
        LOG(FATAL) << "Vold service is unavailable";
@@ -249,7 +250,10 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v
    }
    }


    mJobQueue.reserve(16);
    mJobQueue.reserve(16);
    mJobProcessor = std::thread([this]() { runJobProcessing(); });
    mJobProcessor = std::thread([this]() {
        mJni->initializeForCurrentThread();
        runJobProcessing();
    });


    mountExistingImages();
    mountExistingImages();
}
}
@@ -1248,9 +1252,10 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
            continue;
            continue;
        }
        }


        jobQueue.emplace_back([this, zipFile, entry, ifs, libFileId,
        jobQueue.emplace_back([this, zipFile, entry, ifs = std::weak_ptr<IncFsMount>(ifs),
                               libPath = std::move(targetLibPath), makeFileTs]() mutable {
                               libFileId, libPath = std::move(targetLibPath),
            extractZipFile(ifs, zipFile.get(), entry, libFileId, libPath, makeFileTs);
                               makeFileTs]() mutable {
            extractZipFile(ifs.lock(), zipFile.get(), entry, libFileId, libPath, makeFileTs);
        });
        });


        if (sEnablePerfLogging) {
        if (sEnablePerfLogging) {
@@ -1296,6 +1301,11 @@ void IncrementalService::extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle
                                        ZipEntry& entry, const incfs::FileId& libFileId,
                                        ZipEntry& entry, const incfs::FileId& libFileId,
                                        std::string_view targetLibPath,
                                        std::string_view targetLibPath,
                                        Clock::time_point scheduledTs) {
                                        Clock::time_point scheduledTs) {
    if (!ifs) {
        LOG(INFO) << "Skipping zip file " << targetLibPath << " extraction for an expired mount";
        return;
    }

    auto libName = path::basename(targetLibPath);
    auto libName = path::basename(targetLibPath);
    auto startedTs = Clock::now();
    auto startedTs = Clock::now();


Loading