1414 * limitations under the License.
1515 */
1616
17+ #include < chrono>
18+ #include < future>
19+ #include < mutex>
20+ #include " android/hidl/base/1.0/IBase.h"
1721#define LOG_TAG " Lshal"
1822#include < android-base/logging.h>
1923
3640
3741using namespace testing ;
3842
43+ using std::chrono_literals::operator " " ms;
44+
3945using ::android::hidl::base::V1_0::DebugInfo;
4046using ::android::hidl::base::V1_0::IBase;
4147using ::android::hidl::manager::V1_0::IServiceManager;
@@ -934,12 +940,9 @@ TEST_F(ListTest, DumpDebug) {
934940 return hardware::Void ();
935941 }));
936942 EXPECT_CALL (*serviceManager, get (_, _))
937- .WillRepeatedly (
938- Invoke ([&](const hidl_string&, const hidl_string& instance) -> sp<IBase> {
939- int id = getIdFromInstanceName (instance);
940- if (id > inheritanceLevel) return nullptr ;
941- return sp<IBase>(service);
942- }));
943+ .WillRepeatedly (Invoke ([&](const hidl_string&, const hidl_string&) -> sp<IBase> {
944+ return sp<IBase>(service);
945+ }));
943946
944947 const std::string expected = " [fake description 0]\n "
945948 " Interface\n "
@@ -957,6 +960,110 @@ TEST_F(ListTest, DumpDebug) {
957960 EXPECT_EQ (" " , err.str ());
958961}
959962
963+ // In SlowService, everything goes slooooooow. Each IPC call will wait for
964+ // the specified time before calling the callback function or returning.
965+ class SlowService : public IBase {
966+ public:
967+ explicit SlowService (std::chrono::milliseconds wait) : mWait(wait) {}
968+ android::hardware::Return<void > interfaceDescriptor (interfaceDescriptor_cb cb) override {
969+ std::this_thread::sleep_for (mWait );
970+ cb (getInterfaceName (1 ));
971+ storeHistory (" interfaceDescriptor" );
972+ return hardware::Void ();
973+ }
974+ android::hardware::Return<void > interfaceChain (interfaceChain_cb cb) override {
975+ std::this_thread::sleep_for (mWait );
976+ std::vector<hidl_string> ret;
977+ ret.push_back (getInterfaceName (1 ));
978+ ret.push_back (IBase::descriptor);
979+ cb (ret);
980+ storeHistory (" interfaceChain" );
981+ return hardware::Void ();
982+ }
983+ android::hardware::Return<void > getHashChain (getHashChain_cb cb) override {
984+ std::this_thread::sleep_for (mWait );
985+ std::vector<hidl_hash> ret;
986+ ret.push_back (getHashFromId (0 ));
987+ ret.push_back (getHashFromId (0xff ));
988+ cb (ret);
989+ storeHistory (" getHashChain" );
990+ return hardware::Void ();
991+ }
992+ android::hardware::Return<void > debug (const hidl_handle&,
993+ const hidl_vec<hidl_string>&) override {
994+ std::this_thread::sleep_for (mWait );
995+ storeHistory (" debug" );
996+ return Void ();
997+ }
998+
999+ template <class R , class P , class Pred >
1000+ bool waitForHistory (std::chrono::duration<R, P> wait, Pred predicate) {
1001+ std::unique_lock<std::mutex> lock (mLock );
1002+ return mCv .wait_for (lock, wait, [&]() { return predicate (mCallHistory ); });
1003+ }
1004+
1005+ private:
1006+ void storeHistory (std::string hist) {
1007+ {
1008+ std::lock_guard<std::mutex> lock (mLock );
1009+ mCallHistory .emplace_back (std::move (hist));
1010+ }
1011+ mCv .notify_all ();
1012+ }
1013+
1014+ const std::chrono::milliseconds mWait ;
1015+ std::mutex mLock ;
1016+ std::condition_variable mCv ;
1017+ // List of functions that have finished being called on this interface.
1018+ std::vector<std::string> mCallHistory ;
1019+ };
1020+
1021+ class TimeoutTest : public ListTest {
1022+ public:
1023+ void setMockServiceManager (sp<IBase> service) {
1024+ EXPECT_CALL (*serviceManager, list (_))
1025+ .WillRepeatedly (Invoke ([&](IServiceManager::list_cb cb) {
1026+ std::vector<hidl_string> ret;
1027+ ret.push_back (getInterfaceName (1 ) + " /default" );
1028+ cb (ret);
1029+ return hardware::Void ();
1030+ }));
1031+ EXPECT_CALL (*serviceManager, get (_, _))
1032+ .WillRepeatedly (Invoke ([&](const hidl_string&, const hidl_string&) -> sp<IBase> {
1033+ return service;
1034+ }));
1035+ }
1036+ };
1037+
1038+ TEST_F (TimeoutTest, BackgroundThreadIsKept) {
1039+ auto lshalIpcTimeout = 100ms;
1040+ auto serviceIpcTimeout = 200ms;
1041+ lshal->setWaitTimeForTest (lshalIpcTimeout, lshalIpcTimeout);
1042+ sp<SlowService> service = new SlowService (serviceIpcTimeout);
1043+ setMockServiceManager (service);
1044+
1045+ optind = 1 ; // mimic Lshal::parseArg()
1046+ EXPECT_NE (0u , mockList->main (createArg ({" lshal" , " --types=b" , " -i" , " --neat" })));
1047+ EXPECT_THAT (err.str (), HasSubstr (" Skipping \" a.h.foo1@1.0::IFoo/default\" " ));
1048+ EXPECT_TRUE (service->waitForHistory (serviceIpcTimeout * 5 , [](const auto & hist) {
1049+ return hist.size () == 1 && hist[0 ] == " interfaceChain" ;
1050+ })) << " The background thread should continue after the main thread moves on, but it is killed" ;
1051+ }
1052+
1053+ TEST_F (TimeoutTest, BackgroundThreadDoesNotBlockMainThread) {
1054+ auto lshalIpcTimeout = 100ms;
1055+ auto serviceIpcTimeout = 2000ms;
1056+ auto start = std::chrono::system_clock::now ();
1057+ lshal->setWaitTimeForTest (lshalIpcTimeout, lshalIpcTimeout);
1058+ sp<SlowService> service = new SlowService (serviceIpcTimeout);
1059+ setMockServiceManager (service);
1060+
1061+ optind = 1 ; // mimic Lshal::parseArg()
1062+ EXPECT_NE (0u , mockList->main (createArg ({" lshal" , " --types=b" , " -i" , " --neat" })));
1063+ EXPECT_LE (std::chrono::system_clock::now (), start + 5 * lshalIpcTimeout)
1064+ << " The main thread should not be blocked by the background task" ;
1065+ }
1066+
9601067class ListVintfTest : public ListTest {
9611068public:
9621069 virtual void SetUp () override {
@@ -1079,5 +1186,6 @@ TEST_F(HelpTest, UnknownOptionHelp2) {
10791186
10801187int main (int argc, char **argv) {
10811188 ::testing::InitGoogleMock (&argc, argv);
1082- return RUN_ALL_TESTS ();
1189+ // Use _exit() to force terminate background threads in Timeout.h
1190+ _exit (RUN_ALL_TESTS ());
10831191}
0 commit comments