Merge "Update IMemory.hal comments."
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 1a4fd3c..1b0184a 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -382,6 +382,24 @@
         return v;
     }
 
+    // equality check, assuming that T::operator== is defined.
+    bool operator==(const hidl_vec &other) const {
+        if (mSize != other.size()) {
+            return false;
+        }
+        for (size_t i = 0; i < mSize; ++i) {
+            if (!(mBuffer[i] == other.mBuffer[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // inequality check, assuming that T::operator== is defined.
+    inline bool operator!=(const hidl_vec &other) const {
+        return !((*this) == other);
+    }
+
     size_t size() const {
         return mSize;
     }
@@ -649,6 +667,20 @@
                 &mBuffer[index * details::product<SIZES...>::value]);
     }
 
+    // equality check, assuming that T::operator== is defined.
+    bool operator==(const hidl_array &other) const {
+        for (size_t i = 0; i < elementCount(); ++i) {
+            if (!(mBuffer[i] == other.mBuffer[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    inline bool operator!=(const hidl_array &other) const {
+        return !((*this) == other);
+    }
+
     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
 
     static constexpr size_tuple_type size() {
@@ -696,6 +728,20 @@
         return mBuffer[index];
     }
 
+    // equality check, assuming that T::operator== is defined.
+    bool operator==(const hidl_array &other) const {
+        for (size_t i = 0; i < elementCount(); ++i) {
+            if (!(mBuffer[i] == other.mBuffer[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    inline bool operator!=(const hidl_array &other) const {
+        return !((*this) == other);
+    }
+
     static constexpr size_t size() { return SIZE1; }
     static constexpr size_t elementCount() { return SIZE1; }
 
diff --git a/base/include/hidl/MQDescriptor.h b/base/include/hidl/MQDescriptor.h
index ebd0911..8043761 100644
--- a/base/include/hidl/MQDescriptor.h
+++ b/base/include/hidl/MQDescriptor.h
@@ -56,8 +56,9 @@
             native_handle_t* nHandle, size_t size);
 
     MQDescriptor(size_t bufferSize, native_handle_t* nHandle,
-                 size_t messageSize);
+                 size_t messageSize, bool configureEventFlag = false);
 
+    MQDescriptor();
     ~MQDescriptor();
 
     explicit MQDescriptor(const MQDescriptor &other);
@@ -92,12 +93,20 @@
 
     static const size_t kOffsetOfGrantors;
     static const size_t kOffsetOfHandle;
+    enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS, EVFLAGWORDPOS };
+
     /*
-     * There should atleast be GrantorDescriptors for the read counter, write
-     * counter and data buffer.
+     * There should at least be GrantorDescriptors for the read counter, write
+     * counter and data buffer. A GrantorDescriptor for an EventFlag word is
+     * not required if there is no need for blocking FMQ operations.
      */
-    static constexpr int32_t kMinGrantorCount = 3;
-    enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS };
+    static constexpr int32_t kMinGrantorCount = DATAPTRPOS + 1;
+
+    /*
+     * Minimum number of GrantorDescriptors required if EventFlag support is
+     * needed for blocking FMQ operations.
+     */
+    static constexpr int32_t kMinGrantorCountForEvFlagSupport = EVFLAGWORDPOS + 1;
 private:
     ::android::hardware::hidl_vec<GrantorDescriptor> mGrantors;
     ::android::hardware::details::hidl_pointer<native_handle_t> mHandle;
@@ -139,29 +148,36 @@
 
 template<MQFlavor flavor>
 MQDescriptor<flavor>::MQDescriptor(size_t bufferSize, native_handle_t *nHandle,
-                           size_t messageSize)
+                                   size_t messageSize, bool configureEventFlag)
     : mHandle(nHandle), mQuantum(messageSize), mFlags(flavor) {
-    mGrantors.resize(kMinGrantorCount);
+    /*
+     * If configureEventFlag is true, allocate an additional spot in mGrantor
+     * for containing the fd and offset for mmapping the EventFlag word.
+     */
+    mGrantors.resize(configureEventFlag? kMinGrantorCountForEvFlagSupport : kMinGrantorCount);
+
+    size_t memSize[] = {
+        sizeof(RingBufferPosition),  /* memory to be allocated for read pointer counter */
+        sizeof(RingBufferPosition),  /* memory to be allocated for write pointer counter */
+        bufferSize,                  /* memory to be allocated for data buffer */
+        sizeof(std::atomic<uint32_t>)/* memory to be allocated for EventFlag word */
+    };
+
     /*
      * Create a default grantor descriptor for read, write pointers and
      * the data buffer. fdIndex parameter is set to 0 by default and
      * the offset for each grantor is contiguous.
      */
-    mGrantors[READPTRPOS] = {
-        0 /* grantor flags */, 0 /* fdIndex */, 0 /* offset */,
-        sizeof(RingBufferPosition) /* extent */
-    };
-
-    mGrantors[WRITEPTRPOS] = {
-        0 /* grantor flags */,
-        0 /* fdIndex */,
-        sizeof(RingBufferPosition) /* offset */,
-        sizeof(RingBufferPosition) /* extent */
-    };
-    mGrantors[DATAPTRPOS] = {
-        0 /* grantor flags */, 0 /* fdIndex */,
-        2 * sizeof(RingBufferPosition) /* offset */, bufferSize /* extent */
-    };
+    for (size_t grantorPos = 0, offset = 0;
+         grantorPos < mGrantors.size();
+         offset += memSize[grantorPos++]) {
+        mGrantors[grantorPos] = {
+            0 /* grantor flags */,
+            0 /* fdIndex */,
+            static_cast<uint32_t>(offset),
+            memSize[grantorPos]
+        };
+    }
 }
 
 template<MQFlavor flavor>
@@ -185,6 +201,12 @@
 }
 
 template<MQFlavor flavor>
+MQDescriptor<flavor>::MQDescriptor() : MQDescriptor(
+        std::vector<android::hardware::GrantorDescriptor>(),
+        nullptr /* nHandle */,
+        0 /* size */) {}
+
+template<MQFlavor flavor>
 MQDescriptor<flavor>::~MQDescriptor() {
     if (mHandle != nullptr) {
         native_handle_close(mHandle);
diff --git a/test_main.cpp b/test_main.cpp
index ca5d017..bdf4b49 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -189,6 +189,16 @@
     EXPECT_EQ(sum, 15+16+17);
 }
 
+TEST_F(LibHidlTest, VecEqTest) {
+    android::hardware::hidl_vec<int32_t> hv1{5, 6, 7};
+    android::hardware::hidl_vec<int32_t> hv2{5, 6, 7};
+    android::hardware::hidl_vec<int32_t> hv3{5, 6, 8};
+
+    // use the == and != operator intentionally here
+    EXPECT_TRUE(hv1 == hv2);
+    EXPECT_TRUE(hv1 != hv3);
+}
+
 TEST_F(LibHidlTest, ArrayTest) {
     using android::hardware::hidl_array;
     int32_t array[] = {5, 6, 7};
diff --git a/transport/Android.bp b/transport/Android.bp
index 5614ffb..9b0fe2c 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -13,10 +13,11 @@
 // limitations under the License.
 
 subdirs = [
+    "base/1.0",
     "manager/1.0",
     "memory/1.0",
     "memory/1.0/default",
-    "base/1.0"
+    "token/1.0",
 ]
 
 cc_library_shared {
diff --git a/transport/memory/1.0/default/Android.bp b/transport/memory/1.0/default/Android.bp
index 4bc24a2..2b89f07 100644
--- a/transport/memory/1.0/default/Android.bp
+++ b/transport/memory/1.0/default/Android.bp
@@ -16,7 +16,6 @@
     name: "android.hidl.memory@1.0-impl",
     relative_install_path: "hw",
     srcs: [
-        "AshmemAllocator.cpp",
         "AshmemMapper.cpp",
         "AshmemMemory.cpp",
         "HidlFetch.cpp"
@@ -39,7 +38,10 @@
 cc_binary {
     name: "android.hidl.memory@1.0-service",
     relative_install_path: "hw",
-    srcs: ["service.cpp"],
+    srcs: [
+        "AshmemAllocator.cpp",
+        "service.cpp"
+    ],
     init_rc: ["android.hidl.memory@1.0-service.rc"],
 
     shared_libs: [
@@ -48,8 +50,10 @@
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
+        "libbase",
         "liblog",
         "libutils",
+        "libcutils",
     ],
 
     required: [
diff --git a/transport/memory/1.0/default/HidlFetch.cpp b/transport/memory/1.0/default/HidlFetch.cpp
index 8236055..adb55d3 100644
--- a/transport/memory/1.0/default/HidlFetch.cpp
+++ b/transport/memory/1.0/default/HidlFetch.cpp
@@ -27,14 +27,6 @@
 namespace V1_0 {
 namespace implementation {
 
-IAllocator* HIDL_FETCH_IAllocator(const char* name) {
-    if (name == kAshmemMemoryName) {
-        return new AshmemAllocator;
-    }
-
-    return nullptr;
-}
-
 IMapper* HIDL_FETCH_IMapper(const char* name) {
     if (name == kAshmemMemoryName) {
         return new AshmemMapper;
diff --git a/transport/memory/1.0/default/HidlFetch.h b/transport/memory/1.0/default/HidlFetch.h
index a9d366f..389ca30 100644
--- a/transport/memory/1.0/default/HidlFetch.h
+++ b/transport/memory/1.0/default/HidlFetch.h
@@ -26,9 +26,6 @@
 namespace V1_0 {
 namespace implementation {
 
-// TODO: disable passthrough allocator. It's much better if it's in a centralized location
-extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* name);
-
 extern "C" IMapper* HIDL_FETCH_IMapper(const char* name);
 
 }  // namespace implementation
diff --git a/transport/memory/1.0/default/service.cpp b/transport/memory/1.0/default/service.cpp
index ff3a8e8..8ea8b8a 100644
--- a/transport/memory/1.0/default/service.cpp
+++ b/transport/memory/1.0/default/service.cpp
@@ -1,12 +1,31 @@
 #define LOG_TAG "android.hidl.memory@1.0-service"
 
+#include "AshmemAllocator.h"
+
+#include <android-base/logging.h>
 #include <android/hidl/memory/1.0/IAllocator.h>
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
 
-#include <hidl/LegacySupport.h>
-
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
 using android::hidl::memory::V1_0::IAllocator;
-using android::hardware::defaultPassthroughServiceImplementation;
+using android::hidl::memory::V1_0::implementation::AshmemAllocator;
+using android::sp;
+using android::status_t;
 
 int main() {
-    return defaultPassthroughServiceImplementation<IAllocator>("ashmem");
+    sp<IAllocator> allocator = new AshmemAllocator();
+
+    status_t status = allocator->registerAsService("ashmem");
+
+    if (android::OK != status) {
+        LOG(FATAL) << "Unable to register allocator service: " << status;
+    }
+
+    ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+
+    return -1;
 }
diff --git a/transport/token/1.0/Android.bp b/transport/token/1.0/Android.bp
new file mode 100644
index 0000000..0ebe1e4
--- /dev/null
+++ b/transport/token/1.0/Android.bp
@@ -0,0 +1,52 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hidl.token@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hidl:system/libhidl/transport android.hidl.token@1.0",
+    srcs: [
+        "ITokenManager.hal",
+    ],
+    out: [
+        "android/hidl/token/1.0/TokenManagerAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hidl.token@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hidl:system/libhidl/transport android.hidl.token@1.0",
+    srcs: [
+        "ITokenManager.hal",
+    ],
+    out: [
+        "android/hidl/token/1.0/ITokenManager.h",
+        "android/hidl/token/1.0/IHwTokenManager.h",
+        "android/hidl/token/1.0/BnTokenManager.h",
+        "android/hidl/token/1.0/BpTokenManager.h",
+        "android/hidl/token/1.0/BsTokenManager.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hidl.token@1.0",
+    generated_sources: ["android.hidl.token@1.0_genc++"],
+    generated_headers: ["android.hidl.token@1.0_genc++_headers"],
+    export_generated_headers: ["android.hidl.token@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/transport/token/1.0/Android.mk b/transport/token/1.0/Android.mk
new file mode 100644
index 0000000..3d07671
--- /dev/null
+++ b/transport/token/1.0/Android.mk
@@ -0,0 +1,76 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hidl.token@1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hidl.base@1.0-java \
+
+
+#
+# Build ITokenManager.hal
+#
+GEN := $(intermediates)/android/hidl/token/V1_0/ITokenManager.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ITokenManager.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hidl:system/libhidl/transport \
+        -randroid.hidl:system/libhidl/transport \
+        android.hidl.token@1.0::ITokenManager
+
+$(GEN): $(LOCAL_PATH)/ITokenManager.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hidl.token@1.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hidl.base@1.0-java-static \
+
+
+#
+# Build ITokenManager.hal
+#
+GEN := $(intermediates)/android/hidl/token/V1_0/ITokenManager.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ITokenManager.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hidl:system/libhidl/transport \
+        -randroid.hidl:system/libhidl/transport \
+        android.hidl.token@1.0::ITokenManager
+
+$(GEN): $(LOCAL_PATH)/ITokenManager.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/transport/token/1.0/ITokenManager.hal b/transport/token/1.0/ITokenManager.hal
new file mode 100644
index 0000000..dc4134a
--- /dev/null
+++ b/transport/token/1.0/ITokenManager.hal
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package android.hidl.token@1.0;
+
+/**
+ * This facilitates converting hidl interfaces into something that
+ * are more easily transferrable to other processes.
+ */
+interface ITokenManager {
+
+    /**
+     * Register an interface. The server must only keep a weak reference
+     * to the token. The lifetime of the token is thus linked to the
+     * lifetime of the stored interface.
+     *
+     * @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);
+
+    /**
+     * Explicitly unregister an interface. If the server still holds a weak reference
+     * to an interface, but that interface interface is deleted and the reference
+     * cannot be promoted, then success must be false.
+     *
+     * @param token Token recieved from createToken
+     * @return success Whether or not an interface was successfully unregistered.
+     */
+    unregister(uint64_t token) generates (bool success);
+
+    /**
+     * Fetches an interface from a provided token.
+     *
+     * @param token Token recieved from createToken
+     * @return store Interface registered with createToken and the corresponding
+     *               token or nullptr.
+     */
+    get(uint64_t token) generates (interface store);
+};
diff --git a/update-makefiles.sh b/update-makefiles.sh
index 6a77a7d..3cd1cd2 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -6,14 +6,15 @@
   exit 1;
 fi
 
-#base
-hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.base@1.0
-hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.base@1.0
+packages=(
+    android.hidl.base@1.0
+    android.hidl.manager@1.0
+    android.hidl.memory@1.0
+    android.hidl.token@1.0
+)
 
-#manager
-hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.manager@1.0
-hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.manager@1.0
-
-#memory
-hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.memory@1.0
-hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.memory@1.0
+for package in "${packages[@]}"; do
+    echo "Updating $package."
+    hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport $package
+    hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport $package
+done