Merge "Implicit const char* cast removed, operator<< added to hidl_string." into oc-dev
diff --git a/base/Android.bp b/base/Android.bp
index 321f499..25b2a80 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -21,12 +21,10 @@
         "libhidl-gen-utils",
         "liblog",
         "libutils",
-        "libvintf",
     ],
     export_shared_lib_headers: [
         "libbase",
         "libutils",
-        "libvintf",
     ],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index 5a07554..8223599 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -21,58 +21,10 @@
 
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
-#include <hidl-util/FQName.h>
-#include <vintf/VintfObject.h>
-#include <vintf/parse_string.h>
 
 namespace android {
 namespace hardware {
 
-vintf::Transport getTransportFromManifest(
-        const FQName &fqName, const std::string &instanceName,
-        const vintf::HalManifest *vm) {
-    if (vm == nullptr) {
-        return vintf::Transport::EMPTY;
-    }
-    return vm->getTransport(fqName.package(),
-            vintf::Version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()},
-            fqName.name(), instanceName);
-}
-
-vintf::Transport getTransport(const std::string &interfaceName, const std::string &instanceName) {
-    FQName fqName(interfaceName);
-    if (!fqName.isValid()) {
-        LOG(ERROR) << "getTransport: " << interfaceName << " is not a valid fully-qualified name.";
-        return vintf::Transport::EMPTY;
-    }
-    if (!fqName.hasVersion()) {
-        LOG(ERROR) << "getTransport: " << fqName.string()
-                   << " does not specify a version. Using default transport.";
-        return vintf::Transport::EMPTY;
-    }
-    if (fqName.name().empty()) {
-        LOG(ERROR) << "getTransport: " << fqName.string()
-                   << " does not specify an interface name. Using default transport.";
-        return vintf::Transport::EMPTY;
-    }
-
-    vintf::Transport tr = getTransportFromManifest(fqName, instanceName,
-            vintf::VintfObject::GetFrameworkHalManifest());
-    if (tr != vintf::Transport::EMPTY) {
-        return tr;
-    }
-    tr = getTransportFromManifest(fqName, instanceName,
-            vintf::VintfObject::GetDeviceHalManifest());
-    if (tr != vintf::Transport::EMPTY) {
-        return tr;
-    }
-
-    LOG(WARNING) << "getTransportFromManifest: Cannot find entry "
-                 << fqName.string()
-                 << " in either framework or device manifest, using default transport.";
-    return vintf::Transport::EMPTY;
-}
-
 namespace details {
 bool debuggable() {
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 0137eed..d7c3b83 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -31,7 +31,6 @@
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/StrongPointer.h>
-#include <vintf/Transport.h>
 #include <vector>
 
 namespace android {
@@ -56,13 +55,6 @@
 
 namespace hardware {
 
-// Get transport method from vendor interface manifest.
-// interfaceName has the format "android.hardware.foo@1.0::IFoo"
-// instanceName is "default", "ashmem", etc.
-// If it starts with "android.hidl.", a static map is looked up instead.
-vintf::Transport getTransport(const std::string &interfaceName,
-                              const std::string &instanceName);
-
 namespace details {
 // Return true on userdebug / eng builds and false on user builds.
 bool debuggable();
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
 
diff --git a/manifest.xml b/manifest.xml
index db83d63..d3a6e66 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -1,4 +1,4 @@
-<manifest version="1.0">
+<manifest version="1.0" type="framework">
     <hal>
         <name>android.hidl.manager</name>
         <transport>hwbinder</transport>
diff --git a/transport/Android.bp b/transport/Android.bp
index f81d9c6..835c6e1 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -60,7 +60,6 @@
         "HidlBinderSupport.cpp",
         "HidlPassthroughSupport.cpp",
         "HidlTransportSupport.cpp",
-        "LegacySupport.cpp",
         "ServiceManagement.cpp",
         "Static.cpp"
     ],
diff --git a/transport/LegacySupport.cpp b/transport/LegacySupport.cpp
deleted file mode 100644
index ae02928..0000000
--- a/transport/LegacySupport.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define LOG_TAG "libhidltransport"
-
-#include <inttypes.h>
-
-#include <hidl/LegacySupport.h>
-
-#include <chrono>
-#include <thread>
-#include <utils/misc.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
-
-#include <android-base/properties.h>
-
-namespace android {
-namespace hardware {
-
-namespace details {
-
-using android::base::GetBoolProperty;
-using android::base::WaitForPropertyCreation;
-
-static const char* kPersistPropReadyProperty = "ro.persistent_properties.ready";
-static const char* kBinderizationProperty = "persist.hal.binderization";
-
-bool blockingHalBinderizationEnabled() {
-    if (!GetBoolProperty(kPersistPropReadyProperty, false)) { // not set yet
-        int64_t startTime = elapsedRealtime();
-        WaitForPropertyCreation(kPersistPropReadyProperty, std::chrono::milliseconds::max());
-        ALOGI("Waiting for %s took %" PRId64 " ms", kPersistPropReadyProperty,
-              elapsedRealtime() - startTime);
-    }
-    return GetBoolProperty(kBinderizationProperty, false);
-}
-
-void blockIfBinderizationDisabled(const std::string& interface,
-                                  const std::string& instance) {
-    // TODO(b/34274385) remove this
-
-    size_t loc = interface.find_first_of("@");
-    if (loc == std::string::npos) {
-        LOG_ALWAYS_FATAL("Bad interface name: %s", interface.c_str());
-    }
-    std::string package = interface.substr(0, loc);
-
-    // only block if this is supposed to be toggled
-    if (getTransport(interface, instance) != vintf::Transport::TOGGLED) {
-        return;
-    }
-
-    // Must wait for data to be mounted and persistant properties to be read,
-    // but only delay the start of hals which require reading this property.
-    bool enabled = blockingHalBinderizationEnabled();
-
-    if (!enabled) {
-        ALOGI("Deactivating %s/%s binderized service to"
-              " yield to passthrough implementation.",
-              interface.c_str(),
-              instance.c_str());
-        while (true) {
-            sleep(UINT_MAX);
-        }
-    }
-}
-}  // namespace details
-
-}  // namespace hardware
-}  // namespace android
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 23349c3..ecd64b2 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -218,6 +218,12 @@
         return false;
     }
 
+    Return<Transport> getTransport(const hidl_string& /* fqName */,
+                                   const hidl_string& /* name */) {
+        LOG(FATAL) << "Cannot getTransport with passthrough service manager.";
+        return Transport::EMPTY;
+    }
+
     Return<void> list(list_cb /* _hidl_cb */) override {
         LOG(FATAL) << "Cannot list services with passthrough service manager.";
         return Void();
diff --git a/transport/include/hidl/HidlTransportSupport.h b/transport/include/hidl/HidlTransportSupport.h
index 8a2a70a..3cac1e9 100644
--- a/transport/include/hidl/HidlTransportSupport.h
+++ b/transport/include/hidl/HidlTransportSupport.h
@@ -50,16 +50,28 @@
 namespace details {
 
 // cast the interface IParent to IChild.
-// Return nullptr if parent is null or any failure.
+// Return nonnull if cast successful.
+// Return nullptr if:
+// 1. parent is null
+// 2. cast failed because IChild is not a child type of IParent.
+// 3. !emitError, calling into parent fails.
+// Return an error Return object if:
+// 1. emitError, calling into parent fails.
 template<typename IChild, typename IParent, typename BpChild, typename BpParent>
-sp<IChild> castInterface(sp<IParent> parent, const char *childIndicator) {
+Return<sp<IChild>> castInterface(sp<IParent> parent, const char *childIndicator, bool emitError) {
     if (parent.get() == nullptr) {
         // casts always succeed with nullptrs.
         return nullptr;
     }
-    bool canCast = details::canCastInterface(parent.get(), childIndicator);
+    Return<bool> canCastRet = details::canCastInterface(parent.get(), childIndicator, emitError);
+    if (!canCastRet.isOk()) {
+        // call fails, propagate the error if emitError
+        return emitError
+                ? details::StatusOf<bool, sp<IChild>>(canCastRet)
+                : Return<sp<IChild>>(sp<IChild>(nullptr));
+    }
 
-    if (!canCast) {
+    if (!canCastRet) {
         return sp<IChild>(nullptr); // cast failed.
     }
     // TODO b/32001926 Needs to be fixed for socket mode.
diff --git a/transport/include/hidl/HidlTransportUtils.h b/transport/include/hidl/HidlTransportUtils.h
index 0fe70c4..fbd6516 100644
--- a/transport/include/hidl/HidlTransportUtils.h
+++ b/transport/include/hidl/HidlTransportUtils.h
@@ -25,14 +25,17 @@
 
 /*
  * Verifies the interface chain of 'interface' contains 'castTo'
+ * @param emitError if emitError is false, return Return<bool>{false} on error; if emitError
+ * is true, the Return<bool> object contains the actual error.
  */
-inline bool canCastInterface(::android::hidl::base::V1_0::IBase* interface, const char* castTo) {
+inline Return<bool> canCastInterface(::android::hidl::base::V1_0::IBase* interface,
+        const char* castTo, bool emitError = false) {
     if (interface == nullptr) {
         return false;
     }
 
     bool canCast = false;
-    auto ret = interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
+    auto chainRet = interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
         for (size_t i = 0; i < types.size(); i++) {
             if (types[i] == castTo) {
                 canCast = true;
@@ -40,7 +43,15 @@
             }
         }
     });
-    return ret.isOk() && canCast;
+
+    if (!chainRet.isOk()) {
+        // call fails, propagate the error if emitError
+        return emitError
+                ? details::StatusOf<void, bool>(chainRet)
+                : Return<bool>(false);
+    }
+
+    return canCast;
 }
 
 inline std::string getDescriptor(::android::hidl::base::V1_0::IBase* interface) {
diff --git a/transport/include/hidl/LegacySupport.h b/transport/include/hidl/LegacySupport.h
index efe4d92..2f0c3f3 100644
--- a/transport/include/hidl/LegacySupport.h
+++ b/transport/include/hidl/LegacySupport.h
@@ -26,12 +26,6 @@
 namespace android {
 namespace hardware {
 
-namespace details {
-bool blockingHalBinderizationEnabled();
-void blockIfBinderizationDisabled(const std::string& interface,
-                                  const std::string& instance);
-} // namespace details
-
 /**
  * Registers passthrough service implementation.
  */
@@ -39,13 +33,6 @@
 __attribute__((warn_unused_result))
 status_t registerPassthroughServiceImplementation(
         std::string name = "default") {
-    // TODO(b/34274385)
-    // If binderization is enabled, we should start up. Otherwise, wait around.
-    // If we return/kill ourselves, we will just be restarted by init. This
-    // function is only called from thin wrapping services, so blocking won't
-    // stop anything important from happening.
-    details::blockIfBinderizationDisabled(Interface::descriptor, name);
-
     sp<Interface> service = Interface::getService(name, true /* getStub */);
 
     if (service == nullptr) {
diff --git a/transport/manager/1.0/IServiceManager.hal b/transport/manager/1.0/IServiceManager.hal
index 9e1c2fc..1a37c54 100644
--- a/transport/manager/1.0/IServiceManager.hal
+++ b/transport/manager/1.0/IServiceManager.hal
@@ -73,6 +73,22 @@
      */
     add(string name, interface service) generates (bool success);
 
+    enum Transport : uint8_t {
+        EMPTY,
+        HWBINDER,
+        PASSTHROUGH,
+    };
+
+    /**
+     * Get the transport of a service.
+     *
+     * @param fqName     Fully-qualified interface name.
+     * @param name       Instance name. Same as in IServiceManager::add
+     *
+     * @return transport Transport of service if known.
+     */
+    getTransport(string fqName, string name) generates (Transport transport);
+
     /**
      * List all registered services. Must be sorted.
      *
diff --git a/transport/token/1.0/ITokenManager.hal b/transport/token/1.0/ITokenManager.hal
index b1bb735..23a44bd 100644
--- a/transport/token/1.0/ITokenManager.hal
+++ b/transport/token/1.0/ITokenManager.hal
@@ -26,10 +26,12 @@
      * Register an interface. The server must keep a strong reference
      * to the interface until the token is destroyed by calling unregister.
      *
+     * Must return empty token on failure.
+     *
      * @param store Interface which can later be fetched with the returned token.
      * @return token Opaque value which may be used as inputs to other functions.
      */
-    createToken(interface store) generates (uint64_t token);
+    createToken(interface store) generates (vec<uint8_t>token);
 
     /**
      * Destory a token and the strong reference to the associated interface.
@@ -37,7 +39,7 @@
      * @param token Token received from createToken
      * @return success Whether or not the token was successfully unregistered.
      */
-    unregister(uint64_t token) generates (bool success);
+    unregister(vec<uint8_t> token) generates (bool success);
 
     /**
      * Fetch an interface from a provided token.
@@ -46,5 +48,5 @@
      * @return store Interface registered with createToken and the corresponding
      *               token or nullptr.
      */
-    get(uint64_t token) generates (interface store);
+    get(vec<uint8_t> token) generates (interface store);
 };
diff --git a/transport/token/1.0/utils/HybridInterface.cpp b/transport/token/1.0/utils/HybridInterface.cpp
index f28446e..106ad4e 100644
--- a/transport/token/1.0/utils/HybridInterface.cpp
+++ b/transport/token/1.0/utils/HybridInterface.cpp
@@ -89,19 +89,17 @@
 }
 
 bool createHalToken(const sp<HInterface>& interface, HalToken* token) {
-    hardware::Return<HalToken> transaction(false);
+    hardware::Return<void> transaction;
     {
         std::lock_guard<std::mutex> lock(gTokenManagerLock);
         if (isBadTokenManager()) {
             return false;
         }
-        transaction = gTokenManager->createToken(interface);
-        if (isBadTransaction(transaction)) {
-            return false;
-        }
+        transaction = gTokenManager->createToken(interface, [&](const HalToken &newToken) {
+            *token = newToken;
+        });
     }
-    *token = static_cast<HalToken>(transaction);
-    return true;
+    return !isBadTransaction(transaction);
 }
 
 bool deleteHalToken(const HalToken& token) {
diff --git a/transport/token/1.0/utils/include/hidl/HybridInterface.h b/transport/token/1.0/utils/include/hidl/HybridInterface.h
index 42d3734..8c3e742 100644
--- a/transport/token/1.0/utils/include/hidl/HybridInterface.h
+++ b/transport/token/1.0/utils/include/hidl/HybridInterface.h
@@ -96,7 +96,7 @@
 
 namespace android {
 
-typedef uint64_t HalToken;
+typedef ::android::hardware::hidl_vec<uint8_t> HalToken;
 typedef ::android::hidl::base::V1_0::IBase HInterface;
 
 constexpr uint32_t DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE =
@@ -247,7 +247,7 @@
             ALOGE("H2BConverter: Failed to create HAL token.");
         }
         reply->writeBool(result);
-        reply->writeUint64(token);
+        reply->writeByteArray(token.size(), token.data());
         return NO_ERROR;
     }
     return BNINTERFACE::onTransact(code, data, reply, flags);
@@ -313,7 +313,11 @@
     data.writeInterfaceToken(BaseInterface::getInterfaceDescriptor());
     if (mImpl->transact(GET_HAL_TOKEN, data, &reply) == NO_ERROR) {
         bool tokenCreated = reply.readBool();
-        HalToken token = reply.readUint64();
+
+        std::vector<uint8_t> tokenVector;
+        reply.readByteVector(&tokenVector);
+        HalToken token = HalToken(tokenVector);
+
         if (tokenCreated) {
             sp<HInterface> hBase = retrieveHalInterface(token);
             if (hBase != nullptr) {