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