1 /**
2  * Copyright (c) 2022, 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/automotive/watchdog/internal/ThreadPolicyWithPriority.h>
20 #include <android-base/result.h>
21 
22 #include <sched.h>
23 
24 namespace android {
25 namespace automotive {
26 namespace watchdog {
27 
28 class ThreadPriorityControllerInterface {
29 public:
30     virtual ~ThreadPriorityControllerInterface() = default;
31     virtual android::base::Result<void> setThreadPriority(int pid, int tid, int uid, int policy,
32                                                           int priority) = 0;
33     virtual android::base::Result<void> getThreadPriority(
34             int pid, int tid, int uid,
35             aidl::android::automotive::watchdog::internal::ThreadPolicyWithPriority* result) = 0;
36 };
37 
38 class ThreadPriorityController final : public ThreadPriorityControllerInterface {
39 public:
40     // An interface for stubbing system calls in unit testing.
41     class SystemCallsInterface {
42     public:
43         virtual int setScheduler(pid_t tid, int policy, const sched_param* param) = 0;
44         virtual int getScheduler(pid_t tid) = 0;
45         virtual int getParam(pid_t tid, sched_param* param) = 0;
46         virtual android::base::Result<std::tuple<uid_t, pid_t>> readPidStatusFileForPid(
47                 pid_t pid) = 0;
48 
49         virtual ~SystemCallsInterface() = default;
50     };
51 
ThreadPriorityController()52     ThreadPriorityController() : mSystemCallsInterface(std::make_unique<SystemCalls>()) {}
53 
ThreadPriorityController(std::unique_ptr<SystemCallsInterface> s)54     explicit ThreadPriorityController(std::unique_ptr<SystemCallsInterface> s) :
55           mSystemCallsInterface(std::move(s)) {}
56 
57     android::base::Result<void> setThreadPriority(int pid, int tid, int uid, int policy,
58                                                   int priority) override;
59     android::base::Result<void> getThreadPriority(
60             int pid, int tid, int uid,
61             aidl::android::automotive::watchdog::internal::ThreadPolicyWithPriority* result)
62             override;
63 
64 private:
65     class SystemCalls final : public SystemCallsInterface {
66         int setScheduler(pid_t tid, int policy, const sched_param* param) override;
67         int getScheduler(pid_t tid) override;
68         int getParam(pid_t tid, sched_param* param) override;
69         android::base::Result<std::tuple<uid_t, pid_t>> readPidStatusFileForPid(pid_t pid) override;
70     };
71 
72     std::unique_ptr<SystemCallsInterface> mSystemCallsInterface;
73 
74     android::base::Result<void> checkPidTidUid(pid_t pid, pid_t tid, uid_t uid);
75 };
76 
77 }  // namespace watchdog
78 }  // namespace automotive
79 }  // namespace android
80