Removing status reporting from under lock.
Test: atest PackageManagerShellCommandTest
Bug: b/136132412 b/133435829
Change-Id: I782b51ec792ec9464146a02c4afc3fc03bab7ae5
Merged-In: I782b51ec792ec9464146a02c4afc3fc03bab7ae5
diff --git a/libdataloader/DataLoaderConnector.cpp b/libdataloader/DataLoaderConnector.cpp
index fe4b49b..c86baac 100644
--- a/libdataloader/DataLoaderConnector.cpp
+++ b/libdataloader/DataLoaderConnector.cpp
@@ -262,9 +262,6 @@
return false;
}
- JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
- const auto& jni = jniIds(env);
- reportStatusViaCallback(env, mListener, mStorageId, jni.constants.DATA_LOADER_CREATED);
return true;
}
bool onStart() {
@@ -273,34 +270,17 @@
if (checkAndClearJavaException(__func__)) {
result = false;
}
- if (!result) {
- JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
- const auto& jni = jniIds(env);
- reportStatusViaCallback(env, mListener, mStorageId, jni.constants.DATA_LOADER_STOPPED);
- return false;
- }
- JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
- const auto& jni = jniIds(env);
- reportStatusViaCallback(env, mListener, mStorageId, jni.constants.DATA_LOADER_STARTED);
- return true;
+ return result;
}
void onStop() {
CHECK(mDataLoader);
mDataLoader->onStop(mDataLoader);
checkAndClearJavaException(__func__);
-
- JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
- const auto& jni = jniIds(env);
- reportStatusViaCallback(env, mListener, mStorageId, jni.constants.DATA_LOADER_STOPPED);
}
void onDestroy() {
CHECK(mDataLoader);
mDataLoader->onDestroy(mDataLoader);
checkAndClearJavaException(__func__);
-
- JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
- const auto& jni = jniIds(env);
- reportStatusViaCallback(env, mListener, mStorageId, jni.constants.DATA_LOADER_DESTROYED);
}
bool onPrepareImage(jobject addedFiles, jobject removedFiles) {
@@ -309,12 +289,6 @@
if (checkAndClearJavaException(__func__)) {
result = false;
}
-
- JNIEnv* env = GetOrAttachJNIEnvironment(mJvm);
- const auto& jni = jniIds(env);
- reportStatusViaCallback(env, mListener, mStorageId,
- result ? jni.constants.DATA_LOADER_IMAGE_READY
- : jni.constants.DATA_LOADER_IMAGE_NOT_READY);
return result;
}
@@ -384,6 +358,7 @@
}
const IncFsControl& control() const { return mControl; }
+ jobject listener() const { return mListener; }
private:
JavaVM* mJvm = nullptr;
@@ -573,11 +548,15 @@
bool DataLoaderService_OnCreate(JNIEnv* env, jobject service, jint storageId, jobject control,
jobject params, jobject listener) {
- auto reportNotReady = [listener, storageId](JNIEnv* env) {
+ auto reportDestroyed = [env, storageId](jobject listener) {
+ if (listener) {
+ return;
+ }
const auto& jni = jniIds(env);
reportStatusViaCallback(env, listener, storageId, jni.constants.DATA_LOADER_DESTROYED);
};
- std::unique_ptr<JNIEnv, decltype(reportNotReady)> reportNotReadyOnExit(env, reportNotReady);
+ std::unique_ptr<_jobject, decltype(reportDestroyed)> reportDestroyedOnExit(listener,
+ reportDestroyed);
auto nativeControl = createIncFsControlFromManaged(env, control);
ALOGE("DataLoader::create1 cmd: %d/%s", nativeControl.cmdFd,
@@ -615,12 +594,26 @@
}
}
- reportNotReadyOnExit.release();
+ reportDestroyedOnExit.release();
+
+ const auto& jni = jniIds(env);
+ reportStatusViaCallback(env, listener, storageId, jni.constants.DATA_LOADER_CREATED);
+
return true;
}
-bool DataLoaderService_OnStart(jint storageId) {
+bool DataLoaderService_OnStart(JNIEnv* env, jint storageId) {
+ auto reportStopped = [env, storageId](jobject listener) {
+ if (listener) {
+ return;
+ }
+ const auto& jni = jniIds(env);
+ reportStatusViaCallback(env, listener, storageId, jni.constants.DATA_LOADER_STOPPED);
+ };
+ std::unique_ptr<_jobject, decltype(reportStopped)> reportStoppedOnExit(nullptr, reportStopped);
+
IncFsControl control;
+ jobject listener;
DataLoaderConnectorPtr dataLoaderConnector;
{
std::lock_guard lock{globals().dataLoaderConnectorsLock};
@@ -629,6 +622,10 @@
ALOGE("Failed to start id(%d): not found", storageId);
return false;
}
+
+ listener = dlIt->second->listener();
+ reportStoppedOnExit.reset(listener);
+
dataLoaderConnector = dlIt->second;
if (!dataLoaderConnector->onStart()) {
ALOGE("Failed to start id(%d): onStart returned false", storageId);
@@ -662,10 +659,24 @@
logLooper().wake();
}
+ reportStoppedOnExit.release();
+
+ const auto& jni = jniIds(env);
+ reportStatusViaCallback(env, listener, storageId, jni.constants.DATA_LOADER_STARTED);
+
return true;
}
-bool DataLoaderService_OnStop(jint storageId) {
+bool DataLoaderService_OnStop(JNIEnv* env, jint storageId) {
+ auto reportStopped = [env, storageId](jobject listener) {
+ if (listener) {
+ return;
+ }
+ const auto& jni = jniIds(env);
+ reportStatusViaCallback(env, listener, storageId, jni.constants.DATA_LOADER_STOPPED);
+ };
+ std::unique_ptr<_jobject, decltype(reportStopped)> reportStoppedOnExit(nullptr, reportStopped);
+
IncFsControl control;
{
std::lock_guard lock{globals().dataLoaderConnectorsLock};
@@ -675,6 +686,8 @@
return false;
}
control = dlIt->second->control();
+
+ reportStoppedOnExit.reset(dlIt->second->listener());
}
if (control.cmdFd >= 0) {
@@ -702,8 +715,18 @@
return true;
}
-bool DataLoaderService_OnDestroy(jint storageId) {
- DataLoaderService_OnStop(storageId);
+bool DataLoaderService_OnDestroy(JNIEnv* env, jint storageId) {
+ DataLoaderService_OnStop(env, storageId);
+
+ auto reportDestroyed = [env, storageId](jobject listener) {
+ if (listener) {
+ return;
+ }
+ const auto& jni = jniIds(env);
+ reportStatusViaCallback(env, listener, storageId, jni.constants.DATA_LOADER_DESTROYED);
+ };
+ std::unique_ptr<_jobject, decltype(reportDestroyed)> reportDestroyedOnExit(nullptr,
+ reportDestroyed);
std::lock_guard lock{globals().dataLoaderConnectorsLock};
auto dlIt = globals().dataLoaderConnectors.find(storageId);
@@ -711,19 +734,36 @@
ALOGE("Failed to remove id(%d): not found", storageId);
return false;
}
+ reportDestroyedOnExit.reset(env->NewLocalRef(dlIt->second->listener()));
+
auto&& dataLoaderConnector = dlIt->second;
dataLoaderConnector->onDestroy();
globals().dataLoaderConnectors.erase(dlIt);
+
return true;
}
-bool DataLoaderService_OnPrepareImage(jint storageId, jobject addedFiles, jobject removedFiles) {
- std::lock_guard lock{globals().dataLoaderConnectorsLock};
- auto dlIt = globals().dataLoaderConnectors.find(storageId);
- if (dlIt == globals().dataLoaderConnectors.end()) {
- ALOGE("Failed to handle onPrepareImage for id(%d): not found", storageId);
- return false;
+bool DataLoaderService_OnPrepareImage(JNIEnv* env, jint storageId, jobject addedFiles,
+ jobject removedFiles) {
+ jobject listener;
+ bool result;
+ {
+ std::lock_guard lock{globals().dataLoaderConnectorsLock};
+ auto dlIt = globals().dataLoaderConnectors.find(storageId);
+ if (dlIt == globals().dataLoaderConnectors.end()) {
+ ALOGE("Failed to handle onPrepareImage for id(%d): not found", storageId);
+ return false;
+ }
+ listener = dlIt->second->listener();
+
+ auto&& dataLoaderConnector = dlIt->second;
+ result = dataLoaderConnector->onPrepareImage(addedFiles, removedFiles);
}
- auto&& dataLoaderConnector = dlIt->second;
- return dataLoaderConnector->onPrepareImage(addedFiles, removedFiles);
+
+ const auto& jni = jniIds(env);
+ reportStatusViaCallback(env, listener, storageId,
+ result ? jni.constants.DATA_LOADER_IMAGE_READY
+ : jni.constants.DATA_LOADER_IMAGE_NOT_READY);
+
+ return result;
}
diff --git a/libdataloader/include/dataloader_ndk.h b/libdataloader/include/dataloader_ndk.h
index 9e57ac7..3304aa1 100644
--- a/libdataloader/include/dataloader_ndk.h
+++ b/libdataloader/include/dataloader_ndk.h
@@ -88,8 +88,6 @@
};
void DataLoader_Initialize(struct DataLoaderFactory*);
-bool DataLoaderService_OnPrepareImage(jint storageId, jobject addedFiles, jobject removedFiles);
-
void DataLoader_FilesystemConnector_writeData(DataLoaderFilesystemConnectorPtr, jstring name,
jlong offsetBytes, jlong lengthBytes,
jobject incomingFd);
@@ -107,11 +105,12 @@
// DataLoaderService JNI
bool DataLoaderService_OnCreate(JNIEnv* env, jobject service, jint storageId, jobject control,
jobject params, jobject listener);
-bool DataLoaderService_OnStart(jint storageId);
-bool DataLoaderService_OnStop(jint storageId);
-bool DataLoaderService_OnDestroy(jint storageId);
+bool DataLoaderService_OnStart(JNIEnv* env, jint storageId);
+bool DataLoaderService_OnStop(JNIEnv* env, jint storageId);
+bool DataLoaderService_OnDestroy(JNIEnv* env, jint storageId);
-bool DataLoaderService_OnPrepareImage(jint storageId, jobject addedFiles, jobject removedFiles);
+bool DataLoaderService_OnPrepareImage(JNIEnv* env, jint storageId, jobject addedFiles,
+ jobject removedFiles);
__END_DECLS