1527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal/** 2527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * Copyright (C) 2015 The Android Open Source Project 3527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * 4527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * Licensed under the Apache License, Version 2.0 (the "License"); 5527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * you may not use this file except in compliance with the License. 6527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * You may obtain a copy of the License at 7527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * 8527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * http://www.apache.org/licenses/LICENSE-2.0 9527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * 10527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * Unless required by applicable law or agreed to in writing, software 11527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * distributed under the License is distributed on an "AS IS" BASIS, 12527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * See the License for the specific language governing permissions and 14527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * limitations under the License. 15527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal */ 16527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 17527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalpackage com.android.launcher3.util; 18527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 19b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyalimport android.util.Log; 20527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport android.view.View; 21527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport android.view.View.OnAttachStateChangeListener; 22527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport android.view.ViewTreeObserver.OnDrawListener; 23527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 24527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport com.android.launcher3.DeferredHandler; 25527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport com.android.launcher3.Launcher; 26527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 27527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport java.util.ArrayList; 28527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport java.util.concurrent.Executor; 29527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 30527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal/** 31527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal * An executor which runs all the tasks after the first onDraw is called on the target view. 32527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal */ 33527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalpublic class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable, 34527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal OnAttachStateChangeListener { 35527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 36527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal private final ArrayList<Runnable> mTasks = new ArrayList<>(); 37527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal private final DeferredHandler mHandler; 38527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 39527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal private Launcher mLauncher; 40527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal private View mAttachedView; 41527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal private boolean mCompleted; 42527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 43b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal private boolean mLoadAnimationCompleted; 44b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal private boolean mFirstDrawCompleted; 45b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal 46527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public ViewOnDrawExecutor(DeferredHandler handler) { 47527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mHandler = handler; 48527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 49527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 50527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void attachTo(Launcher launcher) { 51527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mLauncher = launcher; 52527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mAttachedView = launcher.getWorkspace(); 53527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mAttachedView.addOnAttachStateChangeListener(this); 54527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 55527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal attachObserver(); 56527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 57527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 58527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal private void attachObserver() { 59527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal if (!mCompleted) { 60527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mAttachedView.getViewTreeObserver().addOnDrawListener(this); 61527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 62527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 63527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 64527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Override 65527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void execute(Runnable command) { 66527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mTasks.add(command); 67527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 68527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 69527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Override 70527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void onViewAttachedToWindow(View v) { 71527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal attachObserver(); 72527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 73527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 74527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Override 75527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void onViewDetachedFromWindow(View v) { } 76527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 77527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Override 78527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void onDraw() { 79b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal mFirstDrawCompleted = true; 80527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mAttachedView.post(this); 81527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 82527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 83b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal public void onLoadAnimationCompleted() { 84b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal mLoadAnimationCompleted = true; 85b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal if (mAttachedView != null) { 86b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal mAttachedView.post(this); 87b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal } 88b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal } 89b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal 90527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Override 91527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void run() { 92b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called. 93b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) { 94b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal for (final Runnable r : mTasks) { 95b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal mHandler.post(r); 96b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal } 97b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal markCompleted(); 98527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 99527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 100527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 101527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void markCompleted() { 102527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mTasks.clear(); 103b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal mCompleted = true; 104527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal if (mAttachedView != null) { 105527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mAttachedView.getViewTreeObserver().removeOnDrawListener(this); 106527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mAttachedView.removeOnAttachStateChangeListener(this); 107527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 108527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal if (mLauncher != null) { 109527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal mLauncher.clearPendingExecutor(this); 110527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 111527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 112527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal} 113