Merge "thermal: typos in HAL."
diff --git a/nfc/1.0/vts/Nfc.vts b/nfc/1.0/vts/Nfc.vts
index 8c18653..1f50698 100644
--- a/nfc/1.0/vts/Nfc.vts
+++ b/nfc/1.0/vts/Nfc.vts
@@ -1,7 +1,6 @@
 component_class: HAL_HIDL
 component_type_version: 1.0
 component_name: "INfc"
-component_type: NFC
 
 package: "android.hardware.nfc"
 
diff --git a/nfc/1.0/vts/NfcClientCallback.vts b/nfc/1.0/vts/NfcClientCallback.vts
index e468935..e2a3e5b 100644
--- a/nfc/1.0/vts/NfcClientCallback.vts
+++ b/nfc/1.0/vts/NfcClientCallback.vts
@@ -1,7 +1,6 @@
 component_class: HAL_HIDL
 component_type_version: 1.0
 component_name: "INfcClientCallback"
-component_type: NFC
 
 package: "android.hardware.nfc"
 
diff --git a/nfc/1.0/vts/types.vts b/nfc/1.0/vts/types.vts
index f56ddf1..969a8af 100644
--- a/nfc/1.0/vts/types.vts
+++ b/nfc/1.0/vts/types.vts
@@ -1,7 +1,6 @@
 component_class: HAL_HIDL
 component_type_version: 1.0
 component_name: "types"
-component_type: NFC
 
 package: "android.hardware.nfc"
 
diff --git a/tests/baz/1.0/IBase.hal b/tests/baz/1.0/IBase.hal
index 3f18d41..add4153 100644
--- a/tests/baz/1.0/IBase.hal
+++ b/tests/baz/1.0/IBase.hal
@@ -76,6 +76,9 @@
 
     someMethodWithVectorOfArray(VectorOfArray in) generates (VectorOfArray out);
 
+    someMethodTakingAVectorOfArray(vec<MacAddress> in)
+        generates (vec<MacAddress> out);
+
     transpose(StringMatrix5x3 in) generates (StringMatrix3x5 out);
     transpose2(ThreeStrings[5] in) generates (FiveStrings[3] out);
 };
diff --git a/tests/foo/1.0/default/FooCallback.cpp b/tests/foo/1.0/default/FooCallback.cpp
index 08d3ce0..d3eef77 100644
--- a/tests/foo/1.0/default/FooCallback.cpp
+++ b/tests/foo/1.0/default/FooCallback.cpp
@@ -1,3 +1,6 @@
+
+#define LOG_TAG "hidl_test"
+
 #include "FooCallback.h"
 #include <android-base/logging.h>
 #include <inttypes.h>
