/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define TLOG_TAG "lib-stats" #include #include #include #include #include #include #include #include #include #include #include #include #include using android::frameworks::stats::VendorAtom; using android::frameworks::stats::VendorAtomValue; using android::trusty::stats::tz::IStats; #define PARCEL_SET(value_type, value_args...) \ do { \ auto parcel = stats_vendor_atom_to_VendorAtom(self); \ VendorAtomValue atom_value; \ atom_value.set(value_args); \ if (parcel->values.size() < atom_value_index + 1) { \ parcel->values.resize(atom_value_index + 1); \ } \ parcel->values[atom_value_index] = std::move(atom_value); \ return android::OK; \ } while (0) // We do not have anything to put in the structures right now, // but we need them to be allocatable. struct stats_istats {}; struct stats_vendor_atom {}; IBINDER_DEFINE_IFACE(IStats, stats_istats); IBINDER_DEFINE_PARCELABLE(VendorAtom, stats_vendor_atom); // VendorAtom parcel setter C API int stats_istats_get_service(const char* port, size_t port_len, struct stats_istats** pself) { assert(pself); android::sp binder; const char* binder_port = port; if (port_len > 0) { assert(port && port[port_len - 1] == '\0'); } if (int rc = binder_discover_get_service(binder_port, binder); rc != android::OK) { return rc; } auto container = new (std::nothrow) stats_istats_container{ IStats::asInterface(binder), stats_istats{}, {1}}; if (container == nullptr) { return ERR_NO_MEMORY; } *pself = &container->cbinder; return android::OK; } int stats_istats_report_vendor_atom(struct stats_istats* self, struct stats_vendor_atom* vendor_atom) { auto iface = stats_istats_to_IStats(self); auto parcel = stats_vendor_atom_to_VendorAtom(vendor_atom); auto rc = iface->reportVendorAtom(*parcel); if (!rc.isOk()) { TLOGE("iface->reportVendorAtom failed %s\n", rc.toString8().c_str()); return rc.exceptionCode(); } return android::OK; } // VendorAtom parcel setter C API int stats_vendor_atom_create_parcel(struct stats_vendor_atom** pself) { assert(pself); auto parcel = new (std::nothrow) VendorAtom(); if (parcel == nullptr) { return ERR_NO_MEMORY; } const auto container = new (std::nothrow) stats_vendor_atom_container{parcel, stats_vendor_atom{}, {1}}; if (container == nullptr) { delete parcel; return ERR_NO_MEMORY; } *pself = &container->cparcel; return android::OK; } int stats_vendor_atom_set_reverse_domain_name(struct stats_vendor_atom* self, const char* name, size_t name_len) { auto parcel = stats_vendor_atom_to_VendorAtom(self); parcel->reverseDomainName = android::String16(name, name_len); return android::OK; } int stats_vendor_atom_set_atom_id(struct stats_vendor_atom* self, int atom_id) { auto parcel = stats_vendor_atom_to_VendorAtom(self); parcel->atomId = atom_id; return android::OK; } int stats_vendor_atom_set_int_value_at(struct stats_vendor_atom* self, size_t atom_value_index, int32_t value) { PARCEL_SET(VendorAtomValue::intValue, value); } int stats_vendor_atom_set_long_value_at(struct stats_vendor_atom* self, size_t atom_value_index, int64_t value) { PARCEL_SET(VendorAtomValue::longValue, value); } int stats_vendor_atom_set_float_value_at(struct stats_vendor_atom* self, size_t atom_value_index, float value) { PARCEL_SET(VendorAtomValue::floatValue, value); } int stats_vendor_atom_set_string_value_at(struct stats_vendor_atom* self, size_t atom_value_index, const char* value, size_t value_len) { PARCEL_SET(VendorAtomValue::stringValue, value, value_len); }