[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
This commit is contained in:
@@ -135,7 +135,7 @@ static void android_server_SystemServer_spawnFdLeakCheckThread(JNIEnv*, jobject)
|
||||
|
||||
static jlong android_server_SystemServer_startIncrementalService(JNIEnv* env, jclass klass,
|
||||
jobject self) {
|
||||
return Incremental_IncrementalService_Start();
|
||||
return Incremental_IncrementalService_Start(env);
|
||||
}
|
||||
|
||||
static void android_server_SystemServer_setIncrementalServiceSystemReady(JNIEnv* env, jclass klass,
|
||||
|
||||
@@ -410,6 +410,8 @@ private:
|
||||
|
||||
// Installation.
|
||||
bool onPrepareImage(dataloader::DataLoaderInstallationFiles addedFiles) final {
|
||||
ALOGE("onPrepareImage: start.");
|
||||
|
||||
JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
|
||||
const auto& jni = jniIds(env);
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@ static bool incFsValid(const sp<IVold>& vold) {
|
||||
return true;
|
||||
}
|
||||
|
||||
BinderIncrementalService::BinderIncrementalService(const sp<IServiceManager>& sm)
|
||||
: mImpl(RealServiceManager(sm), getIncrementalDir()) {}
|
||||
BinderIncrementalService::BinderIncrementalService(const sp<IServiceManager>& sm, JNIEnv* env)
|
||||
: mImpl(RealServiceManager(sm, env), getIncrementalDir()) {}
|
||||
|
||||
BinderIncrementalService* BinderIncrementalService::start() {
|
||||
BinderIncrementalService* BinderIncrementalService::start(JNIEnv* env) {
|
||||
if (!incFsEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -81,7 +81,7 @@ BinderIncrementalService* BinderIncrementalService::start() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sp<BinderIncrementalService> self(new BinderIncrementalService(sm));
|
||||
sp<BinderIncrementalService> self(new BinderIncrementalService(sm, env));
|
||||
status_t ret = sm->addService(String16{getServiceName()}, self);
|
||||
if (ret != android::OK) {
|
||||
return nullptr;
|
||||
@@ -290,8 +290,8 @@ binder::Status BinderIncrementalService::waitForNativeBinariesExtraction(int sto
|
||||
|
||||
} // namespace android::os::incremental
|
||||
|
||||
jlong Incremental_IncrementalService_Start() {
|
||||
return (jlong)android::os::incremental::BinderIncrementalService::start();
|
||||
jlong Incremental_IncrementalService_Start(JNIEnv* env) {
|
||||
return (jlong)android::os::incremental::BinderIncrementalService::start(env);
|
||||
}
|
||||
void Incremental_IncrementalService_OnSystemReady(jlong self) {
|
||||
if (self) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <binder/BinderService.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "IncrementalService.h"
|
||||
#include "android/os/incremental/BnIncrementalService.h"
|
||||
@@ -28,9 +29,9 @@ namespace android::os::incremental {
|
||||
class BinderIncrementalService : public BnIncrementalService,
|
||||
public BinderService<BinderIncrementalService> {
|
||||
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"; }
|
||||
status_t dump(int fd, const Vector<String16>& args) final;
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v
|
||||
mDataLoaderManager(sm.getDataLoaderManager()),
|
||||
mIncFs(sm.getIncFs()),
|
||||
mAppOpsManager(sm.getAppOpsManager()),
|
||||
mJni(sm.getJni()),
|
||||
mIncrementalDir(rootDir) {
|
||||
if (!mVold) {
|
||||
LOG(FATAL) << "Vold service is unavailable";
|
||||
@@ -249,7 +250,10 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v
|
||||
}
|
||||
|
||||
mJobQueue.reserve(16);
|
||||
mJobProcessor = std::thread([this]() { runJobProcessing(); });
|
||||
mJobProcessor = std::thread([this]() {
|
||||
mJni->initializeForCurrentThread();
|
||||
runJobProcessing();
|
||||
});
|
||||
|
||||
mountExistingImages();
|
||||
}
|
||||
@@ -1248,9 +1252,10 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
|
||||
continue;
|
||||
}
|
||||
|
||||
jobQueue.emplace_back([this, zipFile, entry, ifs, libFileId,
|
||||
libPath = std::move(targetLibPath), makeFileTs]() mutable {
|
||||
extractZipFile(ifs, zipFile.get(), entry, libFileId, libPath, makeFileTs);
|
||||
jobQueue.emplace_back([this, zipFile, entry, ifs = std::weak_ptr<IncFsMount>(ifs),
|
||||
libFileId, libPath = std::move(targetLibPath),
|
||||
makeFileTs]() mutable {
|
||||
extractZipFile(ifs.lock(), zipFile.get(), entry, libFileId, libPath, makeFileTs);
|
||||
});
|
||||
|
||||
if (sEnablePerfLogging) {
|
||||
@@ -1296,6 +1301,11 @@ void IncrementalService::extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle
|
||||
ZipEntry& entry, const incfs::FileId& libFileId,
|
||||
std::string_view targetLibPath,
|
||||
Clock::time_point scheduledTs) {
|
||||
if (!ifs) {
|
||||
LOG(INFO) << "Skipping zip file " << targetLibPath << " extraction for an expired mount";
|
||||
return;
|
||||
}
|
||||
|
||||
auto libName = path::basename(targetLibPath);
|
||||
auto startedTs = Clock::now();
|
||||
|
||||
|
||||
@@ -289,10 +289,11 @@ private:
|
||||
Clock::time_point scheduledTs);
|
||||
|
||||
private:
|
||||
std::unique_ptr<VoldServiceWrapper> const mVold;
|
||||
std::unique_ptr<DataLoaderManagerWrapper> const mDataLoaderManager;
|
||||
std::unique_ptr<IncFsWrapper> const mIncFs;
|
||||
std::unique_ptr<AppOpsManagerWrapper> const mAppOpsManager;
|
||||
const std::unique_ptr<VoldServiceWrapper> mVold;
|
||||
const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
|
||||
const std::unique_ptr<IncFsWrapper> mIncFs;
|
||||
const std::unique_ptr<AppOpsManagerWrapper> mAppOpsManager;
|
||||
const std::unique_ptr<JniWrapper> mJni;
|
||||
const std::string mIncrementalDir;
|
||||
|
||||
mutable std::mutex mLock;
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "IncrementalService"
|
||||
|
||||
#include "ServiceWrappers.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <utils/String16.h>
|
||||
|
||||
using namespace std::literals;
|
||||
@@ -25,8 +28,123 @@ namespace android::os::incremental {
|
||||
static constexpr auto kVoldServiceName = "vold"sv;
|
||||
static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv;
|
||||
|
||||
RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager)
|
||||
: mServiceManager(std::move(serviceManager)) {}
|
||||
class RealVoldService : public VoldServiceWrapper {
|
||||
public:
|
||||
RealVoldService(const sp<os::IVold> vold) : mInterface(std::move(vold)) {}
|
||||
~RealVoldService() = default;
|
||||
binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir,
|
||||
int32_t flags,
|
||||
IncrementalFileSystemControlParcel* _aidl_return) const final {
|
||||
return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
|
||||
}
|
||||
binder::Status unmountIncFs(const std::string& dir) const final {
|
||||
return mInterface->unmountIncFs(dir);
|
||||
}
|
||||
binder::Status bindMount(const std::string& sourceDir,
|
||||
const std::string& targetDir) const final {
|
||||
return mInterface->bindMount(sourceDir, targetDir);
|
||||
}
|
||||
binder::Status setIncFsMountOptions(
|
||||
const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
|
||||
bool enableReadLogs) const final {
|
||||
return mInterface->setIncFsMountOptions(control, enableReadLogs);
|
||||
}
|
||||
|
||||
private:
|
||||
sp<os::IVold> mInterface;
|
||||
};
|
||||
|
||||
class RealDataLoaderManager : public DataLoaderManagerWrapper {
|
||||
public:
|
||||
RealDataLoaderManager(const sp<content::pm::IDataLoaderManager> manager)
|
||||
: mInterface(manager) {}
|
||||
~RealDataLoaderManager() = default;
|
||||
binder::Status initializeDataLoader(MountId mountId, const DataLoaderParamsParcel& params,
|
||||
const FileSystemControlParcel& control,
|
||||
const sp<IDataLoaderStatusListener>& listener,
|
||||
bool* _aidl_return) const final {
|
||||
return mInterface->initializeDataLoader(mountId, params, control, listener, _aidl_return);
|
||||
}
|
||||
binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const final {
|
||||
return mInterface->getDataLoader(mountId, _aidl_return);
|
||||
}
|
||||
binder::Status destroyDataLoader(MountId mountId) const final {
|
||||
return mInterface->destroyDataLoader(mountId);
|
||||
}
|
||||
|
||||
private:
|
||||
sp<content::pm::IDataLoaderManager> mInterface;
|
||||
};
|
||||
|
||||
class RealAppOpsManager : public AppOpsManagerWrapper {
|
||||
public:
|
||||
~RealAppOpsManager() = default;
|
||||
binder::Status checkPermission(const char* permission, const char* operation,
|
||||
const char* package) const final {
|
||||
return android::incremental::CheckPermissionForDataDelivery(permission, operation, package);
|
||||
}
|
||||
void startWatchingMode(int32_t op, const String16& packageName,
|
||||
const sp<IAppOpsCallback>& callback) final {
|
||||
mAppOpsManager.startWatchingMode(op, packageName, callback);
|
||||
}
|
||||
void stopWatchingMode(const sp<IAppOpsCallback>& callback) final {
|
||||
mAppOpsManager.stopWatchingMode(callback);
|
||||
}
|
||||
|
||||
private:
|
||||
android::AppOpsManager mAppOpsManager;
|
||||
};
|
||||
|
||||
class RealJniWrapper final : public JniWrapper {
|
||||
public:
|
||||
RealJniWrapper(JavaVM* jvm);
|
||||
void initializeForCurrentThread() const final;
|
||||
|
||||
static JavaVM* getJvm(JNIEnv* env);
|
||||
|
||||
private:
|
||||
JavaVM* const mJvm;
|
||||
};
|
||||
|
||||
class RealIncFs : public IncFsWrapper {
|
||||
public:
|
||||
RealIncFs() = default;
|
||||
~RealIncFs() = default;
|
||||
Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final {
|
||||
return incfs::createControl(cmd, pendingReads, logs);
|
||||
}
|
||||
ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
|
||||
NewFileParams params) const final {
|
||||
return incfs::makeFile(control, path, mode, id, params);
|
||||
}
|
||||
ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
|
||||
return incfs::makeDir(control, path, mode);
|
||||
}
|
||||
RawMetadata getMetadata(const Control& control, FileId fileid) const final {
|
||||
return incfs::getMetadata(control, fileid);
|
||||
}
|
||||
RawMetadata getMetadata(const Control& control, std::string_view path) const final {
|
||||
return incfs::getMetadata(control, path);
|
||||
}
|
||||
FileId getFileId(const Control& control, std::string_view path) const final {
|
||||
return incfs::getFileId(control, path);
|
||||
}
|
||||
ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
|
||||
return incfs::link(control, from, to);
|
||||
}
|
||||
ErrorCode unlink(const Control& control, std::string_view path) const final {
|
||||
return incfs::unlink(control, path);
|
||||
}
|
||||
base::unique_fd openForSpecialOps(const Control& control, FileId id) const final {
|
||||
return base::unique_fd{incfs::openForSpecialOps(control, id).release()};
|
||||
}
|
||||
ErrorCode writeBlocks(Span<const DataBlock> blocks) const final {
|
||||
return incfs::writeBlocks(blocks);
|
||||
}
|
||||
};
|
||||
|
||||
RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
|
||||
: mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
|
||||
|
||||
template <class INTERFACE>
|
||||
sp<INTERFACE> RealServiceManager::getRealService(std::string_view serviceName) const {
|
||||
@@ -63,4 +181,62 @@ std::unique_ptr<AppOpsManagerWrapper> RealServiceManager::getAppOpsManager() {
|
||||
return std::make_unique<RealAppOpsManager>();
|
||||
}
|
||||
|
||||
std::unique_ptr<JniWrapper> RealServiceManager::getJni() {
|
||||
return std::make_unique<RealJniWrapper>(mJvm);
|
||||
}
|
||||
|
||||
static JavaVM* getJavaVm(JNIEnv* env) {
|
||||
CHECK(env);
|
||||
JavaVM* jvm = nullptr;
|
||||
env->GetJavaVM(&jvm);
|
||||
CHECK(jvm);
|
||||
return jvm;
|
||||
}
|
||||
|
||||
static JNIEnv* getJniEnv(JavaVM* vm) {
|
||||
JNIEnv* env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
return nullptr;
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static JNIEnv* getOrAttachJniEnv(JavaVM* jvm) {
|
||||
if (!jvm) {
|
||||
LOG(ERROR) << "No JVM instance";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JNIEnv* env = getJniEnv(jvm);
|
||||
if (!env) {
|
||||
int result = jvm->AttachCurrentThread(&env, nullptr);
|
||||
if (result != JNI_OK) {
|
||||
LOG(ERROR) << "JVM thread attach failed: " << result;
|
||||
return nullptr;
|
||||
}
|
||||
struct VmDetacher {
|
||||
VmDetacher(JavaVM* vm) : mVm(vm) {}
|
||||
~VmDetacher() { mVm->DetachCurrentThread(); }
|
||||
|
||||
private:
|
||||
JavaVM* const mVm;
|
||||
};
|
||||
static thread_local VmDetacher detacher(jvm);
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
RealJniWrapper::RealJniWrapper(JavaVM* jvm) : mJvm(jvm) {
|
||||
CHECK(!!mJvm) << "JVM is unavailable";
|
||||
}
|
||||
|
||||
void RealJniWrapper::initializeForCurrentThread() const {
|
||||
(void)getOrAttachJniEnv(mJvm);
|
||||
}
|
||||
|
||||
JavaVM* RealJniWrapper::getJvm(JNIEnv* env) {
|
||||
return getJavaVm(env);
|
||||
}
|
||||
|
||||
} // namespace android::os::incremental
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <binder/AppOpsManager.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <incfs.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -93,6 +94,12 @@ public:
|
||||
virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
|
||||
};
|
||||
|
||||
class JniWrapper {
|
||||
public:
|
||||
virtual ~JniWrapper() = default;
|
||||
virtual void initializeForCurrentThread() const = 0;
|
||||
};
|
||||
|
||||
class ServiceManagerWrapper {
|
||||
public:
|
||||
virtual ~ServiceManagerWrapper() = default;
|
||||
@@ -100,127 +107,26 @@ public:
|
||||
virtual std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() = 0;
|
||||
virtual std::unique_ptr<IncFsWrapper> getIncFs() = 0;
|
||||
virtual std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() = 0;
|
||||
virtual std::unique_ptr<JniWrapper> getJni() = 0;
|
||||
};
|
||||
|
||||
// --- Real stuff ---
|
||||
|
||||
class RealVoldService : public VoldServiceWrapper {
|
||||
public:
|
||||
RealVoldService(const sp<os::IVold> vold) : mInterface(std::move(vold)) {}
|
||||
~RealVoldService() = default;
|
||||
binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir,
|
||||
int32_t flags,
|
||||
IncrementalFileSystemControlParcel* _aidl_return) const final {
|
||||
return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
|
||||
}
|
||||
binder::Status unmountIncFs(const std::string& dir) const final {
|
||||
return mInterface->unmountIncFs(dir);
|
||||
}
|
||||
binder::Status bindMount(const std::string& sourceDir,
|
||||
const std::string& targetDir) const final {
|
||||
return mInterface->bindMount(sourceDir, targetDir);
|
||||
}
|
||||
binder::Status setIncFsMountOptions(
|
||||
const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
|
||||
bool enableReadLogs) const final {
|
||||
return mInterface->setIncFsMountOptions(control, enableReadLogs);
|
||||
}
|
||||
|
||||
private:
|
||||
sp<os::IVold> mInterface;
|
||||
};
|
||||
|
||||
class RealDataLoaderManager : public DataLoaderManagerWrapper {
|
||||
public:
|
||||
RealDataLoaderManager(const sp<content::pm::IDataLoaderManager> manager)
|
||||
: mInterface(manager) {}
|
||||
~RealDataLoaderManager() = default;
|
||||
binder::Status initializeDataLoader(MountId mountId, const DataLoaderParamsParcel& params,
|
||||
const FileSystemControlParcel& control,
|
||||
const sp<IDataLoaderStatusListener>& listener,
|
||||
bool* _aidl_return) const final {
|
||||
return mInterface->initializeDataLoader(mountId, params, control, listener, _aidl_return);
|
||||
}
|
||||
binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const final {
|
||||
return mInterface->getDataLoader(mountId, _aidl_return);
|
||||
}
|
||||
binder::Status destroyDataLoader(MountId mountId) const final {
|
||||
return mInterface->destroyDataLoader(mountId);
|
||||
}
|
||||
|
||||
private:
|
||||
sp<content::pm::IDataLoaderManager> mInterface;
|
||||
};
|
||||
|
||||
class RealAppOpsManager : public AppOpsManagerWrapper {
|
||||
public:
|
||||
~RealAppOpsManager() = default;
|
||||
binder::Status checkPermission(const char* permission, const char* operation,
|
||||
const char* package) const final {
|
||||
return android::incremental::CheckPermissionForDataDelivery(permission, operation, package);
|
||||
}
|
||||
void startWatchingMode(int32_t op, const String16& packageName,
|
||||
const sp<IAppOpsCallback>& callback) final {
|
||||
mAppOpsManager.startWatchingMode(op, packageName, callback);
|
||||
}
|
||||
void stopWatchingMode(const sp<IAppOpsCallback>& callback) final {
|
||||
mAppOpsManager.stopWatchingMode(callback);
|
||||
}
|
||||
|
||||
private:
|
||||
android::AppOpsManager mAppOpsManager;
|
||||
};
|
||||
|
||||
class RealServiceManager : public ServiceManagerWrapper {
|
||||
public:
|
||||
RealServiceManager(sp<IServiceManager> serviceManager);
|
||||
RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env);
|
||||
~RealServiceManager() = default;
|
||||
std::unique_ptr<VoldServiceWrapper> getVoldService() final;
|
||||
std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final;
|
||||
std::unique_ptr<IncFsWrapper> getIncFs() final;
|
||||
std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final;
|
||||
std::unique_ptr<JniWrapper> getJni() final;
|
||||
|
||||
private:
|
||||
template <class INTERFACE>
|
||||
sp<INTERFACE> getRealService(std::string_view serviceName) const;
|
||||
sp<android::IServiceManager> mServiceManager;
|
||||
};
|
||||
|
||||
class RealIncFs : public IncFsWrapper {
|
||||
public:
|
||||
RealIncFs() = default;
|
||||
~RealIncFs() = default;
|
||||
Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final {
|
||||
return incfs::createControl(cmd, pendingReads, logs);
|
||||
}
|
||||
ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
|
||||
NewFileParams params) const final {
|
||||
return incfs::makeFile(control, path, mode, id, params);
|
||||
}
|
||||
ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
|
||||
return incfs::makeDir(control, path, mode);
|
||||
}
|
||||
RawMetadata getMetadata(const Control& control, FileId fileid) const final {
|
||||
return incfs::getMetadata(control, fileid);
|
||||
}
|
||||
RawMetadata getMetadata(const Control& control, std::string_view path) const final {
|
||||
return incfs::getMetadata(control, path);
|
||||
}
|
||||
FileId getFileId(const Control& control, std::string_view path) const final {
|
||||
return incfs::getFileId(control, path);
|
||||
}
|
||||
ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
|
||||
return incfs::link(control, from, to);
|
||||
}
|
||||
ErrorCode unlink(const Control& control, std::string_view path) const final {
|
||||
return incfs::unlink(control, path);
|
||||
}
|
||||
base::unique_fd openForSpecialOps(const Control& control, FileId id) const final {
|
||||
return base::unique_fd{incfs::openForSpecialOps(control, id).release()};
|
||||
}
|
||||
ErrorCode writeBlocks(Span<const DataBlock> blocks) const final {
|
||||
return incfs::writeBlocks(blocks);
|
||||
}
|
||||
JavaVM* const mJvm;
|
||||
};
|
||||
|
||||
} // namespace android::os::incremental
|
||||
|
||||
@@ -24,7 +24,7 @@ __BEGIN_DECLS
|
||||
|
||||
#define INCREMENTAL_LIBRARY_NAME "service.incremental.so"
|
||||
|
||||
jlong Incremental_IncrementalService_Start();
|
||||
jlong Incremental_IncrementalService_Start(JNIEnv* env);
|
||||
void Incremental_IncrementalService_OnSystemReady(jlong self);
|
||||
void Incremental_IncrementalService_OnDump(jlong self, jint fd);
|
||||
|
||||
|
||||
@@ -261,28 +261,39 @@ public:
|
||||
sp<IAppOpsCallback> mStoredCallback;
|
||||
};
|
||||
|
||||
class MockJniWrapper : public JniWrapper {
|
||||
public:
|
||||
MOCK_CONST_METHOD0(initializeForCurrentThread, void());
|
||||
|
||||
MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(1); }
|
||||
};
|
||||
|
||||
class MockServiceManager : public ServiceManagerWrapper {
|
||||
public:
|
||||
MockServiceManager(std::unique_ptr<MockVoldService> vold,
|
||||
std::unique_ptr<MockDataLoaderManager> manager,
|
||||
std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
|
||||
std::unique_ptr<MockIncFs> incfs,
|
||||
std::unique_ptr<MockAppOpsManager> appOpsManager)
|
||||
std::unique_ptr<MockAppOpsManager> appOpsManager,
|
||||
std::unique_ptr<MockJniWrapper> jni)
|
||||
: mVold(std::move(vold)),
|
||||
mDataLoaderManager(std::move(manager)),
|
||||
mDataLoaderManager(std::move(dataLoaderManager)),
|
||||
mIncFs(std::move(incfs)),
|
||||
mAppOpsManager(std::move(appOpsManager)) {}
|
||||
mAppOpsManager(std::move(appOpsManager)),
|
||||
mJni(std::move(jni)) {}
|
||||
std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
|
||||
std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
|
||||
return std::move(mDataLoaderManager);
|
||||
}
|
||||
std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
|
||||
std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final { return std::move(mAppOpsManager); }
|
||||
std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<MockVoldService> mVold;
|
||||
std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
|
||||
std::unique_ptr<MockIncFs> mIncFs;
|
||||
std::unique_ptr<MockAppOpsManager> mAppOpsManager;
|
||||
std::unique_ptr<MockJniWrapper> mJni;
|
||||
};
|
||||
|
||||
// --- IncrementalServiceTest ---
|
||||
@@ -298,11 +309,15 @@ public:
|
||||
mIncFs = incFs.get();
|
||||
auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
|
||||
mAppOpsManager = appOps.get();
|
||||
auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
|
||||
mJni = jni.get();
|
||||
mIncrementalService =
|
||||
std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
|
||||
std::move(dataloaderManager),
|
||||
std::move(
|
||||
dataloaderManager),
|
||||
std::move(incFs),
|
||||
std::move(appOps)),
|
||||
std::move(appOps),
|
||||
std::move(jni)),
|
||||
mRootDir.path);
|
||||
mDataLoaderParcel.packageName = "com.test";
|
||||
mDataLoaderParcel.arguments = "uri";
|
||||
@@ -336,6 +351,7 @@ protected:
|
||||
NiceMock<MockIncFs>* mIncFs;
|
||||
NiceMock<MockDataLoaderManager>* mDataLoaderManager;
|
||||
NiceMock<MockAppOpsManager>* mAppOpsManager;
|
||||
NiceMock<MockJniWrapper>* mJni;
|
||||
std::unique_ptr<IncrementalService> mIncrementalService;
|
||||
TemporaryDir mRootDir;
|
||||
DataLoaderParamsParcel mDataLoaderParcel;
|
||||
|
||||
Reference in New Issue
Block a user