1 /*
2  * Copyright (C) 2012 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 #define LOG_TAG "SchedulingPolicyService"
18 //#define LOG_NDEBUG 0
19 
20 #include <audio_utils/threads.h>
21 #include <binder/IServiceManager.h>
22 #include <cutils/android_filesystem_config.h>
23 #include <cutils/properties.h>
24 #include <utils/Mutex.h>
25 #include "ISchedulingPolicyService.h"
26 #include "mediautils/SchedulingPolicyService.h"
27 
28 namespace android {
29 
30 static sp<ISchedulingPolicyService> sSchedulingPolicyService;
31 static const String16 _scheduling_policy("scheduling_policy");
32 static Mutex sMutex;
33 
requestPriority(pid_t pid,pid_t tid,int32_t prio,bool isForApp,bool asynchronous)34 int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool isForApp, bool asynchronous)
35 {
36     // audioserver thread priority boosted internally to reduce binder latency and boot time.
37     if (!isForApp && pid == getpid() && getuid() == AID_AUDIOSERVER && prio >= 1 && prio <= 3) {
38         const status_t status = audio_utils::set_thread_priority(
39                 tid, audio_utils::rtprio_to_unified_priority(prio));
40         if (status == NO_ERROR) return NO_ERROR;
41         ALOGD("%s: set priority %d, status:%d needs to fallback to SchedulingPolicyService",
42                 __func__, prio, status);
43     }
44 
45     // FIXME merge duplicated code related to service lookup, caching, and error recovery
46     int ret;
47     for (;;) {
48         sMutex.lock();
49         sp<ISchedulingPolicyService> sps = sSchedulingPolicyService;
50         sMutex.unlock();
51         if (sps == 0) {
52             sp<IBinder> binder = defaultServiceManager()->checkService(_scheduling_policy);
53             if (binder == 0) {
54                 sleep(1);
55                 continue;
56             }
57             sps = interface_cast<ISchedulingPolicyService>(binder);
58             sMutex.lock();
59             sSchedulingPolicyService = sps;
60             sMutex.unlock();
61         }
62         ret = sps->requestPriority(pid, tid, prio, isForApp, asynchronous);
63         if (ret != DEAD_OBJECT) {
64             break;
65         }
66         ALOGW("SchedulingPolicyService died");
67         sMutex.lock();
68         sSchedulingPolicyService.clear();
69         sMutex.unlock();
70     }
71     return ret;
72 }
73 
requestCpusetBoost(bool enable,const sp<IBinder> & client)74 int requestCpusetBoost(bool enable, const sp<IBinder> &client)
75 {
76     int ret;
77     sMutex.lock();
78     sp<ISchedulingPolicyService> sps = sSchedulingPolicyService;
79     sMutex.unlock();
80     if (sps == 0) {
81         sp<IBinder> binder = defaultServiceManager()->checkService(_scheduling_policy);
82         if (binder == 0) {
83             return DEAD_OBJECT;
84         }
85         sps = interface_cast<ISchedulingPolicyService>(binder);
86         sMutex.lock();
87         sSchedulingPolicyService = sps;
88         sMutex.unlock();
89     }
90     ret = sps->requestCpusetBoost(enable, client);
91     if (ret != DEAD_OBJECT) {
92         return ret;
93     }
94     ALOGW("SchedulingPolicyService died");
95     sMutex.lock();
96     sSchedulingPolicyService.clear();
97     sMutex.unlock();
98     return ret;
99 }
100 
requestSpatializerPriority(pid_t pid,pid_t tid)101 int requestSpatializerPriority(pid_t pid, pid_t tid) {
102     if (pid == -1 || tid == -1) return BAD_VALUE;
103 
104     // update priority to RT if specified.
105     constexpr int32_t kRTPriorityMin = 1;
106     constexpr int32_t kRTPriorityMax = 3;
107     const int32_t priorityBoost =
108             property_get_int32("audio.spatializer.priority", kRTPriorityMin);
109     if (priorityBoost >= kRTPriorityMin && priorityBoost <= kRTPriorityMax) {
110         const status_t status = requestPriority(
111                 pid, tid, priorityBoost, false /* isForApp */, true /*asynchronous*/);
112         if (status != OK) {
113             ALOGW("%s: Cannot request spatializer priority boost %d, status:%d",
114                     __func__, priorityBoost, status);
115             return status < 0 ? status : UNKNOWN_ERROR;
116         }
117         return priorityBoost;
118     }
119     return 0;  // no boost requested
120 }
121 
122 }   // namespace android
123