Merge "Add lint for compound types containing < 2 fields"
diff --git a/generateCpp.cpp b/generateCpp.cpp
index b160a11..cf8381e 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -1369,11 +1369,6 @@
out.indent();
- out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
- << ";\n";
- out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
- out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
-
generateStubSourceForMethod(out, method, superInterface);
out.unindent();
diff --git a/generateJava.cpp b/generateJava.cpp
index 577caf9..b0b002e 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -508,15 +508,6 @@
out.indent();
- out << "boolean _hidl_is_oneway = (_hidl_flags & " << Interface::FLAG_ONE_WAY->javaValue()
- << ") != 0;\n";
- out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
- out.block([&] {
- out << "_hidl_reply.writeStatus(" << UNKNOWN_ERROR << ");\n";
- out << "_hidl_reply.send();\n";
- out << "break;\n";
- });
-
if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
method->javaImpl(IMPL_STUB, out);
out.unindent();
diff --git a/test/hidl_test/hidl_test_client.cpp b/test/hidl_test/hidl_test_client.cpp
index 23b5f08..ac28d22 100644
--- a/test/hidl_test/hidl_test_client.cpp
+++ b/test/hidl_test/hidl_test_client.cpp
@@ -19,6 +19,7 @@
#include <android/hardware/tests/bar/1.0/IBar.h>
#include <android/hardware/tests/bar/1.0/IComplicated.h>
#include <android/hardware/tests/bar/1.0/IImportRules.h>
+#include <android/hardware/tests/baz/1.0/BnHwBaz.h>
#include <android/hardware/tests/baz/1.0/IBaz.h>
#include <android/hardware/tests/expression/1.0/IExpression.h>
#include <android/hardware/tests/foo/1.0/BnHwSimple.h>
@@ -715,13 +716,6 @@
[](const hidl_vec<hidl_string>& registered) { ASSERT_EQ(0, registered.size()); }));
}
-TEST_F(HidlTest, RegisterSameInterfaceRepeatedly) {
- for (size_t i = 0; i < 1000; i++) {
- sp<IChild> child = new SimpleChild();
- EXPECT_EQ(::android::OK, child->registerAsService());
- }
-}
-
TEST_F(HidlTest, SubInterfaceServiceRegistrationTest) {
using ::android::hardware::interfacesEqual;
@@ -1882,6 +1876,58 @@
EXPECT_OK(bar->thisIsNew());
}
+TEST_F(HidlTest, TwowayMethodOnewayEnabledTest) {
+ using ::android::hardware::IBinder;
+ using ::android::hardware::Parcel;
+ using ::android::hardware::tests::baz::V1_0::BnHwBaz;
+
+ sp<IBinder> binder = ::android::hardware::toBinder(baz);
+
+ Parcel request, reply;
+ EXPECT_EQ(::android::OK, request.writeInterfaceToken(IBaz::descriptor));
+ EXPECT_EQ(::android::OK, request.writeInt64(1234));
+ // IBaz::doThatAndReturnSomething is two-way but we call it using FLAG_ONEWAY.
+ EXPECT_EQ(::android::OK, binder->transact(18 /*doThatAndReturnSomething*/, request, &reply,
+ IBinder::FLAG_ONEWAY));
+
+ ::android::hardware::Status status;
+ ::android::status_t readFromParcelStatus = ::android::hardware::readFromParcel(&status, reply);
+ if (mode == BINDERIZED) {
+ EXPECT_EQ(::android::NOT_ENOUGH_DATA, readFromParcelStatus);
+ EXPECT_EQ(::android::hardware::Status::EX_TRANSACTION_FAILED, status.exceptionCode());
+ } else {
+ EXPECT_EQ(666, reply.readInt32());
+ }
+
+ EXPECT_OK(baz->ping()); // still works
+}
+
+TEST_F(HidlTest, OnewayMethodOnewayDisabledTest) {
+ using ::android::hardware::IBinder;
+ using ::android::hardware::Parcel;
+ using ::android::hardware::tests::baz::V1_0::BnHwBaz;
+
+ sp<IBinder> binder = ::android::hardware::toBinder(baz);
+
+ Parcel request, reply;
+ EXPECT_EQ(::android::OK, request.writeInterfaceToken(IBaz::descriptor));
+ EXPECT_EQ(::android::OK, request.writeFloat(1.0f));
+ nsecs_t now = systemTime();
+ // IBaz::doThis is oneway but we call it without using FLAG_ONEWAY.
+ EXPECT_EQ(
+ // Expect OK because IPCThreadState::executeCommand for BR_TRANSACTION
+ // sends an empty reply for two-way transactions if the transaction itself
+ // did not send a reply.
+ ::android::OK,
+ binder->transact(17 /*doThis*/, request, &reply, 0 /* Not FLAG_ONEWAY */));
+ if (gHidlEnvironment->enableDelayMeasurementTests) {
+ // IBaz::doThis is oneway, should return instantly.
+ EXPECT_LT(systemTime() - now, ONEWAY_TOLERANCE_NS);
+ }
+
+ EXPECT_OK(baz->ping()); // still works
+}
+
TEST_F(HidlTest, TrieSimpleTest) {
trieInterface->newTrie([&](const TrieNode& trie) {
trieInterface->addStrings(trie, {"a", "ba"}, [&](const TrieNode& trie) {
diff --git a/test/java_test/hidl_test_java_native.cpp b/test/java_test/hidl_test_java_native.cpp
index a7467d7..0fdc097 100644
--- a/test/java_test/hidl_test_java_native.cpp
+++ b/test/java_test/hidl_test_java_native.cpp
@@ -632,6 +632,46 @@
in, [&](const auto &out) { EXPECT_EQ(in, out); }));
}
+TEST_F(HidlTest, TwowayMethodOnewayEnabledTest) {
+ using ::android::hardware::IBinder;
+ using ::android::hardware::Parcel;
+
+ sp<IBinder> binder = ::android::hardware::toBinder(baz);
+
+ Parcel request, reply;
+ EXPECT_EQ(::android::OK, request.writeInterfaceToken(IBaz::descriptor));
+ EXPECT_EQ(::android::OK, request.writeInt64(1234));
+ // IBaz::doThatAndReturnSomething is two-way but we call it using FLAG_ONEWAY.
+ EXPECT_EQ(::android::OK, binder->transact(18 /*doThatAndReturnSomething*/, request, &reply,
+ IBinder::FLAG_ONEWAY));
+
+ ::android::hardware::Status status;
+ EXPECT_EQ(::android::NOT_ENOUGH_DATA, ::android::hardware::readFromParcel(&status, reply));
+ EXPECT_EQ(::android::hardware::Status::EX_TRANSACTION_FAILED, status.exceptionCode());
+
+ EXPECT_OK(baz->ping()); // still works
+}
+
+TEST_F(HidlTest, OnewayMethodOnewayDisabledTest) {
+ using ::android::hardware::IBinder;
+ using ::android::hardware::Parcel;
+
+ sp<IBinder> binder = ::android::hardware::toBinder(baz);
+
+ Parcel request, reply;
+ EXPECT_EQ(::android::OK, request.writeInterfaceToken(IBaz::descriptor));
+ EXPECT_EQ(::android::OK, request.writeFloat(1.0f));
+ // IBaz::doThis is oneway but we call it without using FLAG_ONEWAY.
+ EXPECT_EQ(
+ // Expect UNKNOWN_ERROR because the JNI class JHwBinder always sets
+ // the reply to UNKNOWN_ERROR for two-way transactions if the
+ // transaction itself did not send a reply.
+ ::android::UNKNOWN_ERROR,
+ binder->transact(17 /*doThis*/, request, &reply, 0 /* Not FLAG_ONEWAY */));
+
+ EXPECT_OK(baz->ping()); // still works
+}
+
TEST_F(HidlTest, SafeUnionNoInitTest) {
EXPECT_OK(safeunionInterface->newLargeSafeUnion([&](const LargeSafeUnion& safeUnion) {
EXPECT_EQ(LargeSafeUnion::hidl_discriminator::noinit, safeUnion.getDiscriminator());
diff --git a/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java b/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
index 0f1394c..0e278d9 100644
--- a/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
+++ b/test/java_test/src/com/android/commands/hidl_test_java/HidlTestJava.java
@@ -30,6 +30,9 @@
import android.hardware.tests.safeunion.V1_0.ISafeUnion.LargeSafeUnion;
import android.hardware.tests.safeunion.V1_0.ISafeUnion.SmallSafeUnion;
import android.os.HwBinder;
+import android.os.HwParcel;
+import android.os.IBinder;
+import android.os.IHwBinder;
import android.os.NativeHandle;
import android.os.RemoteException;
import android.os.HidlSupport;
@@ -577,6 +580,46 @@
}
{
+ // Tests calling a two-way method with oneway enabled.
+ IHwBinder binder = proxy.asBinder();
+ HwParcel request = new HwParcel();
+ HwParcel reply = new HwParcel();
+
+ request.writeInterfaceToken(IBaz.kInterfaceName);
+ request.writeInt64(1234);
+ // IBaz::doThatAndReturnSomething is not oneway but we call it using FLAG_ONEWAY.
+ binder.transact(18 /*doThatAndReturnSomething*/, request, reply, IBinder.FLAG_ONEWAY);
+
+ try {
+ reply.verifySuccess();
+ // This should never run.
+ ExpectTrue(false);
+ } catch (Exception e) {
+ ExpectTrue(e instanceof RemoteException);
+ }
+
+ proxy.ping();
+ }
+
+ {
+ // Tests calling a oneway method with oneway disabled.
+ IHwBinder binder = proxy.asBinder();
+ HwParcel request = new HwParcel();
+ HwParcel reply = new HwParcel();
+
+ request.writeInterfaceToken(IBaz.kInterfaceName);
+ request.writeFloat(1.0f);
+ // IBaz::doThis is oneway but we call it without using FLAG_ONEWAY.
+ // This does not raise an exception because
+ // IPCThreadState::executeCommand for BR_TRANSACTION sends an empty
+ // reply for two-way transactions if the transaction itself did not
+ // send a reply.
+ binder.transact(17 /*doThis*/, request, reply, 0 /* Not FLAG_ONEWAY */);
+
+ proxy.ping();
+ }
+
+ {
IBase.Foo foo = new IBase.Foo();
foo.x = 1;