• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
EaselStateResidencyDataProvider(uint32_t id)31 EaselStateResidencyDataProvider::EaselStateResidencyDataProvider(uint32_t id) :
32     mPowerEntityId(id), mTotalOnSnapshotCount(0), mTotalNotOnSnapshotCount(0) {}
33 
getResults(std::unordered_map<uint32_t,PowerEntityStateResidencyResult> & results)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 
getStateSpaces()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