Merge "Write VTS target test for Configstore HAL" into oc-dev
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index bf16a9b..c4f935b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -28,6 +28,25 @@
 
 namespace impl {
 
+/*
+ * This property is used for test purpose to generate fake events.
+ *
+ * It has the following format:
+ *
+ * int32Values[0] - command (1 - start fake data generation, 0 - stop)
+ * int32Values[1] - VehicleProperty to which command applies
+ *
+ * For start command, additional data should be provided:
+ *   int64Values[0] - periodic interval in nanoseconds
+ *   floatValues[0] - initial value
+ *   floatValues[1] - dispersion defines min and max range relative to initial value
+ *   floatValues[2] - increment, with every timer tick the value will be incremented by this amount
+ */
+const int32_t kGenerateFakeDataControllingProperty = 0x0666
+        | VehiclePropertyGroup::VENDOR
+        | VehicleArea::GLOBAL
+        | VehiclePropertyType::COMPLEX;
+
 const int32_t kHvacPowerProperties[] = {
     toInt(VehicleProperty::HVAC_FAN_SPEED),
     toInt(VehicleProperty::HVAC_FAN_DIRECTION),
@@ -64,6 +83,24 @@
 
     {
         .config = {
+            .prop = toInt(VehicleProperty::PERF_ODOMETER),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .floatValues = {0.0f} }
+    },
+
+    {
+        .config = {
+            .prop = toInt(VehicleProperty::ENGINE_RPM),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+        },
+        .initialValue = { .floatValues = {0.0f} }
+    },
+
+    {
+        .config = {
             .prop = toInt(VehicleProperty::CURRENT_GEAR),
             .access = VehiclePropertyAccess::READ,
             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -284,6 +321,14 @@
             .maxSampleRate = 10,  // 10 Hz, every 100 ms
         },
         .initialValue = { .floatValues = {101.0f} }
+    },
+
+    {
+        .config = {
+            .prop = kGenerateFakeDataControllingProperty,
+            .access = VehiclePropertyAccess::WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
     }
 };
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 0ac6ada..ea40cc5 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -27,11 +27,18 @@
 
 namespace impl {
 
+enum class FakeDataCommand : int32_t {
+    Stop = 0,
+    Start = 1,
+};
+
 EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore)
     : mPropStore(propStore),
       mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)),
       mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer,
-                                  this, std::placeholders::_1)) {
+                                  this, std::placeholders::_1)),
+      mFakeValueGenerator(std::bind(&EmulatedVehicleHal::onFakeValueGenerated,
+                                    this, std::placeholders::_1, std::placeholders::_2)) {
 
     for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
         mPropStore->registerProperty(kVehicleProperties[i].config);
@@ -52,6 +59,10 @@
 }
 
 StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) {
+    if (propValue.prop == kGenerateFakeDataControllingProperty) {
+        return handleGenerateFakeDataRequest(propValue);
+    };
+
     if (mHvacPowerProps.count(propValue.prop)) {
         auto hvacPowerOn = mPropStore->readValueOrNull(toInt(VehicleProperty::HVAC_POWER_ON),
                                                       toInt(VehicleAreaZone::ROW_1));
@@ -176,6 +187,81 @@
     return mPropStore->readAllValues();
 }
 
+StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
+    ALOGI("%s", __func__);
+    const auto& v = request.value;
+    if (v.int32Values.size() < 2) {
+        ALOGE("%s: expected at least 2 elements in int32Values, got: %zu", __func__,
+                v.int32Values.size());
+        return StatusCode::INVALID_ARG;
+    }
+
+    FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]);
+    int32_t propId = v.int32Values[1];
+
+    switch (command) {
+        case FakeDataCommand::Start: {
+            if (!v.int64Values.size()) {
+                ALOGE("%s: interval is not provided in int64Values", __func__);
+                return StatusCode::INVALID_ARG;
+            }
+            auto interval = std::chrono::nanoseconds(v.int64Values[0]);
+
+            if (v.floatValues.size() < 3) {
+                ALOGE("%s: expected at least 3 element sin floatValues, got: %zu", __func__,
+                        v.floatValues.size());
+                return StatusCode::INVALID_ARG;
+            }
+            float initialValue = v.floatValues[0];
+            float dispersion = v.floatValues[1];
+            float increment = v.floatValues[2];
+
+            ALOGI("%s, propId: %d, initalValue: %f", __func__, propId, initialValue);
+            mFakeValueGenerator.startGeneratingHalEvents(
+                interval, propId, initialValue, dispersion, increment);
+
+            break;
+        }
+        case FakeDataCommand::Stop: {
+            ALOGI("%s, FakeDataCommandStop", __func__);
+            mFakeValueGenerator.stopGeneratingHalEvents(propId);
+            break;
+        }
+        default: {
+            ALOGE("%s: unexpected command: %d", __func__, command);
+            return StatusCode::INVALID_ARG;
+        }
+    }
+    return StatusCode::OK;
+}
+
+void EmulatedVehicleHal::onFakeValueGenerated(int32_t propId, float value) {
+    VehiclePropValuePtr updatedPropValue {};
+    switch (getPropType(propId)) {
+        case VehiclePropertyType::FLOAT:
+            updatedPropValue = getValuePool()->obtainFloat(value);
+            break;
+        case VehiclePropertyType::INT32:
+            updatedPropValue = getValuePool()->obtainInt32(static_cast<int32_t>(value));
+            break;
+        default:
+            ALOGE("%s: data type for property: 0x%x not supported", __func__, propId);
+            return;
+
+    }
+
+    if (updatedPropValue) {
+        updatedPropValue->prop = propId;
+        updatedPropValue->areaId = 0;  // Add area support if necessary.
+        updatedPropValue->timestamp = elapsedRealtimeNano();
+        mPropStore->writeValue(*updatedPropValue);
+        auto changeMode = mPropStore->getConfigOrDie(propId)->changeMode;
+        if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) {
+            doHalEvent(move(updatedPropValue));
+        }
+    }
+}
+
 }  // impl
 
 }  // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index e0874e2..009485d 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -34,6 +34,7 @@
 #include "DefaultConfig.h"
 #include "VehicleHalProto.pb.h"
 #include "VehicleEmulator.h"
