1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CAR_EVS_APP_VEHICLELISTENER_H
18 #define CAR_EVS_APP_VEHICLELISTENER_H
19 
20 #include "EvsStateControl.h"
21 
22 /*
23  * This class listens for asynchronous updates from the Vehicle HAL.  While the EVS
24  * applications is active, it can poll the vehicle state directly.  However, when it goes to
25  * sleep, we need these notifications to bring it active again.
26  */
27 class EvsVehicleListener : public IVehicleCallback {
28 public:
29     // Methods from ::android::hardware::automotive::vehicle::V2_0::IVehicleCallback follow.
onPropertyEvent(const hidl_vec<VehiclePropValue> &)30     Return<void> onPropertyEvent(const hidl_vec <VehiclePropValue> & /*values*/) override {
31         {
32             // Our use case is so simple, we don't actually need to update a variable,
33             // but the docs seem to say we have to take the lock anyway to keep
34             // the condition variable implementation happy.
35             std::lock_guard<std::mutex> g(mLock);
36         }
37         mEventCond.notify_one();
38         return Return<void>();
39     }
40 
onPropertySet(const VehiclePropValue &)41     Return<void> onPropertySet(const VehiclePropValue & /*value*/) override {
42         // Ignore the direct set calls (we don't expect to make any anyway)
43         return Return<void>();
44     }
45 
onPropertySetError(StatusCode,int32_t,int32_t)46     Return<void> onPropertySetError(StatusCode      /* errorCode */,
47                                     int32_t         /* propId */,
48                                     int32_t         /* areaId */) override {
49         // We don't set values, so we don't listen for set errors
50         return Return<void>();
51     }
52 
waitForEvents(int timeout_ms)53     bool waitForEvents(int timeout_ms) {
54         std::unique_lock<std::mutex> g(mLock);
55         std::cv_status result = mEventCond.wait_for(g, std::chrono::milliseconds(timeout_ms));
56         return (result == std::cv_status::no_timeout);
57     }
58 
run(EvsStateControl * pStateController)59     void run(EvsStateControl *pStateController) {
60         while (true) {
61             // Wait until we have an event to which to react
62             // (wake up and validate our current state "just in case" every so often)
63             waitForEvents(5000);
64 
65             // If we were delivered an event (or it's been a while) update as necessary
66             EvsStateControl::Command cmd = {
67                 .operation = EvsStateControl::Op::CHECK_VEHICLE_STATE,
68                 .arg1      = 0,
69                 .arg2      = 0,
70             };
71             pStateController->postCommand(cmd);
72         }
73     }
74 
75 private:
76     std::mutex mLock;
77     std::condition_variable mEventCond;
78 };
79 
80 #endif //CAR_EVS_APP_VEHICLELISTENER_H
81