@@ -9,68 +12,111 @@
 namespace V1_0 {
 namespace implementation {
 
+enum {
+    NOT_REPORTED = -1LL
+};
+
+FooCallback::FooCallback()
+        : mLock{}, mCond{} {
+    for (size_t i = 0; i < invokeInfo.size(); i++) {
+        invokeInfo[i].invoked = false;
+        invokeInfo[i].timeNs = NOT_REPORTED;
+        invokeInfo[i].callerBlockedNs = NOT_REPORTED;
+    }
+}
+
 Return<void> FooCallback::heyItsYou(
         const sp<IFooCallback> &_cb) {
     nsecs_t start = systemTime();
-    ALOGI("SERVER(FooCallback) heyItsYou cb = %p", _cb.get());
-    mLock.lock();
-    invokeInfo[0].invoked = true;
-    invokeInfo[0].timeNs = systemTime() - start;
-    mCond.signal();
-    mLock.unlock();
+    ALOGI("SERVER(FooCallback) 1: heyItsYou cb = %p", _cb.get());
+    nsecs_t end = systemTime();
+    {
+        Mutex::Autolock lock(mLock);
+        invokeInfo[0].invoked = true;
+        invokeInfo[0].timeNs = end - start;
+        mCond.signal();
+    }
+    ALOGI("SERVER(FooCallback) 2: heyItsYou returned");
     return Void();
 }
 
 Return<bool> FooCallback::heyItsYouIsntIt(const sp<IFooCallback> &_cb) {
     nsecs_t start = systemTime();
-    ALOGI("SERVER(FooCallback) heyItsYouIsntIt cb = %p sleeping for %" PRId64 " seconds", _cb.get(), DELAY_S);
+    ALOGI("SERVER(FooCallback) 3: heyItsYouIsntIt cb = %p sleeping for %" PRId64 " seconds", _cb.get(), DELAY_S);
     sleep(DELAY_S);
-    ALOGI("SERVER(FooCallback) heyItsYouIsntIt cb = %p responding", _cb.get());
-    mLock.lock();
-    invokeInfo[1].invoked = true;
-    invokeInfo[1].timeNs = systemTime() - start;
-    mCond.signal();
-    mLock.unlock();
+    ALOGI("SERVER(FooCallback) 4: heyItsYouIsntIt cb = %p responding", _cb.get());
+    nsecs_t end = systemTime();
+    {
+        Mutex::Autolock lock(mLock);
+        invokeInfo[1].invoked = true;
+        invokeInfo[1].timeNs = end - start;
+        mCond.signal();
+    }
+    ALOGI("SERVER(FooCallback) 5: heyItsYouIsntIt cb = %p responding", _cb.get());
     return true;
 }
 
 Return<void> FooCallback::heyItsTheMeaningOfLife(uint8_t tmol) {
     nsecs_t start = systemTime();
-    ALOGI("SERVER(FooCallback) heyItsTheMeaningOfLife = %d sleeping for %" PRId64 " seconds", tmol, DELAY_S);
+    ALOGI("SERVER(FooCallback) 6.1: heyItsTheMeaningOfLife = %d sleeping for %" PRId64 " seconds", tmol, DELAY_S);
     sleep(DELAY_S);
-    ALOGI("SERVER(FooCallback) heyItsTheMeaningOfLife = %d done sleeping", tmol);
-    mLock.lock();
-    invokeInfo[2].invoked = true;
-    invokeInfo[2].timeNs = systemTime() - start;
-    mCond.signal();
-    mLock.unlock();
+    ALOGI("SERVER(FooCallback) 6.2: heyItsTheMeaningOfLife = %d done sleeping", tmol);
+    nsecs_t end = systemTime();
+    {
+        Mutex::Autolock lock(mLock);
+        invokeInfo[2].invoked = true;
+        invokeInfo[2].timeNs = end - start;
+        mCond.signal();
+    }
+    ALOGI("SERVER(FooCallback) 6.3: heyItsTheMeaningOfLife returned");
     return Void();
 }
 
 Return<void> FooCallback::reportResults(int64_t ns, reportResults_cb cb) {
-    ALOGI("SERVER(FooCallback) reportResults(%" PRId64 " seconds)", nanoseconds_to_seconds(ns));
+    ALOGI("SERVER(FooCallback) 8.1: reportResults(%" PRId64 " seconds)", nanoseconds_to_seconds(ns));
     nsecs_t leftToWaitNs = ns;
-    mLock.lock();
-    while (!(invokeInfo[0].invoked && invokeInfo[1].invoked && invokeInfo[2].invoked) &&
-           leftToWaitNs > 0) {
-      nsecs_t start = systemTime();
-      ::android::status_t rc = mCond.waitRelative(mLock, leftToWaitNs);
-      if (rc != ::android::OK) {
-          ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 " ns) Condition::waitRelative(%" PRId64 ") returned error (%d)", ns, leftToWaitNs, rc);
-          break;
-      }
-      ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 " ns) Condition::waitRelative was signalled", ns);
-      leftToWaitNs -= systemTime() - start;
+    bool cond;
+    {
+        Mutex::Autolock lock(mLock);
+        while ((cond = ((!invokeInfo[0].invoked ||
+                !invokeInfo[1].invoked ||
+                !invokeInfo[2].invoked ||
+                invokeInfo[0].callerBlockedNs == NOT_REPORTED ||
+                invokeInfo[1].callerBlockedNs == NOT_REPORTED ||
+                invokeInfo[2].callerBlockedNs == NOT_REPORTED)   &&
+               leftToWaitNs > 0))) {
+            nsecs_t start = systemTime();
+            ::android::status_t rc = mCond.waitRelative(mLock, leftToWaitNs);
+            if (rc != ::android::OK) {
+                ALOGW("SERVER(FooCallback)::reportResults(%" PRId64 " ns) Condition::waitRelative(%" PRId64 ") returned error (%d)", ns, leftToWaitNs, rc);
+                if (rc == -ETIMEDOUT) {
+                    // time's up
+                    leftToWaitNs = -1;
+                }
+                break;
+            }
+            ALOGI("SERVER(FooCallback)::reportResults(%" PRId64 " ns) Condition::waitRelative was signalled", ns);
+            leftToWaitNs -= systemTime() - start;
+        }
     }
-    mLock.unlock();
+    ALOGI("SERVER(FooCallback) 8.2: reportResults returned;"
+            "invoked? %d, %d, %d; leftToWaitNs = %" PRId64 "; cond = %d",
+            invokeInfo[0].invoked, invokeInfo[1].invoked, invokeInfo[2].invoked,
+            leftToWaitNs, cond);
     cb(leftToWaitNs, invokeInfo);
     return Void();
 }
 
 Return<void> FooCallback::youBlockedMeFor(const hidl_array<int64_t, 3> &ns) {
-    for (size_t i = 0; i < 3; i++) {
-        invokeInfo[i].callerBlockedNs = ns[i];
+    ALOGI("SERVER(FooCallback) 7.1: youBlockedMeFor");
+    {
+        Mutex::Autolock lock(mLock);
+        for (size_t i = 0; i < 3; i++) {
+            invokeInfo[i].callerBlockedNs = ns[i];
+        }
+        mCond.signal();
     }
+    ALOGI("SERVER(FooCallback) 7.2: returned");
     return Void();
 }
 
diff --git a/tests/foo/1.0/default/FooCallback.h b/tests/foo/1.0/default/FooCallback.h
index 6c284ca..5921972 100644
--- a/tests/foo/1.0/default/FooCallback.h
+++ b/tests/foo/1.0/default/FooCallback.h
@@ -22,7 +22,7 @@
 using ::android::sp;
 
 struct FooCallback : public IFooCallback {
-    FooCallback() : mLock{}, mCond{} {}
+    FooCallback();
     // Methods from ::android::hardware::tests::foo::V1_0::IFooCallback follow.
     Return<void> heyItsYou(const sp<IFooCallback>& cb)  override;
     Return<bool> heyItsYouIsntIt(const sp<IFooCallback>& cb)  override;
diff --git a/vibrator/1.0/vts/Android.mk b/vibrator/1.0/vts/Android.mk
new file mode 100644
index 0000000..cb70548
--- /dev/null
+++ b/vibrator/1.0/vts/Android.mk
@@ -0,0 +1,55 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# build VTS driver for Vibrator v1.0.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libvts_driver_hidl_vibrator@1.0
+
+LOCAL_SRC_FILES := \
+  Vibrator.vts \
+  types.vts \
+
+LOCAL_C_INCLUDES := \
+  android.hardware.vibrator@1.0 \
+  system/core/base/include \
+  system/core/include \
+
+LOCAL_SHARED_LIBRARIES += \
+  android.hardware.vibrator@1.0 \
+  libbase \
+  libutils \
+  libcutils \
+  liblog \
+  libhidl \
+  libhwbinder \
+  libprotobuf-cpp-full \
+  libvts_common \
+  libvts_datatype \
+  libvts_measurement \
+  libvts_multidevice_proto \
+
+LOCAL_CFLAGS += -DENABLE_TREBLE
+
+LOCAL_STATIC_LIBRARIES := \
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+
+LOCAL_MULTILIB := both
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/vibrator/1.0/vts/Vibrator.vts b/vibrator/1.0/vts/Vibrator.vts
new file mode 100644
index 0000000..f1ab053
--- /dev/null
+++ b/vibrator/1.0/vts/Vibrator.vts
@@ -0,0 +1,30 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "IVibrator"
+
+package: "android.hardware.vibrator"
+
+import: "android.hardware.vibrator@1.0::types"
+
+interface: {
+    api: {
+        name: "on"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "Status"
+        }
+        arg: {
+            type: TYPE_SCALAR
+            scalar_type: "uint32_t"
+        }
+    }
+
+    api: {
+        name: "off"
+        return_type_hidl: {
+            type: TYPE_ENUM
+            predefined_type: "Status"
+        }
+    }
+
+}
diff --git a/vibrator/1.0/vts/types.vts b/vibrator/1.0/vts/types.vts
new file mode 100644
index 0000000..0eba051
--- /dev/null
+++ b/vibrator/1.0/vts/types.vts
@@ -0,0 +1,24 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "types"
+
+package: "android.hardware.vibrator"
+
+
+attribute: {
+    name: "Status"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint32_t"
+
+        enumerator: "OK"
+        scalar_value: {
+            uint32_t: 0
+        }
+        enumerator: "ERR"
+        scalar_value: {
+            uint32_t: 1
+        }
+    }
+}
+