• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #include "src/android_internal/suspend_control_service.h"
18 
19 #include <string.h>
20 
21 #include <memory>
22 #include <vector>
23 
24 #include <android/system/suspend/internal/ISuspendControlServiceInternal.h>
25 
26 #include <binder/IServiceManager.h>
27 
28 namespace perfetto {
29 namespace android_internal {
30 
31 namespace aidl = android::system::suspend::internal;
32 
33 static android::sp<aidl::ISuspendControlServiceInternal> svc_ = nullptr;
34 
MaybeGetService()35 aidl::ISuspendControlServiceInternal* MaybeGetService() {
36   if (svc_ == nullptr) {
37     svc_ = android::waitForService<aidl::ISuspendControlServiceInternal>(
38         android::String16("suspend_control_internal"));
39   }
40   return svc_.get();
41 }
42 
ResetService()43 void ResetService() {
44   svc_.clear();
45 }
46 
GetKernelWakelocks(KernelWakelock * wakelock,size_t * size_of_arr)47 bool GetKernelWakelocks(KernelWakelock* wakelock, size_t* size_of_arr) {
48   const size_t in_array_size = *size_of_arr;
49   *size_of_arr = 0;
50 
51   aidl::ISuspendControlServiceInternal* svc = MaybeGetService();
52   if (svc == nullptr) {
53     return false;
54   }
55 
56   std::vector<aidl::WakeLockInfo> results;
57 
58   android::binder::Status status = svc->getWakeLockStatsFiltered(
59       aidl::ISuspendControlServiceInternal::WAKE_LOCK_INFO_TOTAL_TIME |
60           aidl::ISuspendControlServiceInternal::
61               WAKE_LOCK_INFO_IS_KERNEL_WAKELOCK,
62       &results);
63 
64   if (!status.isOk()) {
65     if (status.transactionError() == android::DEAD_OBJECT) {
66       auto& cur = wakelock[(*size_of_arr)++];
67       strlcpy(cur.wakelock_name, "dead", sizeof(cur.wakelock_name));
68       // Service has died.  Reset it to attempt to acquire a new one next time.
69       ResetService();
70     }
71     return false;
72   }
73 
74   size_t max_size = std::min(in_array_size, results.size());
75   for (const auto& result : results) {
76     if (*size_of_arr >= max_size) {
77       break;
78     }
79     auto& cur = wakelock[(*size_of_arr)++];
80     strlcpy(cur.wakelock_name, result.name.c_str(), sizeof(cur.wakelock_name));
81     cur.total_time_ms = result.totalTime;
82     cur.is_kernel = result.isKernelWakelock;
83   }
84   return true;
85 }
86 
87 }  // namespace android_internal
88 }  // namespace perfetto
89