[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
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index e99a264..76b1713 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -135,7 +135,7 @@
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,
diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
index 853eba7..e32a343 100644
--- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
+++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
@@ -410,6 +410,8 @@
// Installation.
bool onPrepareImage(dataloader::DataLoaderInstallationFiles addedFiles) final {
+ ALOGE("onPrepareImage: start.");
+
JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
const auto& jni = jniIds(env);
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
index ebebf60..fc8c6fe 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -58,10 +58,10 @@
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 @@
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 @@
} // 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) {
diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h
index aca10ab..5a7d5da 100644
--- a/services/incremental/BinderIncrementalService.h
+++ b/services/incremental/BinderIncrementalService.h
@@ -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 @@
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;
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 400388e..2c6bf0a 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -237,6 +237,7 @@
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 @@
}
mJobQueue.reserve(16);
- mJobProcessor = std::thread([this]() { runJobProcessing(); });
+ mJobProcessor = std::thread([this]() {
+ mJni->initializeForCurrentThread();
+ runJobProcessing();
+ });
mountExistingImages();
}
@@ -1248,9 +1252,10 @@
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 @@
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();
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 4fdce4b..e7705df 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -289,10 +289,11 @@
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;
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 9f4192f..bf8e696 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -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 @@
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 @@
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
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 84bf1ff..142bf2e 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -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 @@
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 @@
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
diff --git a/services/incremental/include/incremental_service.h b/services/incremental/include/incremental_service.h
index 4a34b11..3213875 100644
--- a/services/incremental/include/incremental_service.h
+++ b/services/incremental/include/incremental_service.h
@@ -24,7 +24,7 @@
#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);
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 9911319..117dca8 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -261,28 +261,39 @@
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 @@
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 @@
NiceMock<MockIncFs>* mIncFs;
NiceMock<MockDataLoaderManager>* mDataLoaderManager;
NiceMock<MockAppOpsManager>* mAppOpsManager;
+ NiceMock<MockJniWrapper>* mJni;
std::unique_ptr<IncrementalService> mIncrementalService;
TemporaryDir mRootDir;
DataLoaderParamsParcel mDataLoaderParcel;