Home | History | Annotate | Download | only in powerstats
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "easelstateresidency"
     18 
     19 #include <android-base/logging.h>
     20 #include <fstream>
     21 #include "EaselStateResidencyDataProvider.h"
     22 
     23 namespace android {
     24 namespace device {
     25 namespace google {
     26 namespace wahoo {
     27 namespace powerstats {
     28 
     29 const uint32_t EASEL_SYNTHETIC_SLEEP_ID = 0;
     30 
     31 EaselStateResidencyDataProvider::EaselStateResidencyDataProvider(uint32_t id) :
     32     mPowerEntityId(id), mTotalOnSnapshotCount(0), mTotalNotOnSnapshotCount(0) {}
     33 
     34 bool EaselStateResidencyDataProvider::getResults(
     35     std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
     36     const std::string path = "/sys/devices/virtual/misc/mnh_sm/state";
     37 
     38     enum easel_state {
     39         EASEL_OFF = 0,
     40         EASEL_ON,
     41         EASEL_SUSPENDED,
     42         NUM_EASEL_STATES
     43     };
     44 
     45     // Since we are storing stats locally but can have multiple parallel
     46     // callers, locking is required to ensure stats are not corrupted.
     47     std::lock_guard<std::mutex> lock(mLock);
     48 
     49     std::ifstream inFile(path, std::ifstream::in);
     50     if (!inFile.is_open()) {
     51         PLOG(ERROR) << __func__ << ":Failed to open file " << path;
     52         return false;
     53     }
     54 
     55     unsigned long currentState;
     56     if(!(inFile >> currentState) || currentState >= NUM_EASEL_STATES) {
     57         PLOG(ERROR) << __func__ << ":Failed to parse " << path;
     58         return false;
     59     }
     60 
     61     // Update statistics for synthetic sleep state.  We combine OFF and
     62     // SUSPENDED to act as a composite "not on" state so the numbers will behave
     63     // like a real sleep state.
     64     if ((currentState == EASEL_OFF) || (currentState == EASEL_SUSPENDED)) {
     65         mTotalNotOnSnapshotCount++;
     66     } else {
     67         mTotalOnSnapshotCount++;
     68     }
     69 
     70     // Update statistics for synthetic sleep state, where
     71     // totalStateEntryCount = cumulative count of Easel state0 and state2
     72     // (as seen by power.stats HAL)
     73     // totalTimeInStateMs = cumulative count of Easel state1 (as seen by
     74     //   power.stats HAL)
     75     PowerEntityStateResidencyResult result = {
     76         .powerEntityId = mPowerEntityId,
     77         .stateResidencyData = {{.powerEntityStateId = EASEL_SYNTHETIC_SLEEP_ID,
     78                                 .totalStateEntryCount = mTotalOnSnapshotCount,
     79                                 .totalTimeInStateMs = mTotalNotOnSnapshotCount,
     80                                 .lastEntryTimestampMs = 0}}
     81     };
     82 
     83     results.emplace(std::make_pair(mPowerEntityId, result));
     84     return true;
     85 }
     86 
     87 
     88 std::vector<PowerEntityStateSpace> EaselStateResidencyDataProvider::getStateSpaces() {
     89     return {
     90         {.powerEntityId = mPowerEntityId,
     91             .states = {
     92                 {
     93                  .powerEntityStateId = EASEL_SYNTHETIC_SLEEP_ID,
     94                  .powerEntityStateName = "SyntheticSleep"
     95                 }
     96             }
     97         }
     98     };
     99 }
    100 
    101 }  // namespace powerstats
    102 }  // namespace wahoo
    103 }  // namespace google
    104 }  // namespace device
    105 }  // namespace android