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 <hidl/HidlTransportSupport.h> 24 25 #include <condition_variable> 26 #include <mutex> 27 #include <string> 28 29 #include "SuspendControlService.h" 30 #include "WakeLockEntryList.h" 31 32 namespace android { 33 namespace system { 34 namespace suspend { 35 namespace V1_0 { 36 37 using ::android::base::Result; 38 using ::android::base::unique_fd; 39 using ::android::hardware::hidl_string; 40 using ::android::hardware::interfacesEqual; 41 using ::android::hardware::Return; 42 43 using namespace std::chrono_literals; 44 45 class SystemSuspend; 46 47 struct SuspendStats { 48 int success = 0; 49 int fail = 0; 50 int failedFreeze = 0; 51 int failedPrepare = 0; 52 int failedSuspend = 0; 53 int failedSuspendLate = 0; 54 int failedSuspendNoirq = 0; 55 int failedResume = 0; 56 int failedResumeEarly = 0; 57 int failedResumeNoirq = 0; 58 std::string lastFailedDev; 59 int lastFailedErrno = 0; 60 std::string lastFailedStep; 61 }; 62 63 std::string readFd(int fd); 64 65 class WakeLock : public IWakeLock { 66 public: 67 WakeLock(SystemSuspend* systemSuspend, const std::string& name, int pid); 68 ~WakeLock(); 69 70 Return<void> release(); 71 72 private: 73 inline void releaseOnce(); 74 std::once_flag mReleased; 75 76 SystemSuspend* mSystemSuspend; 77 std::string mName; 78 int mPid; 79 }; 80 81 class SystemSuspend : public ISystemSuspend { 82 public: 83 SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, unique_fd suspendStatsFd, 84 size_t maxNativeStatsEntries, unique_fd kernelWakelockStatsFd, 85 std::chrono::milliseconds baseSleepTime, 86 const sp<SuspendControlService>& controlService, bool useSuspendCounter = true); 87 Return<sp<IWakeLock>> acquireWakeLock(WakeLockType type, const hidl_string& name) override; 88 void incSuspendCounter(const std::string& name); 89 void decSuspendCounter(const std::string& name); 90 bool enableAutosuspend(); 91 bool forceSuspend(); 92 93 const WakeLockEntryList& getStatsList() const; 94 void updateWakeLockStatOnRelease(const std::string& name, int pid, TimestampType timeNow); 95 void updateStatsNow(); 96 Result<SuspendStats> getSuspendStats(); 97 98 private: 99 void initAutosuspend(); 100 101 std::mutex mCounterLock; 102 std::condition_variable mCounterCondVar; 103 uint32_t mSuspendCounter; 104 unique_fd mWakeupCountFd; 105 unique_fd mStateFd; 106 107 unique_fd mSuspendStatsFd; 108 109 // Amount of sleep time between consecutive iterations of the suspend loop. 110 std::chrono::milliseconds mBaseSleepTime; 111 std::chrono::milliseconds mSleepTime; 112 // Updates sleep time depending on the result of suspend attempt. 113 void updateSleepTime(bool success); 114 115 sp<SuspendControlService> mControlService; 116 117 WakeLockEntryList mStatsList; 118 119 // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on 120 // /sys/power/wake_lock interface to block suspend. 121 // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface. 122 bool mUseSuspendCounter; 123 unique_fd mWakeLockFd; 124 unique_fd mWakeUnlockFd; 125 }; 126 127 } // namespace V1_0 128 } // namespace suspend 129 } // namespace system 130 } // namespace android 131 132 #endif // ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H 133