1 /*
2  * Copyright (C) 2019 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 package com.android.server;
18 
19 import static android.os.Process.getThreadPriority;
20 import static android.os.Process.myTid;
21 import static android.os.Process.setThreadPriority;
22 
23 import static org.junit.Assert.assertEquals;
24 
25 import android.os.Process;
26 import android.platform.test.annotations.Presubmit;
27 
28 import androidx.test.filters.SmallTest;
29 
30 import org.junit.Test;
31 
32 /**
33  * Tests for {@link ThreadPriorityBooster}.
34  * Build/Install/Run:
35  *  atest FrameworksServicesTests:ThreadPriorityBoosterTest
36  */
37 @SmallTest
38 @Presubmit
39 public class ThreadPriorityBoosterTest {
40     private static final int PRIORITY_BOOST = Process.THREAD_PRIORITY_FOREGROUND;
41     private static final int PRIORITY_BOOST_MORE = Process.THREAD_PRIORITY_DISPLAY;
42 
43     private final ThreadPriorityBooster mBooster = new ThreadPriorityBooster(PRIORITY_BOOST,
44             0 /* lockGuardIndex */);
45 
46     @Test
testThreadPriorityBooster()47     public void testThreadPriorityBooster() {
48         joinNewThread(() -> {
49             final int origPriority = Process.THREAD_PRIORITY_DEFAULT;
50             setThreadPriority(origPriority);
51 
52             boost(() -> {
53                 assertThreadPriority(PRIORITY_BOOST);
54                 boost(() -> {
55                     // Inside the boost region, the priority should also apply to current thread.
56                     mBooster.setBoostToPriority(PRIORITY_BOOST_MORE);
57                     assertThreadPriority(PRIORITY_BOOST_MORE);
58                 });
59                 // It is still in the boost region so the set priority should be kept.
60                 assertThreadPriority(PRIORITY_BOOST_MORE);
61 
62                 joinNewThread(() -> boost(() -> assertThreadPriority(PRIORITY_BOOST_MORE)));
63             });
64             // The priority should be restored after leaving the boost region.
65             assertThreadPriority(origPriority);
66 
67             // It doesn't apply to current thread because outside of the boost region, but the boost
68             // in other threads will use the set priority.
69             mBooster.setBoostToPriority(PRIORITY_BOOST);
70             joinNewThread(() -> boost(() -> assertThreadPriority(PRIORITY_BOOST)));
71 
72             assertThreadPriority(origPriority);
73         });
74     }
75 
assertThreadPriority(int expectedPriority)76     private static void assertThreadPriority(int expectedPriority) {
77         assertEquals(expectedPriority, getThreadPriority(myTid()));
78     }
79 
joinNewThread(Runnable action)80     private static void joinNewThread(Runnable action) {
81         final Thread thread = new Thread(action);
82         thread.start();
83         try {
84             thread.join();
85         } catch (InterruptedException ignored) {
86         }
87     }
88 
boost(Runnable action)89     private void boost(Runnable action) {
90         try {
91             mBooster.boost();
92             action.run();
93         } finally {
94             mBooster.reset();
95         }
96     }
97 }
98