1*70a7ec85SAndroid Build Coastguard Worker /* 2*70a7ec85SAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project 3*70a7ec85SAndroid Build Coastguard Worker * 4*70a7ec85SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*70a7ec85SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*70a7ec85SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*70a7ec85SAndroid Build Coastguard Worker * 8*70a7ec85SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*70a7ec85SAndroid Build Coastguard Worker * 10*70a7ec85SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*70a7ec85SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*70a7ec85SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*70a7ec85SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*70a7ec85SAndroid Build Coastguard Worker * limitations under the License. 15*70a7ec85SAndroid Build Coastguard Worker */ 16*70a7ec85SAndroid Build Coastguard Worker 17*70a7ec85SAndroid Build Coastguard Worker // Special utils for VintfObject(s). 18*70a7ec85SAndroid Build Coastguard Worker 19*70a7ec85SAndroid Build Coastguard Worker #pragma once 20*70a7ec85SAndroid Build Coastguard Worker 21*70a7ec85SAndroid Build Coastguard Worker // This is okay because it is a header private to libvintf. Do not do this in exported headers! 22*70a7ec85SAndroid Build Coastguard Worker #include <android-base/logging.h> 23*70a7ec85SAndroid Build Coastguard Worker 24*70a7ec85SAndroid Build Coastguard Worker #include <vintf/VintfObject.h> 25*70a7ec85SAndroid Build Coastguard Worker 26*70a7ec85SAndroid Build Coastguard Worker namespace android { 27*70a7ec85SAndroid Build Coastguard Worker namespace vintf { 28*70a7ec85SAndroid Build Coastguard Worker namespace details { 29*70a7ec85SAndroid Build Coastguard Worker 30*70a7ec85SAndroid Build Coastguard Worker // Get() fetches data and caches it in LockedSharedPtr. The cached data will be 31*70a7ec85SAndroid Build Coastguard Worker // invalidated when `lastModified` is changed from the last call. Typically `lastModified` 32*70a7ec85SAndroid Build Coastguard Worker // can refer to the "last modified" timestamp of the data source. 33*70a7ec85SAndroid Build Coastguard Worker template <typename T, typename F> 34*70a7ec85SAndroid Build Coastguard Worker std::shared_ptr<const T> Get(const char* id, LockedSharedPtr<T>* ptr, const F& fetch, 35*70a7ec85SAndroid Build Coastguard Worker const std::optional<timespec>& lastModified = std::nullopt) { 36*70a7ec85SAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(ptr->mutex); 37*70a7ec85SAndroid Build Coastguard Worker // Check if the last fetched data is fresh. If it's old, re-fetch the data 38*70a7ec85SAndroid Build Coastguard Worker // with the new timestamp. 39*70a7ec85SAndroid Build Coastguard Worker if (ptr->object && ptr->lastModified != lastModified) { 40*70a7ec85SAndroid Build Coastguard Worker LOG(INFO) << id << ": Reloading VINTF information."; 41*70a7ec85SAndroid Build Coastguard Worker ptr->object = nullptr; 42*70a7ec85SAndroid Build Coastguard Worker } 43*70a7ec85SAndroid Build Coastguard Worker if (!ptr->object) { 44*70a7ec85SAndroid Build Coastguard Worker LOG(INFO) << id << ": Reading VINTF information."; 45*70a7ec85SAndroid Build Coastguard Worker ptr->object = std::make_unique<T>(); 46*70a7ec85SAndroid Build Coastguard Worker ptr->lastModified = lastModified; 47*70a7ec85SAndroid Build Coastguard Worker std::string error; 48*70a7ec85SAndroid Build Coastguard Worker status_t status = fetch(ptr->object.get(), &error); 49*70a7ec85SAndroid Build Coastguard Worker if (status == OK) { 50*70a7ec85SAndroid Build Coastguard Worker LOG(INFO) << id << ": Successfully processed VINTF information"; 51*70a7ec85SAndroid Build Coastguard Worker } else { 52*70a7ec85SAndroid Build Coastguard Worker // Doubled because a malformed error std::string might cause us to 53*70a7ec85SAndroid Build Coastguard Worker // lose the status. 54*70a7ec85SAndroid Build Coastguard Worker LOG(ERROR) << id << ": status from fetching VINTF information: " << status; 55*70a7ec85SAndroid Build Coastguard Worker LOG(ERROR) << id << ": " << status << " VINTF parse error: " << error; 56*70a7ec85SAndroid Build Coastguard Worker ptr->object = nullptr; // frees the old object 57*70a7ec85SAndroid Build Coastguard Worker } 58*70a7ec85SAndroid Build Coastguard Worker } 59*70a7ec85SAndroid Build Coastguard Worker return ptr->object; 60*70a7ec85SAndroid Build Coastguard Worker } 61*70a7ec85SAndroid Build Coastguard Worker 62*70a7ec85SAndroid Build Coastguard Worker } // namespace details 63*70a7ec85SAndroid Build Coastguard Worker } // namespace vintf 64*70a7ec85SAndroid Build Coastguard Worker } // namespace android 65