Merge "Change method name."
diff --git a/test/utils_test/Android.bp b/test/utils_test/Android.bp
index d1aa2a4..808078e 100644
--- a/test/utils_test/Android.bp
+++ b/test/utils_test/Android.bp
@@ -17,6 +17,7 @@
     defaults: ["hidl-gen-defaults"],
     host_supported: true,
     shared_libs: ["libhidl-gen-utils"],
+    static_libs: ["libgmock"],
     srcs: ["main.cpp"],
     test_suites: ["general-tests"],
 }
diff --git a/test/utils_test/main.cpp b/test/utils_test/main.cpp
index 0d88d26..41185c2 100644
--- a/test/utils_test/main.cpp
+++ b/test/utils_test/main.cpp
@@ -18,11 +18,14 @@
 
 #include <hidl-util/FqInstance.h>
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <vector>
 
 using ::android::FqInstance;
 using ::android::FQName;
+using ::testing::Optional;
+using ::testing::Property;
 
 static const std::vector<std::string> kValidFqNames = {
         "android.hardware.foo@1.0::IFoo.Type",
@@ -191,6 +194,21 @@
     EXPECT_EQ((std::make_pair<size_t, size_t>(1u, 2u)), i.getVersion());
 }
 
+TEST(LibHidlGenUtilsTest, FqInstanceFrom) {
+    EXPECT_THAT(FqInstance::from("android.hardware.foo", 1, 0, "IFoo", "default"),
+                Optional(Property(&FqInstance::string, "android.hardware.foo@1.0::IFoo/default")));
+    EXPECT_THAT(FqInstance::from("android.hardware.foo", 1, 0, "IFoo"),
+                Optional(Property(&FqInstance::string, "android.hardware.foo@1.0::IFoo")));
+    EXPECT_THAT(FqInstance::from("android.hardware.foo", 1, 0),
+                Optional(Property(&FqInstance::string, "android.hardware.foo@1.0")));
+    EXPECT_THAT(FqInstance::from(1, 0, "IFoo", "default"),
+                Optional(Property(&FqInstance::string, "@1.0::IFoo/default")));
+    EXPECT_THAT(FqInstance::from(1, 0, "IFoo"),
+                Optional(Property(&FqInstance::string, "@1.0::IFoo")));
+    EXPECT_THAT(FqInstance::from("IFoo", "default"),
+                Optional(Property(&FqInstance::string, "IFoo/default")));
+}
+
 int main(int argc, char **argv) {
     ::testing::InitGoogleTest(&argc, argv);
     return RUN_ALL_TESTS();
diff --git a/utils/include/hidl-util/FqInstance.h b/utils/include/hidl-util/FqInstance.h
index 486845f..35d7a93 100644
--- a/utils/include/hidl-util/FqInstance.h
+++ b/utils/include/hidl-util/FqInstance.h
@@ -18,6 +18,7 @@
 
 #define ANDROID_FQINSTANCE_H_
 
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -69,7 +70,6 @@
     // IFoo.Type:MY_ENUM_VALUE
     //
     // If no "/instance", hasInstance() will return false afterwards.
-    // TODO(b/73774955): deprecate this and use std::optional.
     __attribute__((warn_unused_result)) bool setTo(const std::string& s);
 
     // Convenience method when an FQName and instance are already available.
@@ -95,6 +95,15 @@
     __attribute__((warn_unused_result)) bool setTo(const std::string& interface,
                                                    const std::string& instance);
 
+    // Same as creating an FqInstance then call setTo. See setTo for all valid signatures.
+    // If setTo returns false, this function returns nullopt.
+    template <typename... Args>
+    static std::optional<FqInstance> from(Args&&... args) {
+        FqInstance fqInstance;
+        if (fqInstance.setTo(std::forward<Args>(args)...)) return fqInstance;
+        return std::nullopt;
+    }
+
     // undefined behavior if:
     // - Default constructor is called without setTo();
     // - setTo is called but returned false.