Home | History | Annotate | Download | only in systemui
      1 /*
      2  * Copyright (C) 2015 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.systemui;
     18 
     19 import com.android.internal.annotations.VisibleForTesting;
     20 import com.android.systemui.util.Assert;
     21 
     22 import android.os.Handler;
     23 import android.view.Choreographer;
     24 
     25 import java.util.ArrayList;
     26 
     27 /**
     28  * Utility class for methods used to dejank the UI.
     29  */
     30 public class DejankUtils {
     31 
     32     private static final Choreographer sChoreographer = Choreographer.getInstance();
     33     private static final Handler sHandler = new Handler();
     34     private static final ArrayList<Runnable> sPendingRunnables = new ArrayList<>();
     35 
     36     /**
     37      * Only for testing.
     38      */
     39     private static boolean sImmediate;
     40 
     41     private static final Runnable sAnimationCallbackRunnable = new Runnable() {
     42         @Override
     43         public void run() {
     44             for (int i = 0; i < sPendingRunnables.size(); i++) {
     45                 sHandler.post(sPendingRunnables.get(i));
     46             }
     47             sPendingRunnables.clear();
     48         }
     49     };
     50 
     51     /**
     52      * Executes {@code r} after performTraversals. Use this do to CPU heavy work for which the
     53      * timing is not critical for animation. The work is then scheduled at the same time
     54      * RenderThread is doing its thing, leading to better parallelization.
     55      *
     56      * <p>Needs to be called from the main thread.
     57      */
     58     public static void postAfterTraversal(Runnable r) {
     59         if (sImmediate) {
     60             r.run();
     61             return;
     62         }
     63         Assert.isMainThread();
     64         sPendingRunnables.add(r);
     65         postAnimationCallback();
     66     }
     67 
     68     /**
     69      * Removes a previously scheduled runnable.
     70      *
     71      * <p>Needs to be called from the main thread.
     72      */
     73     public static void removeCallbacks(Runnable r) {
     74         Assert.isMainThread();
     75         sPendingRunnables.remove(r);
     76         sHandler.removeCallbacks(r);
     77     }
     78 
     79     private static void postAnimationCallback() {
     80         sChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, sAnimationCallbackRunnable,
     81                 null);
     82     }
     83 
     84     @VisibleForTesting
     85     public static void setImmediate(boolean immediate) {
     86         sImmediate = immediate;
     87     }
     88 }
     89