+#include "FakeValueGenerator.h"
 
 namespace android {
 namespace hardware {
@@ -67,6 +68,9 @@
         return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
     }
 
+    StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request);
+    void onFakeValueGenerated(int32_t propId, float value);
+
     void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
     bool isContinuousProperty(int32_t propId) const;
 
@@ -74,6 +78,7 @@
     VehiclePropertyStore* mPropStore;
     std::unordered_set<int32_t> mHvacPowerProps;
     RecurrentTimer mRecurrentTimer;
+    FakeValueGenerator mFakeValueGenerator;
 };
 
 }  // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h
new file mode 100644
index 0000000..7bbbb08
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
+
+#include <chrono>
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+
+#include <vhal_v2_0/RecurrentTimer.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+class FakeValueGenerator {
+private:
+    // In every timer tick we may want to generate new value based on initial value for debug
+    // purpose. It's better to have sequential values to see if events gets delivered in order
+    // to the client.
+
+    struct GeneratorCfg {
+        float initialValue;  //
+        float currentValue;  //  Should be in range (initialValue +/- dispersion).
+        float dispersion;    //  Defines minimum and maximum value based on initial value.
+        float increment;     //  Value that we will be added to currentValue with each timer tick.
+    };
+
+public:
+    using OnHalEvent = std::function<void(int32_t propId, float value)>;
+
+    FakeValueGenerator(const OnHalEvent& onHalEvent) :
+        mOnHalEvent(onHalEvent),
+        mRecurrentTimer(std::bind(&FakeValueGenerator::onTimer, this,
+                                  std::placeholders::_1))
+    {}
+
+    ~FakeValueGenerator() = default;
+
+
+    void startGeneratingHalEvents(std::chrono::nanoseconds interval, int propId, float initialValue,
+                                  float dispersion, float increment) {
+        MuxGuard g(mLock);
+
+        removeLocked(propId);
+
+        mGenCfg.insert({propId, GeneratorCfg {
+            .initialValue = initialValue,
+            .currentValue = initialValue,
+            .dispersion = dispersion,
+            .increment = increment,
+        }});
+
+        mRecurrentTimer.registerRecurrentEvent(interval, propId);
+    }
+
+    void stopGeneratingHalEvents(int propId) {
+        MuxGuard g(mLock);
+        if (propId == 0) {
+            // Remove all.
+            for (auto&& it : mGenCfg) {
+                removeLocked(it.first);
+            }
+        } else {
+            removeLocked(propId);
+        }
+    }
+
+private:
+    void removeLocked(int propId) {
+        if (mGenCfg.erase(propId)) {
+            mRecurrentTimer.unregisterRecurrentEvent(propId);
+        }
+    }
+
+    void onTimer(const std::vector<int32_t>& properties) {
+        MuxGuard g(mLock);
+
+        for (int32_t propId : properties) {
+            auto& cfg = mGenCfg[propId];
+            cfg.currentValue += cfg.increment;
+            if (cfg.currentValue > cfg.initialValue + cfg.dispersion) {
+                cfg.currentValue = cfg.initialValue - cfg.dispersion;
+            }
+            mOnHalEvent(propId, cfg.currentValue);
+        }
+    }
+
+private:
+    using MuxGuard = std::lock_guard<std::mutex>;
+
+    mutable std::mutex mLock;
+    OnHalEvent mOnHalEvent;
+    RecurrentTimer mRecurrentTimer;
+    std::unordered_map<int32_t, GeneratorCfg> mGenCfg;
+};
+
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+
+
+#endif //android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_
diff --git a/bluetooth/1.0/default/Android.mk b/bluetooth/1.0/default/Android.mk
index 7530925..38294c7 100644
--- a/bluetooth/1.0/default/Android.mk
+++ b/bluetooth/1.0/default/Android.mk
@@ -29,7 +29,6 @@
   libdl \
   libbase \
   libutils \
