• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SuspendControlService.h"
21 
22 #include <android-base/unique_fd.h>
23 #include <android/system/suspend/1.0/ISystemSuspend.h>
24 #include <hidl/HidlTransportSupport.h>
25 #include <system/hardware/interfaces/suspend/1.0/default/SystemSuspendStats.pb.h>
26 
27 #include <condition_variable>
28 #include <mutex>
29 #include <string>
30 
31 namespace android {
32 namespace system {
33 namespace suspend {
34 namespace V1_0 {
35 
36 using ::android::base::unique_fd;
37 using ::android::hardware::hidl_death_recipient;
38 using ::android::hardware::hidl_handle;
39 using ::android::hardware::hidl_string;
40 using ::android::hardware::hidl_vec;
41 using ::android::hardware::interfacesEqual;
42 using ::android::hardware::Return;
43 
44 using TimestampType = uint64_t;
45 using WakeLockIdType = std::string;
46 
47 using namespace std::chrono_literals;
48 
49 class SystemSuspend;
50 
51 std::string readFd(int fd);
52 TimestampType getEpochTimeNow();
53 
54 class WakeLock : public IWakeLock {
55    public:
56     WakeLock(SystemSuspend* systemSuspend, const WakeLockIdType& id, const std::string& name);
57     ~WakeLock();
58 
59     Return<void> release();
60 
61    private:
62     inline void releaseOnce();
63     std::once_flag mReleased;
64 
65     SystemSuspend* mSystemSuspend;
66     WakeLockIdType mId;
67     std::string mName;
68 };
69 
70 class SystemSuspend : public ISystemSuspend {
71    public:
72     SystemSuspend(unique_fd wakeupCountFd, unique_fd stateFd, size_t maxStatsEntries,
73                   std::chrono::milliseconds baseSleepTime,
74                   const sp<SuspendControlService>& controlService, bool useSuspendCounter = true);
75     Return<sp<IWakeLock>> acquireWakeLock(WakeLockType type, const hidl_string& name) override;
76     Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
77     void incSuspendCounter(const std::string& name);
78     void decSuspendCounter(const std::string& name);
79     void deleteWakeLockStatsEntry(WakeLockIdType id);
80     bool enableAutosuspend();
81     bool forceSuspend();
82 
83    private:
84     void initAutosuspend();
85 
86     std::mutex mCounterLock;
87     std::condition_variable mCounterCondVar;
88     uint32_t mSuspendCounter;
89     unique_fd mWakeupCountFd;
90     unique_fd mStateFd;
91 
92     // mStats can be inconsistent with with mSuspendCounter since we use two separate locks to
93     // protect these. However, since mStats is only for debugging we prioritize performance.
94     // Never hold both locks at the same time to avoid deadlock.
95     std::mutex mStatsLock;
96     //  We don't want mStats to grow unboundedly in memory. This constant limits amount of
97     //  information mStats can collect on the device.
98     size_t mMaxStatsEntries;
99     // Used to evict the least recently used wake lock stats entry in case mMaxStatsEntries is
100     // reached.
101     std::map<TimestampType, WakeLockIdType> mLruWakeLockId;
102     SystemSuspendStats mStats;
103 
104     // Amount of sleep time between consecutive iterations of the suspend loop.
105     std::chrono::milliseconds mBaseSleepTime;
106     std::chrono::milliseconds mSleepTime;
107     // Updates sleep time depending on the result of suspend attempt.
108     void updateSleepTime(bool success);
109 
110     sp<SuspendControlService> mControlService;
111 
112     // If true, use mSuspendCounter to keep track of native wake locks. Otherwise, rely on
113     // /sys/power/wake_lock interface to block suspend.
114     // TODO(b/128923994): remove dependency on /sys/power/wake_lock interface.
115     bool mUseSuspendCounter;
116     unique_fd mWakeLockFd;
117     unique_fd mWakeUnlockFd;
118 };
119 
120 }  // namespace V1_0
121 }  // namespace suspend
122 }  // namespace system
123 }  // namespace android
124 
125 #endif  // ANDROID_SYSTEM_SYSTEM_SUSPEND_V1_0_H
126