| |
| /* |
| * 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 <android/frameworks/stats/VendorAtom.h> |
| #include <android/frameworks/stats/VendorAtomValue.h> |
| #include <android/trusty/stats/tz/IStats.h> |
| #include <binder/RpcSession.h> |
| #include <binder/RpcTransportTipcTrusty.h> |
| #include <lib/shared/binder_discover/binder_discover.h> |
| #include <lib/shared/ibinder/ibinder.h> |
| #include <lib/shared/ibinder/macros.h> |
| #include <lib/stats/stats.h> |
| #include <lib/tipc/tipc_srv.h> |
| #include <stdio.h> |
| #include <trusty_log.h> |
| #include <uapi/err.h> |
| |
| 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_type>(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<android::IBinder> 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); |
| } |