-  libhardware_legacy \
   libhardware \
 
 LOCAL_SHARED_LIBRARIES += \
diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk
index 538a6b2..917bfe0 100644
--- a/contexthub/1.0/default/Android.mk
+++ b/contexthub/1.0/default/Android.mk
@@ -13,7 +13,6 @@
         libcutils \
         libdl \
         libhardware \
-        libhardware_legacy \
         libhidlbase \
         libhidltransport \
         liblog \
diff --git a/gnss/1.0/default/Android.mk b/gnss/1.0/default/Android.mk
index dd0ebe9..34da64e 100644
--- a/gnss/1.0/default/Android.mk
+++ b/gnss/1.0/default/Android.mk
@@ -45,7 +45,6 @@
     libdl \
     libbase \
     libutils \
-    libhardware_legacy \
     libhardware \
     libbinder \
 
diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk
index c537346..9df5bf8 100644
--- a/keymaster/3.0/default/Android.mk
+++ b/keymaster/3.0/default/Android.mk
@@ -34,7 +34,6 @@
     libdl \
     libbase \
     libutils \
-    libhardware_legacy \
     libhardware \
     libhidlbase \
     libhidltransport \
diff --git a/light/2.0/default/Android.mk b/light/2.0/default/Android.mk
index 3439c9b..1f44e66 100644
--- a/light/2.0/default/Android.mk
+++ b/light/2.0/default/Android.mk
@@ -34,7 +34,6 @@
     libdl \
     libbase \
     libutils \
-    libhardware_legacy \
     libhardware \
 
 LOCAL_SHARED_LIBRARIES += \
diff --git a/nfc/1.0/default/Android.mk b/nfc/1.0/default/Android.mk
index 2e1f17f..4afad74 100644
--- a/nfc/1.0/default/Android.mk
+++ b/nfc/1.0/default/Android.mk
@@ -14,7 +14,6 @@
 	libdl \
 	libbase \
 	libutils \
-	libhardware_legacy \
 	libhardware \
 
 LOCAL_SHARED_LIBRARIES += \
diff --git a/sensors/1.0/default/Android.mk b/sensors/1.0/default/Android.mk
index bc1cfbd..d114542 100644
--- a/sensors/1.0/default/Android.mk
+++ b/sensors/1.0/default/Android.mk
@@ -14,8 +14,6 @@
         libdl \
         libbase \
         libutils \
-        libhardware_legacy \
-        libhardware \
 
 LOCAL_SHARED_LIBRARIES += \
         libhidlbase \
diff --git a/tests/libhwbinder/1.0/Android.bp b/tests/libhwbinder/1.0/Android.bp
index 9c0fe45..e8d28a3 100644
--- a/tests/libhwbinder/1.0/Android.bp
+++ b/tests/libhwbinder/1.0/Android.bp
@@ -4,6 +4,7 @@
     name: "android.hardware.tests.libhwbinder@1.0_hal",
     srcs: [
         "IBenchmark.hal",
+        "IScheduleTest.hal",
     ],
 }
 
