1bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette/* 2bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * Copyright (C) 2015 The Android Open Source Project 3bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * 4bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 5bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * you may not use this file except in compliance with the License. 6bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * You may obtain a copy of the License at 7bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * 8bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * http://www.apache.org/licenses/LICENSE-2.0 9bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * 10bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * Unless required by applicable law or agreed to in writing, software 11bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 12bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * See the License for the specific language governing permissions and 14bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * limitations under the License. 15bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette */ 16bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 17bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverettepackage android.view; 18bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 19bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viveretteimport com.android.internal.util.GrowingArrayUtils; 20bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 21bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viveretteimport android.os.Handler; 22bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 23bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viveretteimport java.util.ArrayList; 24bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 25bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette/** 26bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * Class used to enqueue pending work from Views when no Handler is attached. 27bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * 28bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * @hide Exposed for test framework only. 29bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette */ 30bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverettepublic class HandlerActionQueue { 31bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette private HandlerAction[] mActions; 32bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette private int mCount; 33bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 34bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void post(Runnable action) { 35bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette postDelayed(action, 0); 36bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 37bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 38bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void postDelayed(Runnable action, long delayMillis) { 39bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction handlerAction = new HandlerAction(action, delayMillis); 40bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 41bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette synchronized (this) { 42bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (mActions == null) { 43bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mActions = new HandlerAction[4]; 44bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 45bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction); 46bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mCount++; 47bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 48bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 49bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 50bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void removeCallbacks(Runnable action) { 51bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette synchronized (this) { 52bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final int count = mCount; 53bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette int j = 0; 54bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 55bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction[] actions = mActions; 56bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette for (int i = 0; i < count; i++) { 57bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (actions[i].matches(action)) { 58bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // Remove this action by overwriting it within 59bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // this loop or nulling it out later. 60bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette continue; 61bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 62bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 63bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (j != i) { 64bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // At least one previous entry was removed, so 65bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // this one needs to move to the "new" list. 66bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette actions[j] = actions[i]; 67bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 68bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 69bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette j++; 70bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 71bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 72bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // The "new" list only has j entries. 73bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mCount = j; 74bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 75bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // Null out any remaining entries. 76bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette for (; j < count; j++) { 77bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette actions[j] = null; 78bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 79bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 80bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 81bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 82bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void executeActions(Handler handler) { 83bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette synchronized (this) { 84bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction[] actions = mActions; 85bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette for (int i = 0, count = mCount; i < count; i++) { 86bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction handlerAction = actions[i]; 87bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette handler.postDelayed(handlerAction.action, handlerAction.delay); 88bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 89bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 90bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mActions = null; 91bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mCount = 0; 92bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 93bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 94bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 95bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public int size() { 96bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return mCount; 97bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 98bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 99bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public Runnable getRunnable(int index) { 100bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (index >= mCount) { 101bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette throw new IndexOutOfBoundsException(); 102bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 103bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return mActions[index].action; 104bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 105bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 106bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public long getDelay(int index) { 107bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (index >= mCount) { 108bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette throw new IndexOutOfBoundsException(); 109bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 110bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return mActions[index].delay; 111bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 112bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 113bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette private static class HandlerAction { 114bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final Runnable action; 115bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final long delay; 116bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 117bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public HandlerAction(Runnable action, long delay) { 118bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette this.action = action; 119bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette this.delay = delay; 120bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 121bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 122bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public boolean matches(Runnable otherAction) { 123bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return otherAction == null && action == null 124bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette || action != null && action.equals(otherAction); 125bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 126bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 127bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette} 128