1144bfe739b93afdee0a1700a34806b0b287e5887Andy Huangpackage com.android.mail.utils; 2144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 3144bfe739b93afdee0a1700a34806b0b287e5887Andy Huangimport android.os.Handler; 4144bfe739b93afdee0a1700a34806b0b287e5887Andy Huangimport android.view.View; 5144bfe739b93afdee0a1700a34806b0b287e5887Andy Huangimport android.view.ViewTreeObserver; 6144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 7144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang/** 8144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang * Given a View to monitor draws on, an instance of this class will notify a listener of state 9144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang * changes between {@link #STATE_ACTIVE} and {@link #STATE_IDLE}. 10144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang * <p> 11144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang * Any drawing will instantly trigger {@link #STATE_ACTIVE}. {@link #STATE_IDLE} is only 12144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang * subsequently triggered if {@link #IDLE_WINDOW_MS} continuous milliseconds elapse with zero draws. 13144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang */ 14144bfe739b93afdee0a1700a34806b0b287e5887Andy Huangpublic class DrawIdler { 15144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 16144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public static final int STATE_IDLE = 0; 17144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public static final int STATE_ACTIVE = 1; 18144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 19144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private static final int IDLE_WINDOW_MS = 100; 20144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 21144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private int mState = STATE_IDLE; 22144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 23144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private View mRoot; 24144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private IdleListener mListener; 25144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private final IdleReader mIdleReader = new IdleReader(); 26144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private final Handler mHandler = new Handler(); 27144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 28144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public interface IdleListener { 29144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang void onStateChanged(DrawIdler idler, int newState); 30144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 31144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 32144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public void setListener(IdleListener listener) { 33144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mListener = listener; 34144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang if (mListener != null) { 35144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mListener.onStateChanged(this, mState); 36144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 37144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 38144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 39144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public void setRootView(View rootView) { 40144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang if (mRoot == rootView) { 41144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang return; 42144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } else if (mRoot != null) { 43144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mRoot.getViewTreeObserver().removeOnPreDrawListener(mIdleReader); 44144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 45144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 46144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mRoot = rootView; 47144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 48144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang if (mRoot != null) { 49144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mRoot.getViewTreeObserver().addOnPreDrawListener(mIdleReader); 50144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 51144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 52144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 53144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public int getCurrentState() { 54144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang return mState; 55144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 56144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 57144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private void setState(int newState) { 58144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang if (mState == newState) { 59144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang return; 60144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 61144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mState = newState; 62144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang if (mListener != null) { 63144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mListener.onStateChanged(this, newState); 64144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 65144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 66144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 67144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang // this inner class keeps implementation details private 68144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang // (we use OnPreDrawListener instead of OnDrawListener because the latter is only JB+) 69144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang private class IdleReader implements Runnable, ViewTreeObserver.OnPreDrawListener { 70144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 71144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang @Override 72144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public void run() { 73144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang setState(STATE_IDLE); 74144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 75144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 76144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang @Override 77144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang public boolean onPreDraw() { 78144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang setState(STATE_ACTIVE); 79144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mHandler.removeCallbacks(this); 80144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang mHandler.postDelayed(this, IDLE_WINDOW_MS); 81144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang return true; // always allow the draw; we're only here to observe 82144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 83144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 84144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang } 85144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang 86144bfe739b93afdee0a1700a34806b0b287e5887Andy Huang} 87