1 /* 2 * Copyright (C) 2017 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.wm; 18 19 import static android.os.Process.THREAD_PRIORITY_DISPLAY; 20 import static android.os.Process.myTid; 21 import static android.os.Process.setThreadPriority; 22 23 import static com.android.server.LockGuard.INDEX_WINDOW; 24 import static com.android.server.am.ActivityManagerService.TOP_APP_PRIORITY_BOOST; 25 26 import com.android.internal.annotations.GuardedBy; 27 import com.android.server.AnimationThread; 28 import com.android.server.ThreadPriorityBooster; 29 30 /** 31 * Window manager version of {@link ThreadPriorityBooster} that boosts even more during app 32 * transitions. 33 */ 34 class WindowManagerThreadPriorityBooster extends ThreadPriorityBooster { 35 36 private final Object mLock = new Object(); 37 38 private final int mAnimationThreadId; 39 private final int mSurfaceAnimationThreadId; 40 41 @GuardedBy("mLock") 42 private boolean mAppTransitionRunning; 43 @GuardedBy("mLock") 44 private boolean mBoundsAnimationRunning; 45 WindowManagerThreadPriorityBooster()46 WindowManagerThreadPriorityBooster() { 47 super(THREAD_PRIORITY_DISPLAY, INDEX_WINDOW); 48 mAnimationThreadId = AnimationThread.get().getThreadId(); 49 mSurfaceAnimationThreadId = SurfaceAnimationThread.get().getThreadId(); 50 } 51 52 @Override boost()53 public void boost() { 54 55 // Do not boost the animation threads. As the animation threads are changing priorities, 56 // boosting it might mess up the priority because we reset it the the previous priority. 57 final int myTid = myTid(); 58 if (myTid == mAnimationThreadId || myTid == mSurfaceAnimationThreadId) { 59 return; 60 } 61 super.boost(); 62 } 63 64 @Override reset()65 public void reset() { 66 67 // See comment in boost(). 68 final int myTid = myTid(); 69 if (myTid == mAnimationThreadId || myTid == mSurfaceAnimationThreadId) { 70 return; 71 } 72 super.reset(); 73 } 74 setAppTransitionRunning(boolean running)75 void setAppTransitionRunning(boolean running) { 76 synchronized (mLock) { 77 if (mAppTransitionRunning != running) { 78 mAppTransitionRunning = running; 79 updatePriorityLocked(); 80 } 81 } 82 } 83 setBoundsAnimationRunning(boolean running)84 void setBoundsAnimationRunning(boolean running) { 85 synchronized (mLock) { 86 if (mBoundsAnimationRunning != running) { 87 mBoundsAnimationRunning = running; 88 updatePriorityLocked(); 89 } 90 } 91 } 92 93 @GuardedBy("mLock") updatePriorityLocked()94 private void updatePriorityLocked() { 95 int priority = (mAppTransitionRunning || mBoundsAnimationRunning) 96 ? TOP_APP_PRIORITY_BOOST : THREAD_PRIORITY_DISPLAY; 97 setBoostToPriority(priority); 98 setThreadPriority(mAnimationThreadId, priority); 99 setThreadPriority(mSurfaceAnimationThreadId, priority); 100 } 101 } 102