16a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu/*
26a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Copyright (C) 2016 The Android Open Source Project
36a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu *
46a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Licensed under the Apache License, Version 2.0 (the "License");
56a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * you may not use this file except in compliance with the License.
66a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * You may obtain a copy of the License at
76a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu *
86a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu *      http://www.apache.org/licenses/LICENSE-2.0
96a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu *
106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * Unless required by applicable law or agreed to in writing, software
116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * distributed under the License is distributed on an "AS IS" BASIS,
126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * See the License for the specific language governing permissions and
146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu * limitations under the License.
156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu */
166a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "RecentEventLogger.h"
186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorServiceUtils.h"
196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <utils/Timers.h>
216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include <inttypes.h>
236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xunamespace android {
256a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xunamespace SensorServiceUtil {
266a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
276a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xunamespace {
286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    constexpr size_t LOG_SIZE = 10;
296a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    constexpr size_t LOG_SIZE_LARGE = 50;  // larger samples for debugging
306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}// unnamed namespace
316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuRecentEventLogger::RecentEventLogger(int sensorType) :
336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        mSensorType(sensorType), mEventSize(eventSizeBySensorType(mSensorType)),
342c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu        mRecentEvents(logSizeBySensorType(sensorType)), mMaskData(false) {
356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    // blank
366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuvoid RecentEventLogger::addEvent(const sensors_event_t& event) {
396a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    std::lock_guard<std::mutex> lk(mLock);
406a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    mRecentEvents.emplace(event);
416a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool RecentEventLogger::isEmpty() const {
446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    return mRecentEvents.size() == 0;
456a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
476a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xustd::string RecentEventLogger::dump() const {
486a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    std::lock_guard<std::mutex> lk(mLock);
496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    //TODO: replace String8 with std::string completely in this function
516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    String8 buffer;
526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    buffer.appendFormat("last %zu events\n", mRecentEvents.size());
546a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    int j = 0;
556a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    for (int i = mRecentEvents.size() - 1; i >= 0; --i) {
566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        const auto& ev = mRecentEvents[i];
576a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        struct tm * timeinfo = localtime(&(ev.mWallTime.tv_sec));
586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        buffer.appendFormat("\t%2d (ts=%.9f, wall=%02d:%02d:%02d.%03d) ",
596a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                ++j, ev.mEvent.timestamp/1e9, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
606a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                (int) ns2ms(ev.mWallTime.tv_nsec));
616a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
626a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        // data
632c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu        if (!mMaskData) {
642c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu            if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
652c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu                buffer.appendFormat("%" PRIu64 ", ", ev.mEvent.u64.step_counter);
662c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu            } else {
672c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu                for (size_t k = 0; k < mEventSize; ++k) {
682c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu                    buffer.appendFormat("%.2f, ", ev.mEvent.data[k]);
692c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu                }
706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            }
712c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu        } else {
722c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu            buffer.append("[value masked]");
736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        }
746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        buffer.append("\n");
756a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    }
766a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    return std::string(buffer.string());
776a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
786a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
792c238fc281da578d382f64443a7c9d7df89b2f39Peng Xuvoid RecentEventLogger::setFormat(std::string format) {
802c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu    if (format == "mask_data" ) {
812c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu        mMaskData = true;
822c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu    } else {
832c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu        mMaskData = false;
842c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu    }
852c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu}
862c238fc281da578d382f64443a7c9d7df89b2f39Peng Xu
876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool RecentEventLogger::populateLastEvent(sensors_event_t *event) const {
886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    std::lock_guard<std::mutex> lk(mLock);
896a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
906a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    if (mRecentEvents.size()) {
9145ca9f58a0f7808169199fba1cc067c51e2d437bPeng Xu        // Index 0 contains the latest event emplace()'ed
9245ca9f58a0f7808169199fba1cc067c51e2d437bPeng Xu        *event = mRecentEvents[0].mEvent;
936a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        return true;
946a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    } else {
956a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        return false;
966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    }
976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
986a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
1006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xusize_t RecentEventLogger::logSizeBySensorType(int sensorType) {
1016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    return (sensorType == SENSOR_TYPE_STEP_COUNTER ||
1026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            sensorType == SENSOR_TYPE_SIGNIFICANT_MOTION ||
103a57670c0b6b2cf9bd0aa318c8b5fee33a9ea5974Andrew Lehmer            sensorType == SENSOR_TYPE_ACCELEROMETER ||
104a57670c0b6b2cf9bd0aa318c8b5fee33a9ea5974Andrew Lehmer            sensorType == SENSOR_TYPE_LIGHT) ? LOG_SIZE_LARGE : LOG_SIZE;
1056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
1066a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
1076a2d3a06caa337857cf60cfc70a9a78909ad3608Peng XuRecentEventLogger::SensorEventLog::SensorEventLog(const sensors_event_t& e) : mEvent(e) {
1086a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    clock_gettime(CLOCK_REALTIME, &mWallTime);
1096a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu}
1106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
1116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} // namespace SensorServiceUtil
1126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu} // namespace android
113