Home | History | Annotate | Download | only in misc
      1 /*
      2  * Copyright (C) 2014 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.recents.misc;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.content.Context;
     22 
     23 import java.util.ArrayList;
     24 
     25 /**
     26  * A ref counted trigger that does some logic when the count is first incremented, or last
     27  * decremented.  Not thread safe as it's not currently needed.
     28  */
     29 public class ReferenceCountedTrigger {
     30 
     31     Context mContext;
     32     int mCount;
     33     ArrayList<Runnable> mFirstIncRunnables = new ArrayList<Runnable>();
     34     ArrayList<Runnable> mLastDecRunnables = new ArrayList<Runnable>();
     35     Runnable mErrorRunnable;
     36 
     37     // Convenience runnables
     38     Runnable mIncrementRunnable = new Runnable() {
     39         @Override
     40         public void run() {
     41             increment();
     42         }
     43     };
     44     Runnable mDecrementRunnable = new Runnable() {
     45         @Override
     46         public void run() {
     47             decrement();
     48         }
     49     };
     50 
     51     public ReferenceCountedTrigger(Context context, Runnable firstIncRunnable,
     52                                    Runnable lastDecRunnable, Runnable errorRunanable) {
     53         mContext = context;
     54         if (firstIncRunnable != null) mFirstIncRunnables.add(firstIncRunnable);
     55         if (lastDecRunnable != null) mLastDecRunnables.add(lastDecRunnable);
     56         mErrorRunnable = errorRunanable;
     57     }
     58 
     59     /** Increments the ref count */
     60     public void increment() {
     61         if (mCount == 0 && !mFirstIncRunnables.isEmpty()) {
     62             int numRunnables = mFirstIncRunnables.size();
     63             for (int i = 0; i < numRunnables; i++) {
     64                 mFirstIncRunnables.get(i).run();
     65             }
     66         }
     67         mCount++;
     68     }
     69 
     70     /** Convenience method to increment this trigger as a runnable */
     71     public Runnable incrementAsRunnable() {
     72         return mIncrementRunnable;
     73     }
     74 
     75     /** Adds a runnable to the last-decrement runnables list. */
     76     public void addLastDecrementRunnable(Runnable r) {
     77         // To ensure that the last decrement always calls, we increment and decrement after setting
     78         // the last decrement runnable
     79         boolean ensureLastDecrement = (mCount == 0);
     80         if (ensureLastDecrement) increment();
     81         mLastDecRunnables.add(r);
     82         if (ensureLastDecrement) decrement();
     83     }
     84 
     85     /** Decrements the ref count */
     86     public void decrement() {
     87         mCount--;
     88         if (mCount == 0 && !mLastDecRunnables.isEmpty()) {
     89             int numRunnables = mLastDecRunnables.size();
     90             for (int i = 0; i < numRunnables; i++) {
     91                 mLastDecRunnables.get(i).run();
     92             }
     93         } else if (mCount < 0) {
     94             if (mErrorRunnable != null) {
     95                 mErrorRunnable.run();
     96             } else {
     97                 new Throwable("Invalid ref count").printStackTrace();
     98                 Console.logError(mContext, "Invalid ref count");
     99             }
    100         }
    101     }
    102 
    103     /** Convenience method to decrement this trigger as a runnable. */
    104     public Runnable decrementAsRunnable() {
    105         return mDecrementRunnable;
    106     }
    107     /** Convenience method to decrement this trigger as a animator listener. */
    108     public Animator.AnimatorListener decrementOnAnimationEnd() {
    109         return new AnimatorListenerAdapter() {
    110             @Override
    111             public void onAnimationEnd(Animator animation) {
    112                 decrement();
    113             }
    114         };
    115     }
    116 
    117     /** Returns the current ref count */
    118     public int getCount() {
    119         return mCount;
    120     }
    121 }
    122