getService: try getting service before waiting

Since waiting involves extra IPCs, and the service
being already up is the common case, this is an optimization
we chose to make a long time ago but got lost in a
refactor.

Bug: 78288185
Test: boot device
Test: hidl's run_all_device_tests.sh (includes hidl_test)
Change-Id: Ia08b63bb42bd11377a73cd450a7b8e63766710b7
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 4023a19..01f83bd 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -703,11 +703,13 @@
     const bool vintfLegacy = (transport == Transport::EMPTY);
 #endif  // ENFORCE_VINTF_MANIFEST
 
-    while (!getStub && (vintfHwbinder || vintfLegacy)) {
-        if (waiter == nullptr) {
+    for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
+        if (waiter == nullptr && tries > 0) {
             waiter = new Waiter(descriptor, instance, sm);
         }
-        waiter->reset(); // don't reorder this -- see comments on reset()
+        if (waiter != nullptr) {
+            waiter->reset();  // don't reorder this -- see comments on reset()
+        }
         Return<sp<IBase>> ret = sm->get(descriptor, instance);
         if (!ret.isOk()) {
             ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
@@ -720,7 +722,9 @@
                 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
 
             if (canCastRet.isOk() && canCastRet) {
-                waiter->done();
+                if (waiter != nullptr) {
+                    waiter->done();
+                }
                 return base; // still needs to be wrapped by Bp class.
             }
 
@@ -730,8 +734,10 @@
         // In case of legacy or we were not asked to retry, don't.
         if (vintfLegacy || !retry) break;
 
-        ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
-        waiter->wait();
+        if (waiter != nullptr) {
+            ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
+            waiter->wait();
+        }
     }
 
     if (waiter != nullptr) {