• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_EVSSTATS_H
18 #define CAR_EVS_APP_EVSSTATS_H
19 
20 #include <aidl/android/frameworks/automotive/telemetry/CarData.h>
21 #include <aidl/android/frameworks/automotive/telemetry/ICarTelemetry.h>
22 #include <android/binder_status.h>
23 #include <utils/Mutex.h>
24 
25 #include <deque>
26 #include <memory>
27 
28 // Performs metric computations, sends to `ICarTelemetry`.
29 //
30 // Not thread-safe. Methods `startComputingFirstFrameLatency`, `finishComputingFirstFrameLatency`
31 // and `sendCollectedDataBlocking` must be called from the same thread.
32 class EvsStats {
33 public:
34     // Instantiates EvsStats.
35     static EvsStats build();
36 
37     // Starts computing end-2-end first frame latency: from the time of the event that starts the
38     // camera to the time of the display of the very first frame.
39     // Call this method when an event that enables the camera occurred, e.g. gear shift to REAR.
40     // Param `startTimeMillis` should be `android::uptimeMillis()`.
41     void startComputingFirstFrameLatency(int64_t startTimeMillis);
42 
43     // Computes the latency and sends the data to `ICarTelemetry` if the receiving service is up.
44     // Call this method when the first camera frame is displayed on the screen and don't call
45     // after that unless a new computation is started.
46     // Param `finishTimeMillis` should be `android::uptimeMillis()`.
47     void finishComputingFirstFrameLatency(int64_t finishTimeMillis);
48 
49     // Sends the collected data to `ICarTelemetry`. Blocks for short amount of time if the service
50     // is unavailable.
51     void sendCollectedDataBlocking();
52 
53 private:
54     enum EvsStatsState {
55         NOT_STARTED = -1,
56     };
57 
58 private:
EvsStats(bool enabled)59     EvsStats(bool enabled) :
60           mEnabled(enabled),
61           mBinderDeathRecipient(::AIBinder_DeathRecipient_new(EvsStats::telemetryBinderDied)) {}
62 
63     // Death recipient callback that is called when ICarTelemetry dies.
64     // The cookie is a pointer to a EvsStats object.
65     static void telemetryBinderDied(void* cookie);
66 
67     void telemetryBinderDiedImpl();
68 
69     // Tries sending data if the receiving service is up.
70     // Must be called when both `mEnabled` is true and `mCollectedData` is not empty.
71     //
72     // \param waitIfNotReady - if true, it can block briefly until ICarTelemetry is ready.
73     void sendCollectedDataUnsafe(bool waitIfNotReady);
74 
75     // Returns the instance of ICarTelemetry.
76     //
77     // \param waitIfNotReady - if true, it can block briefly until ICarTelemetry is ready.
78     std::shared_ptr<aidl::android::frameworks::automotive::telemetry::ICarTelemetry>
79     getCarTelemetry(bool waitIfNotReady);
80 
81     std::mutex mMutex;
82     bool mEnabled;
83     int64_t mFirstFrameLatencyStartTimeMillis = EvsStatsState::NOT_STARTED;
84     // This is a ring buffer
85     std::deque<aidl::android::frameworks::automotive::telemetry::CarData> mCollectedData;
86     std::shared_ptr<aidl::android::frameworks::automotive::telemetry::ICarTelemetry> mCarTelemetry;
87     ndk::ScopedAIBinder_DeathRecipient mBinderDeathRecipient;
88 };
89 
90 #endif  // CAR_EVS_APP_EVSSTATS_H
91