1
2 /*
3 * Copyright (C) 2022 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #define TLOG_TAG "lib-stats"
19
20 #include <android/frameworks/stats/VendorAtom.h>
21 #include <android/frameworks/stats/VendorAtomValue.h>
22 #include <android/trusty/stats/tz/IStats.h>
23 #include <binder/RpcSession.h>
24 #include <binder/RpcTransportTipcTrusty.h>
25 #include <lib/shared/binder_discover/binder_discover.h>
26 #include <lib/shared/ibinder/ibinder.h>
27 #include <lib/shared/ibinder/macros.h>
28 #include <lib/stats/stats.h>
29 #include <lib/tipc/tipc_srv.h>
30 #include <stdio.h>
31 #include <trusty_log.h>
32 #include <uapi/err.h>
33
34 using android::frameworks::stats::VendorAtom;
35 using android::frameworks::stats::VendorAtomValue;
36 using android::trusty::stats::tz::IStats;
37
38 #define PARCEL_SET(value_type, value_args...) \
39 do { \
40 auto parcel = stats_vendor_atom_to_VendorAtom(self); \
41 VendorAtomValue atom_value; \
42 atom_value.set<value_type>(value_args); \
43 if (parcel->values.size() < atom_value_index + 1) { \
44 parcel->values.resize(atom_value_index + 1); \
45 } \
46 parcel->values[atom_value_index] = std::move(atom_value); \
47 return android::OK; \
48 } while (0)
49
50 // We do not have anything to put in the structures right now,
51 // but we need them to be allocatable.
52 struct stats_istats {};
53
54 struct stats_vendor_atom {};
55
56 IBINDER_DEFINE_IFACE(IStats, stats_istats);
57 IBINDER_DEFINE_PARCELABLE(VendorAtom, stats_vendor_atom);
58
59 // VendorAtom parcel setter C API
60
stats_istats_get_service(const char * port,size_t port_len,struct stats_istats ** pself)61 int stats_istats_get_service(const char* port,
62 size_t port_len,
63 struct stats_istats** pself) {
64 assert(pself);
65 android::sp<android::IBinder> binder;
66
67 const char* binder_port = port;
68 if (port_len > 0) {
69 assert(port && port[port_len - 1] == '\0');
70 }
71 if (int rc = binder_discover_get_service(binder_port, binder);
72 rc != android::OK) {
73 return rc;
74 }
75 auto container = new (std::nothrow) stats_istats_container{
76 IStats::asInterface(binder), stats_istats{}, {1}};
77 if (container == nullptr) {
78 return ERR_NO_MEMORY;
79 }
80 *pself = &container->cbinder;
81 return android::OK;
82 }
83
stats_istats_report_vendor_atom(struct stats_istats * self,struct stats_vendor_atom * vendor_atom)84 int stats_istats_report_vendor_atom(struct stats_istats* self,
85 struct stats_vendor_atom* vendor_atom) {
86 auto iface = stats_istats_to_IStats(self);
87 auto parcel = stats_vendor_atom_to_VendorAtom(vendor_atom);
88 auto rc = iface->reportVendorAtom(*parcel);
89 if (!rc.isOk()) {
90 TLOGE("iface->reportVendorAtom failed %s\n", rc.toString8().c_str());
91 return rc.exceptionCode();
92 }
93 return android::OK;
94 }
95
96 // VendorAtom parcel setter C API
97
stats_vendor_atom_create_parcel(struct stats_vendor_atom ** pself)98 int stats_vendor_atom_create_parcel(struct stats_vendor_atom** pself) {
99 assert(pself);
100 auto parcel = new (std::nothrow) VendorAtom();
101 if (parcel == nullptr) {
102 return ERR_NO_MEMORY;
103 }
104 const auto container = new (std::nothrow)
105 stats_vendor_atom_container{parcel, stats_vendor_atom{}, {1}};
106 if (container == nullptr) {
107 delete parcel;
108 return ERR_NO_MEMORY;
109 }
110 *pself = &container->cparcel;
111 return android::OK;
112 }
113
stats_vendor_atom_set_reverse_domain_name(struct stats_vendor_atom * self,const char * name,size_t name_len)114 int stats_vendor_atom_set_reverse_domain_name(struct stats_vendor_atom* self,
115 const char* name,
116 size_t name_len) {
117 auto parcel = stats_vendor_atom_to_VendorAtom(self);
118 parcel->reverseDomainName = android::String16(name, name_len);
119 return android::OK;
120 }
121
stats_vendor_atom_set_atom_id(struct stats_vendor_atom * self,int atom_id)122 int stats_vendor_atom_set_atom_id(struct stats_vendor_atom* self, int atom_id) {
123 auto parcel = stats_vendor_atom_to_VendorAtom(self);
124 parcel->atomId = atom_id;
125 return android::OK;
126 }
127
stats_vendor_atom_set_int_value_at(struct stats_vendor_atom * self,size_t atom_value_index,int32_t value)128 int stats_vendor_atom_set_int_value_at(struct stats_vendor_atom* self,
129 size_t atom_value_index,
130 int32_t value) {
131 PARCEL_SET(VendorAtomValue::intValue, value);
132 }
133
stats_vendor_atom_set_long_value_at(struct stats_vendor_atom * self,size_t atom_value_index,int64_t value)134 int stats_vendor_atom_set_long_value_at(struct stats_vendor_atom* self,
135 size_t atom_value_index,
136 int64_t value) {
137 PARCEL_SET(VendorAtomValue::longValue, value);
138 }
139
stats_vendor_atom_set_float_value_at(struct stats_vendor_atom * self,size_t atom_value_index,float value)140 int stats_vendor_atom_set_float_value_at(struct stats_vendor_atom* self,
141 size_t atom_value_index,
142 float value) {
143 PARCEL_SET(VendorAtomValue::floatValue, value);
144 }
145
stats_vendor_atom_set_string_value_at(struct stats_vendor_atom * self,size_t atom_value_index,const char * value,size_t value_len)146 int stats_vendor_atom_set_string_value_at(struct stats_vendor_atom* self,
147 size_t atom_value_index,
148 const char* value,
149 size_t value_len) {
150 PARCEL_SET(VendorAtomValue::stringValue, value, value_len);
151 }
152