/* * Copyright (C) 2017 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. */ #include <android/os/StatsLogEventWrapper.h> #include <binder/Parcel.h> #include <binder/Parcelable.h> #include <binder/Status.h> #include <utils/RefBase.h> #include <vector> using android::Parcel; using android::Parcelable; using android::status_t; using std::vector; namespace android { namespace os { StatsLogEventWrapper::StatsLogEventWrapper(){}; status_t StatsLogEventWrapper::writeToParcel(Parcel* out) const { // Implement me if desired. We don't currently use this. ALOGE( "Cannot do c++ StatsLogEventWrapper.writeToParcel(); it is not " "implemented."); (void)out; // To prevent compile error of unused parameter 'in' return UNKNOWN_ERROR; }; status_t StatsLogEventWrapper::readFromParcel(const Parcel* in) { status_t res = OK; if (in == NULL) { ALOGE("statsd received parcel argument was NULL."); return BAD_VALUE; } if ((res = in->readInt32(&mTagId)) != OK) { ALOGE("statsd could not read tagId from parcel"); return res; } if ((res = in->readInt64(&mElapsedRealTimeNs)) != OK) { ALOGE("statsd could not read elapsed real time from parcel"); return res; } if ((res = in->readInt64(&mWallClockTimeNs)) != OK) { ALOGE("statsd could not read wall clock time from parcel"); return res; } int numWorkChain = 0; if ((res = in->readInt32(&numWorkChain)) != OK) { ALOGE("statsd could not read number of work chains from parcel"); return res; } if (numWorkChain > 0) { for (int i = 0; i < numWorkChain; i++) { int numNodes = 0; if ((res = in->readInt32(&numNodes)) != OK) { ALOGE( "statsd could not read number of nodes in work chain from parcel"); return res; } if (numNodes == 0) { ALOGE("empty work chain"); return BAD_VALUE; } WorkChain wc; for (int j = 0; j < numNodes; j++) { wc.uids.push_back(in->readInt32()); wc.tags.push_back(std::string(String8(in->readString16()).string())); } mWorkChains.push_back(wc); } } int dataSize = 0; if ((res = in->readInt32(&dataSize)) != OK) { ALOGE("statsd could not read data size from parcel"); return res; } if (mTagId <= 0 || mElapsedRealTimeNs <= 0 || mWallClockTimeNs <= 0 || dataSize <= 0) { ALOGE("statsd received invalid parcel"); return BAD_VALUE; } for (int i = 0; i < dataSize; i++) { int type = in->readInt32(); switch (type) { case StatsLogValue::INT: mElements.push_back(StatsLogValue(in->readInt32())); break; case StatsLogValue::LONG: mElements.push_back(StatsLogValue(in->readInt64())); break; case StatsLogValue::STRING: mElements.push_back( StatsLogValue(std::string(String8(in->readString16()).string()))); break; case StatsLogValue::FLOAT: mElements.push_back(StatsLogValue(in->readFloat())); break; case StatsLogValue::STORAGE: mElements.push_back(StatsLogValue()); mElements.back().setType(StatsLogValue::STORAGE); in->readByteVector(&(mElements.back().storage_value)); break; default: ALOGE("unrecognized data type: %d", type); return BAD_TYPE; } } return NO_ERROR; }; } // Namespace os } // Namespace android