1 /* 2 * Copyright 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 #ifndef ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H 18 #define ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H 19 20 #include <android-base/result.h> 21 #include <android-base/unique_fd.h> 22 #include <android/system/suspend/1.0/ISystemSuspend.h> 23 #include <android/system/suspend/internal/SuspendInfo.h> 24 #include <hidl/HidlTransportSupport.h> 25 26 #include <atomic> 27 #include <condition_variable> 28 #include <mutex> 29 #include <string> 30 31 #include "SuspendControlService.h" 32 #include "WakeLockEntryList.h" 33 #include "WakeupList.h" 34 35 namespace android { 36 namespace system { 37 namespace suspend { 38 namespace V1_0 { 39 40 using ::android::base::Result; 41 using ::android::base::unique_fd; 42 using ::android::hardware::hidl_string; 43 using ::android::hardware::interfacesEqual; 44 using ::android::hardware::Return; 45 using ::android::system::suspend::internal::SuspendInfo; 46 47 using namespace std::chrono_literals; 48 49 class SystemSuspend; 50 51 struct SuspendStats { 52 int success = 0; 53 int fail = 0; 54 int failedFreeze = 0; 55 int failedPrepare = 0; 56 int failedSuspend = 0; 57 int failedSuspendLate = 0; 58 int failedSuspendNoirq = 0; 59 int failedResume = 0; 60 int failedResumeEarly = 0; 61 int failedResumeNoirq = 0; 62 std::string lastFailedDev; 63 int lastFailedErrno = 0; 64 std::string lastFailedStep; 65 }; 66 67 struct SleepTimeConfig { 68 std::chrono::milliseconds baseSleepTime; 69 std::chrono::milliseconds maxSleepTime; 70 double sleepTimeScaleFactor; 71 uint32_t backoffThreshold; 72 std::chrono::milliseconds shortSuspendThreshold; 73 bool failedSuspendBackoffEnabled; 74 bool shortSuspendBackoffEnabled; 75 }; 76 77 std::string readFd(int fd); 78 79 class WakeLock : public IWakeLock { 80 public: 81 WakeLock(SystemSuspend* systemSuspend, const std::string& name, int pid); 82 ~WakeLock(); 83 84 Return<void> release(); 85 86 private: 87 inline void releaseOnce(); 88 std::once_flag mReleased; 89 90 SystemSuspend* mSystemSuspend; 91 std::string mName; 92 int mPid; 93 }; 94 95 class SystemSuspend : public ISystemSuspend { 96 public: 97 SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, unique_fd suspendStatsFd, 98 size_t maxStatsEntries, unique_fd kernelWakelockStatsFd, 99 unique_fd wakeupReasonsFd, unique_fd suspendTimeFd, 100 const SleepTimeConfig& sleepTimeConfig, 101 const sp<SuspendControlService>& controlService, 102 const sp<SuspendControlServiceInternal>& controlServiceInternal, 103 bool useSuspendCounter = true); 104 Return<sp<IWakeLock>> acquireWakeLock(WakeLockType type, const hidl_string& name) override; 105 void incSuspendCounter(const std::string& name); 106 void decSuspendCounter(const std::string& name); 107 bool enableAutosuspend(); 108 bool forceSuspend(); 109 110 const WakeupList& getWakeupList() const; 111 const WakeLockEntryList& getStatsList() const; 112 void updateWakeLockStatOnRelease(const std::string& name, int pid, TimestampType timeNow); 113 void updateStatsNow(); 114 Result<SuspendStats> getSuspendStats(); 115 void getSuspendInfo(SuspendInfo* info); 116 std::chrono::milliseconds getSleepTime() const; 117 118 private: 119 void initAutosuspend(); 120 121 std::mutex mCounterLock; 122 std::condition_variable mCounterCondVar; 123 uint32_t mSuspendCounter; 124 unique_fd mWakeupCountFd; 125 unique_fd mStateFd; 126 127 unique_fd mSuspendStatsFd; 128 unique_fd mSuspendTimeFd; 129 130 std::mutex mSuspendInfoLock; 131 SuspendInfo mSuspendInfo; 132 133 const SleepTimeConfig kSleepTimeConfig; 134 135 // Amount of thread sleep time between consecutive iterations of the suspend loop 136 std::chrono::milliseconds mSleepTime; 137 int32_t mNumConsecutiveBadSuspends; 138 139 // Updates thread sleep time and suspend stats depending on the result of suspend attempt 140 void updateSleepTime(bool success, const struct SuspendTime& suspendTime); 141 142 sp<SuspendControlService> mControlService; 143 sp<SuspendControlServiceInternal> mControlServiceInternal; 144 145 WakeLockEntryList mStatsList; 146 WakeupList mWakeupList; 147 148 // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on 149 // /sys/power/wake_lock interface to block suspend. 150 // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface. 151 bool mUseSuspendCounter; 152 unique_fd mWakeLockFd; 153 unique_fd mWakeUnlockFd; 154 unique_fd mWakeupReasonsFd; 155 156 std::atomic_flag mAutosuspendEnabled = ATOMIC_FLAG_INIT; 157 }; 158 159 } // namespace V1_0 160 } // namespace suspend 161 } // namespace system 162 } // namespace android 163 164 #endif // ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H 165