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_EVSSTATECONTROL_H
18 #define CAR_EVS_APP_EVSSTATECONTROL_H
19 
20 #include "ConfigManager.h"
21 #include "EvsStats.h"
22 #include "RenderBase.h"
23 #include "StreamHandler.h"
24 
25 #include <aidl/android/hardware/automotive/evs/CameraDesc.h>
26 #include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
27 #include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
28 #include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
29 #include <aidl/android/hardware/automotive/vehicle/VehiclePropValues.h>
30 
31 #include <IVhalClient.h>
32 
33 #include <thread>
34 
35 /*
36  * This class runs the main update loop for the EVS application.  It will sleep when it has
37  * nothing to do.  It provides a thread safe way for other threads to wake it and pass commands
38  * to it.
39  */
40 class EvsStateControl final {
41 public:
42     EvsStateControl(
43             std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> pVnet,
44             std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> pEvs,
45             const std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsDisplay>& pDisplay,
46             const ConfigManager& config);
47 
48     enum State {
49         OFF = 0,
50         REVERSE,
51         LEFT,
52         RIGHT,
53         PARKING,
54         NUM_STATES  // Must come last
55     };
56 
57     enum class Op {
58         EXIT,
59         CHECK_VEHICLE_STATE,
60         TOUCH_EVENT,
61     };
62 
63     struct Command {
64         Op operation;
65         uint32_t arg1;
66         uint32_t arg2;
67     };
68 
69     // This spawns a new thread that is expected to run continuously
70     bool startUpdateLoop();
71 
72     // This stops a rendering thread
73     void terminateUpdateLoop();
74 
75     // Safe to be called from other threads
76     void postCommand(const Command& cmd, bool clear = false);
77 
78 private:
79     void updateLoop();
80     android::frameworks::automotive::vhal::ErrorCode invokeGet(
81             aidl::android::hardware::automotive::vehicle::VehiclePropValue* pRequestedPropValue);
82     bool selectStateForCurrentConditions();
83     bool configureEvsPipeline(State desiredState);  // Only call from one thread!
84 
85     std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVehicle;
86     std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mEvs;
87     std::weak_ptr<aidl::android::hardware::automotive::evs::IEvsDisplay> mDisplay;
88     const ConfigManager& mConfig;
89 
90     aidl::android::hardware::automotive::vehicle::VehiclePropValue mGearValue;
91     aidl::android::hardware::automotive::vehicle::VehiclePropValue mTurnSignalValue;
92 
93     State mCurrentState = OFF;
94 
95     // mCameraList is a redundant storage for camera device info, which is also
96     // stored in mCameraDescList and, however, not removed for backward
97     // compatibility.
98     std::vector<ConfigManager::CameraInfo> mCameraList[NUM_STATES];
99     std::unique_ptr<RenderBase> mCurrentRenderer;
100     std::unique_ptr<RenderBase> mDesiredRenderer;
101     std::vector<aidl::android::hardware::automotive::evs::CameraDesc> mCameraDescList[NUM_STATES];
102 
103     std::thread mRenderThread;  // The thread that runs the main rendering loop
104 
105     // Other threads may want to spur us into action, so we provide a thread safe way to do that
106     std::mutex mLock;
107     std::condition_variable mWakeSignal;
108     std::queue<Command> mCommandQueue;
109 
110     EvsStats mEvsStats;  // Not thread-safe
111 
112     // True if the first frame displayed on the mCurrentRenderer. Resets to false when
113     // mCurrentRenderer changes.
114     bool mFirstFrameIsDisplayed;
115 };
116 
117 #endif  // CAR_EVS_APP_EVSSTATECONTROL_H
118