1fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal/*
2fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * Copyright (C) 2015 The Android Open Source Project
3fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal *
4fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * Licensed under the Apache License, Version 2.0 (the "License");
5fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * you may not use this file except in compliance with the License.
6fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * You may obtain a copy of the License at
7fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal *
8fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal *      http://www.apache.org/licenses/LICENSE-2.0
9fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal *
10fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * Unless required by applicable law or agreed to in writing, software
11fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * distributed under the License is distributed on an "AS IS" BASIS,
12fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * See the License for the specific language governing permissions and
14fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal * limitations under the License.
15fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal */
16fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
17fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal#include <gtest/gtest.h>
18fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal#include "vehicle_test_fixtures.h"
19fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal#include "hardware/vehicle.h"
20fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
21fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwalnamespace tests {
22fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
23fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// Check if list_properties command exists.
24fb63668a8a4eab5a0ba32132405c7982629074a1Sanket AgarwalTEST_F(VehicleDevice, isThereListProperties) {
25fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_TRUE(NULL != vehicle_device()->list_properties)
26fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        << "list_properties() function is not implemented";
27fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    std::cout << "Test succeeds.\n";
28fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal}
29fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
30fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// HAL should provide atleast one property. The output of this command should be
31fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// used to verify the vailidity of the function.
32fb63668a8a4eab5a0ba32132405c7982629074a1Sanket AgarwalTEST_F(VehicleDevice, listPropertiesMoreThanOne) {
33fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    vehicle_prop_config_t const* config;
34fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    int num_configs = -1;
35fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    config = vehicle_device()->list_properties(vehicle_device(), &num_configs);
36fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_TRUE(num_configs > -1) << "list_properties() call failed.";
37fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_TRUE(num_configs > 0) << "list_properties() returned zero items.";
38fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    std::cout << "Number of properties reported: " << num_configs << "\n";
39fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    for (int i = 0; i < num_configs; i++) {
40fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        // Print each of the properties.
41fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        const vehicle_prop_config_t& config_temp = config[i];
42fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        std::cout << "Property ID: " << config_temp.prop << "\n";
43fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        std::cout << "Property flags: " << config_temp.config_flags << "\n";
44fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        std::cout << "Property change mode: " << config_temp.change_mode << "\n";
45fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        std::cout << "Property min sample rate: " << config_temp.min_sample_rate << "\n";
46fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        std::cout << "Property max sample rate: " << config_temp.max_sample_rate << "\n\n";
47fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    }
48fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal}
49fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
50fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// Test get() command.
51fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// The fields are hardcoded in the dummy implementation and here.
52fb63668a8a4eab5a0ba32132405c7982629074a1Sanket AgarwalTEST_F(VehicleDevice, getDriveState) {
53fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    vehicle_prop_value_t data;
54fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    data.prop = VEHICLE_PROPERTY_DRIVING_STATUS;
55fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Set drive_state field to EINVAL so that we can check that its valid when
56fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // it comes back.
57fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    data.value_type = -EINVAL;
58fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    data.value.driving_status = -EINVAL;
59fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    vehicle_device()->get(vehicle_device(), &data);
60fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
61fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Check that retured values are not invalid.
62fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_NE(data.value_type, -EINVAL) << "Drive state value type should be integer.";
63fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_NE(data.value.driving_status, -EINVAL) << "Driving status should be positive.";
64fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
65fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    std::cout << "Driving status value type: " << data.value_type << "\n"
66fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal              << "Driving status: " << data.value.driving_status << "\n";
67fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal}
68fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
69fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// Test the workflows for subscribe and init/release.
70fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// Subscribe will return error before init() is called or after release() is
71fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// called.
72fb63668a8a4eab5a0ba32132405c7982629074a1Sanket AgarwalTEST_F(VehicleDevice, initTest) {
73fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Test that init on a new device works. When getting an instance, we are
74fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // already calling 'open' on the device.
75fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    int ret_code =
76fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal        vehicle_device()->init(vehicle_device(), callback_fn(), error_fn());
77fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "ret code: " << ret_code;
78fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
79fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Trying to init again should return an error.
80fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->init(vehicle_device(), callback_fn(), error_fn());
81fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, -EEXIST) << "ret code: " << ret_code;
82fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
83fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Uninit should always return 0.
84fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->release(vehicle_device());
85fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "ret code: " << ret_code;
86fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
87fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // We should be able to init again.
88fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->init(vehicle_device(), callback_fn(), error_fn());
89fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "ret code: " << ret_code;
90fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
91fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Finally release.
92fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->release(vehicle_device());
93fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "ret_code: " << ret_code;
94fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal}
95fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
96fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// Test that subscribe works.
97fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// We wait for 10 seconds while which the vehicle.c can post messages from
98fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal// within it's own thread.
99fb63668a8a4eab5a0ba32132405c7982629074a1Sanket AgarwalTEST_F(VehicleDevice, subscribeTest) {
100fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // If the device is not init subscribe should fail off the bat.
101fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    int ret_code = vehicle_device()->subscribe(vehicle_device(), VEHICLE_PROPERTY_DRIVING_STATUS,
102bf877a7e6673f43ded94ead0784c93c558e5aa2bKeun-young Park            0, 0);
103fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, -EINVAL) << "Return code is: " << ret_code;
104fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
105fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Let's init the device.
106fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->init(vehicle_device(), callback_fn(), error_fn());
107fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "Return code is: " << ret_code;
108fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
109fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // Subscribe should now go through.
110bf877a7e6673f43ded94ead0784c93c558e5aa2bKeun-young Park    ret_code = vehicle_device()->subscribe(vehicle_device(), VEHICLE_PROPERTY_DRIVING_STATUS, 0, 0);
111fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "Return code is: " << ret_code;
112fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
113fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // We should start getting some messages thrown from the callback. Let's
114fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // wait for 20 seconds before unsubscribing.
115fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    std::cout << "Sleeping for 20 seconds.";
116fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    sleep(20);
117fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    std::cout << "Waking from sleep.";
118fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
119fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // This property does not exist, so we should get -EINVAL.
120fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->unsubscribe(vehicle_device(), VEHICLE_PROPERTY_INFO_VIN);
121fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, -EINVAL) << "Return code is: " << ret_code;
122fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
123fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // This property exists, so we should get a success return code - also this
124fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    // will be a blocking call.
125fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ret_code = vehicle_device()->unsubscribe(vehicle_device(), VEHICLE_PROPERTY_DRIVING_STATUS);
126fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal    ASSERT_EQ(ret_code, 0) << "Return code is: " << ret_code;
127fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal}
128fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal
129fb63668a8a4eab5a0ba32132405c7982629074a1Sanket Agarwal}  // namespace tests
130