@@ -16,6 +17,7 @@
     ],
     out: [
         "android/hardware/tests/libhwbinder/1.0/BenchmarkAll.cpp",
+        "android/hardware/tests/libhwbinder/1.0/ScheduleTestAll.cpp",
     ],
 }
 
@@ -32,6 +34,11 @@
         "android/hardware/tests/libhwbinder/1.0/BnHwBenchmark.h",
         "android/hardware/tests/libhwbinder/1.0/BpHwBenchmark.h",
         "android/hardware/tests/libhwbinder/1.0/BsBenchmark.h",
+        "android/hardware/tests/libhwbinder/1.0/IScheduleTest.h",
+        "android/hardware/tests/libhwbinder/1.0/IHwScheduleTest.h",
+        "android/hardware/tests/libhwbinder/1.0/BnHwScheduleTest.h",
+        "android/hardware/tests/libhwbinder/1.0/BpHwScheduleTest.h",
+        "android/hardware/tests/libhwbinder/1.0/BsScheduleTest.h",
     ],
 }
 
diff --git a/tests/libhwbinder/1.0/Android.mk b/tests/libhwbinder/1.0/Android.mk
index 4a5f779..bb430fb 100644
--- a/tests/libhwbinder/1.0/Android.mk
+++ b/tests/libhwbinder/1.0/Android.mk
@@ -34,6 +34,25 @@
 $(GEN): $(LOCAL_PATH)/IBenchmark.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IScheduleTest.hal
+#
+GEN := $(intermediates)/android/hardware/tests/libhwbinder/V1_0/IScheduleTest.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IScheduleTest.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.tests.libhwbinder@1.0::IScheduleTest
+
+$(GEN): $(LOCAL_PATH)/IScheduleTest.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
 include $(BUILD_JAVA_LIBRARY)
 
 
@@ -69,6 +88,25 @@
 $(GEN): $(LOCAL_PATH)/IBenchmark.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IScheduleTest.hal
+#
+GEN := $(intermediates)/android/hardware/tests/libhwbinder/V1_0/IScheduleTest.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IScheduleTest.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.tests.libhwbinder@1.0::IScheduleTest
+
+$(GEN): $(LOCAL_PATH)/IScheduleTest.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 
diff --git a/tests/libhwbinder/1.0/IBenchmark.hal b/tests/libhwbinder/1.0/IBenchmark.hal
index 6b266e2..b3aa320 100644
--- a/tests/libhwbinder/1.0/IBenchmark.hal
+++ b/tests/libhwbinder/1.0/IBenchmark.hal
@@ -17,5 +17,5 @@
 package android.hardware.tests.libhwbinder@1.0;
 
 interface IBenchmark {
-  sendVec(vec<uint8_t> data) generates (vec<uint8_t> return_data);
+  sendVec(vec<uint8_t> data) generates (vec<uint8_t> data);
 };
