Fix getService should retry on DEAD_OBJECT
If getService sees DEAD_OBJECT or nullptr when calling
interfaceChain on the retrieved service, it should
retry. Otherwise (e.g. TRANSACTION_FAILED for selinux
denials), it should bail out.
Test: calling Debug.getMemoryInfo from apps does not hang
Test: kill system_server, audio_server restarts exactly once
(tested 10/10 times)
Test: taking screenshots / using camera / using maps
Test: adb push
$OUT/data/nativetest/VtsHalNfcV1_0TargetTest/VtsHalNfcV1_0TargetTest
/data/local/tmp && adb shell
/data/local/tmp/VtsHalNfcV1_0TargetTest
Bug: 36153684
Bug: 36611652
Change-Id: Iee10d4b9a1c4edfd154afb588a56fcd8c489641e
diff --git a/base/include/hidl/Status.h b/base/include/hidl/Status.h
index a4a83f4..a04cf77 100644
--- a/base/include/hidl/Status.h
+++ b/base/include/hidl/Status.h
@@ -21,6 +21,7 @@
#include <sstream>
#include <android-base/macros.h>
+#include <hidl/HidlInternal.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
@@ -129,11 +130,16 @@
// For gtest output logging
std::ostream& operator<< (std::ostream& stream, const Status& s);
+template<typename T> class Return;
+
namespace details {
class return_status {
private:
Status mStatus {};
mutable bool mCheckedStatus = false;
+
+ template <typename T, typename U>
+ friend Return<U> StatusOf(const Return<T> &other);
protected:
void assertOk() const;
public:
@@ -155,6 +161,12 @@
return mStatus.isOk();
}
+ // Check if underlying error is DEAD_OBJECT.
+ // Does not set mCheckedStatus.
+ bool isDeadObject() const {
+ return mStatus.transactionError() == DEAD_OBJECT;
+ }
+
// For debugging purposes only
std::string description() const {
// Doesn't consider checked.
@@ -229,6 +241,18 @@
return Return<void>();
}
+namespace details {
+// Create a Return<U> from the Status of Return<T>. The provided
+// Return<T> must have an error status and have it checked.
+template <typename T, typename U>
+Return<U> StatusOf(const Return<T> &other) {
+ if (other.mStatus.isOk() || !other.mCheckedStatus) {
+ details::logAlwaysFatal("cannot call statusOf on an OK Status or an unchecked status");
+ }
+ return Return<U>{other.mStatus};
+}
+} // namespace details
+
} // namespace hardware
} // namespace android