• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #pragma once
18 
19 #include <aidl/android/hardware/power/BnPowerHintSession.h>
20 #include <aidl/android/hardware/power/SessionHint.h>
21 #include <aidl/android/hardware/power/WorkDuration.h>
22 #include <utils/Looper.h>
23 #include <utils/Thread.h>
24 
25 #include <mutex>
26 #include <unordered_map>
27 
28 namespace aidl {
29 namespace google {
30 namespace hardware {
31 namespace power {
32 namespace impl {
33 namespace pixel {
34 
35 using aidl::android::hardware::power::BnPowerHintSession;
36 using aidl::android::hardware::power::SessionHint;
37 using aidl::android::hardware::power::WorkDuration;
38 using ::android::Message;
39 using ::android::MessageHandler;
40 using ::android::sp;
41 using std::chrono::milliseconds;
42 using std::chrono::nanoseconds;
43 using std::chrono::steady_clock;
44 using std::chrono::time_point;
45 
46 struct AppHintDesc {
AppHintDescAppHintDesc47     AppHintDesc(int32_t tgid, int32_t uid, std::vector<int32_t> threadIds)
48         : tgid(tgid),
49           uid(uid),
50           threadIds(std::move(threadIds)),
51           duration(0LL),
52           current_min(0),
53           is_active(true),
54           update_count(0),
55           integral_error(0),
56           previous_error(0) {}
57     std::string toString() const;
58     const int32_t tgid;
59     const int32_t uid;
60     std::vector<int32_t> threadIds;
61     nanoseconds duration;
62     int current_min;
63     // status
64     std::atomic<bool> is_active;
65     // pid
66     uint64_t update_count;
67     int64_t integral_error;
68     int64_t previous_error;
69 };
70 
71 class PowerHintSession : public BnPowerHintSession {
72   public:
73     explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
74                               int64_t durationNanos);
75     ~PowerHintSession();
76     ndk::ScopedAStatus close() override;
77     ndk::ScopedAStatus pause() override;
78     ndk::ScopedAStatus resume() override;
79     ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override;
80     ndk::ScopedAStatus reportActualWorkDuration(
81             const std::vector<WorkDuration> &actualDurations) override;
82     ndk::ScopedAStatus sendHint(SessionHint hint) override;
83     ndk::ScopedAStatus setThreads(const std::vector<int32_t> &threadIds) override;
84     bool isActive();
85     bool isTimeout();
86     void setStale();
87     // Is this hint session for a user application
88     bool isAppSession();
89     const std::vector<int> &getTidList() const;
90     int getUclampMin();
91     void dumpToStream(std::ostream &stream);
92 
93     // Disable any temporary boost and return to normal operation. It does not
94     // reset the actual uclamp value, and relies on the caller to do so, to
95     // prevent double-setting. Returns true if it actually disabled an active boost
96     bool disableTemporaryBoost();
97 
98   private:
99     class SessionTimerHandler : public MessageHandler {
100       public:
SessionTimerHandler(PowerHintSession * session,std::string name)101         SessionTimerHandler(PowerHintSession *session, std::string name)
102             : mSession(session), mIsSessionDead(false), mName(name) {}
103         void updateTimer(nanoseconds delay);
104         void handleMessage(const Message &message) override;
105         void setSessionDead();
106         virtual void onTimeout() = 0;
107 
108       protected:
109         PowerHintSession *mSession;
110         std::mutex mClosedLock;
111         std::mutex mMessageLock;
112         std::atomic<time_point<steady_clock>> mTimeout;
113         bool mIsSessionDead;
114         const std::string mName;
115     };
116 
117     class StaleTimerHandler : public SessionTimerHandler {
118       public:
StaleTimerHandler(PowerHintSession * session)119         StaleTimerHandler(PowerHintSession *session) : SessionTimerHandler(session, "stale") {}
120         void updateTimer();
121         void onTimeout() override;
122     };
123 
124     class BoostTimerHandler : public SessionTimerHandler {
125       public:
BoostTimerHandler(PowerHintSession * session)126         BoostTimerHandler(PowerHintSession *session) : SessionTimerHandler(session, "boost") {}
127         void onTimeout() override;
128     };
129 
130   private:
131     void updateUniveralBoostMode();
132     int setSessionUclampMin(int32_t min, bool resetStale = true);
133     void tryToSendPowerHint(std::string hint);
134     int64_t convertWorkDurationToBoostByPid(const std::vector<WorkDuration> &actualDurations);
135     void traceSessionVal(char const *identifier, int64_t val) const;
136     AppHintDesc *mDescriptor = nullptr;
137     sp<StaleTimerHandler> mStaleTimerHandler;
138     sp<BoostTimerHandler> mBoostTimerHandler;
139     std::atomic<time_point<steady_clock>> mLastUpdatedTime;
140     sp<MessageHandler> mPowerManagerHandler;
141     std::mutex mSessionLock;
142     std::atomic<bool> mSessionClosed = false;
143     std::string mIdString;
144     // Used when setting a temporary boost value to hold the true boost
145     std::atomic<std::optional<int>> mNextUclampMin;
146     // To cache the status of whether ADPF hints are supported.
147     std::unordered_map<std::string, std::optional<bool>> mSupportedHints;
148     // Last session hint sent, used for logging
149     int mLastHintSent = -1;
150 };
151 
152 }  // namespace pixel
153 }  // namespace impl
154 }  // namespace power
155 }  // namespace hardware
156 }  // namespace google
157 }  // namespace aidl
158