diff --git a/tests/libhwbinder/1.0/IScheduleTest.hal b/tests/libhwbinder/1.0/IScheduleTest.hal
new file mode 100644
index 0000000..b3f57c5
--- /dev/null
+++ b/tests/libhwbinder/1.0/IScheduleTest.hal
@@ -0,0 +1,21 @@
+/*
+ * 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.hardware.tests.libhwbinder@1.0;
+
+interface IScheduleTest {
+  send(uint32_t cfg, uint32_t callerSta) generates (uint32_t data);
+};
diff --git a/tests/libhwbinder/1.0/default/Android.bp b/tests/libhwbinder/1.0/default/Android.bp
index e690ca5..fa1b2b3 100644
--- a/tests/libhwbinder/1.0/default/Android.bp
+++ b/tests/libhwbinder/1.0/default/Android.bp
@@ -1,18 +1,16 @@
 cc_library_shared {
     name: "android.hardware.tests.libhwbinder@1.0-impl",
-    defaults: ["hidl_defaults"],
     relative_install_path: "hw",
     proprietary: true,
     srcs: [
         "Benchmark.cpp",
+        "ScheduleTest.cpp",
     ],
-
     shared_libs: [
-        "libbase",
         "libhidlbase",
         "libhidltransport",
-        "liblog",
         "libutils",
         "android.hardware.tests.libhwbinder@1.0",
+        "android.hidl.base@1.0",
     ],
 }
diff --git a/tests/libhwbinder/1.0/default/ScheduleTest.cpp b/tests/libhwbinder/1.0/default/ScheduleTest.cpp
new file mode 100644
index 0000000..6356953
--- /dev/null
+++ b/tests/libhwbinder/1.0/default/ScheduleTest.cpp
@@ -0,0 +1,84 @@
+#include "ScheduleTest.h"
+#include <pthread.h>
+#include <iomanip>
+#include <iostream>
+
+using namespace std;
+
+#define ASSERT(cond)                                                      \
+    do {                                                                  \
+        if (!(cond)) {                                                    \
+            cerr << __func__ << ":" << __LINE__ << " condition:" << #cond \
+                 << " failed\n"                                           \
+                 << endl;                                                 \
+            exit(EXIT_FAILURE);                                           \
+        }                                                                 \
+    } while (0)
+
+static int threadPri() {
+    struct sched_param param;
+    int policy;
+    ASSERT(!pthread_getschedparam(pthread_self(), &policy, &param));
+    return param.sched_priority;
+}
+
+static void threadDump(const char* prefix, int verbose) {
+    struct sched_param param;
+    int policy;
+    if (!verbose) return;
+    cout << "--------------------------------------------------" << endl;
+    cout << setw(12) << left << prefix << " pid: " << getpid()
+         << " tid: " << gettid() << " cpu: " << sched_getcpu() << endl;
+    ASSERT(!pthread_getschedparam(pthread_self(), &policy, &param));
+    string s = (policy == SCHED_OTHER)
+                   ? "SCHED_OTHER"
+                   : (policy == SCHED_FIFO)
+                         ? "SCHED_FIFO"
+                         : (policy == SCHED_RR) ? "SCHED_RR" : "???";
+    cout << setw(12) << left << s << param.sched_priority << endl;
+    return;
+}
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace libhwbinder {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::tests::libhwbinder::V1_0::IScheduleTest
+// follow.
+Return<uint32_t> ScheduleTest::send(uint32_t cfg, uint32_t callerSta) {
+    // TODO implement
+    int priority = threadPri();
+    int priority_caller = (callerSta >> 16) & 0xffff;
+    int verbose = cfg & 1;
+    threadDump("hwbinder", verbose);
+    uint32_t h = 0, s = 0;
+    if (priority_caller != priority) {
+        h++;
+        if (verbose) {
+            cout << "err priority_caller:" << priority_caller
+                 << ", priority:" << priority << endl;
+        }
+    }
+    int cpu = sched_getcpu();
+    int cpu_caller = (callerSta)&0xffff;
+    if (cpu != cpu_caller) {
+        s++;
+    }
+    return (h << 16) | (s & 0xffff);
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+IScheduleTest* HIDL_FETCH_IScheduleTest(const char* /* name */) {
+    return new ScheduleTest();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace libhwbinder
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
diff --git a/tests/libhwbinder/1.0/default/ScheduleTest.h b/tests/libhwbinder/1.0/default/ScheduleTest.h
new file mode 100644
index 0000000..ad6dd9d
--- /dev/null
+++ b/tests/libhwbinder/1.0/default/ScheduleTest.h
@@ -0,0 +1,41 @@
+#ifndef ANDROID_HARDWARE_TESTS_LIBHWBINDER_V1_0_SCHEDULETEST_H
+#define ANDROID_HARDWARE_TESTS_LIBHWBINDER_V1_0_SCHEDULETEST_H
+
+#include <android/hardware/tests/libhwbinder/1.0/IScheduleTest.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace tests {
+namespace libhwbinder {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tests::libhwbinder::V1_0::IScheduleTest;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct ScheduleTest : public IScheduleTest {
+    // Methods from ::android::hardware::tests::libhwbinder::V1_0::IScheduleTest
+    // follow.
+    Return<uint32_t> send(uint32_t cfg, uint32_t callerSta) override;
+
+    // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace libhwbinder
+}  // namespace tests
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TESTS_LIBHWBINDER_V1_0_SCHEDULETEST_H
diff --git a/thermal/1.0/default/Android.mk b/thermal/1.0/default/Android.mk
index 2d25dc3..113020a 100644
--- a/thermal/1.0/default/Android.mk
+++ b/thermal/1.0/default/Android.mk
@@ -29,7 +29,6 @@
         libdl \
         libbase \
         libutils \
-        libhardware_legacy \
         libhardware \
 
 LOCAL_SHARED_LIBRARIES += \