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 android.os.Handler; 20bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 2167e2ae86396c6d0f989285275cbf908dee5e71f7Aurimas Liutikasimport com.android.internal.util.GrowingArrayUtils; 22bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 23bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette/** 24bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * Class used to enqueue pending work from Views when no Handler is attached. 25bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * 26bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette * @hide Exposed for test framework only. 27bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette */ 28bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverettepublic class HandlerActionQueue { 29bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette private HandlerAction[] mActions; 30bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette private int mCount; 31bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 32bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void post(Runnable action) { 33bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette postDelayed(action, 0); 34bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 35bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 36bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void postDelayed(Runnable action, long delayMillis) { 37bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction handlerAction = new HandlerAction(action, delayMillis); 38bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 39bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette synchronized (this) { 40bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (mActions == null) { 41bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mActions = new HandlerAction[4]; 42bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 43bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction); 44bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mCount++; 45bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 46bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 47bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 48bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void removeCallbacks(Runnable action) { 49bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette synchronized (this) { 50bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final int count = mCount; 51bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette int j = 0; 52bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 53bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction[] actions = mActions; 54bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette for (int i = 0; i < count; i++) { 55bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (actions[i].matches(action)) { 56bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // Remove this action by overwriting it within 57bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // this loop or nulling it out later. 58bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette continue; 59bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 60bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 61bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (j != i) { 62bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // At least one previous entry was removed, so 63bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // this one needs to move to the "new" list. 64bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette actions[j] = actions[i]; 65bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 66bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 67bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette j++; 68bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 69bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 70bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // The "new" list only has j entries. 71bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mCount = j; 72bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 73bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette // Null out any remaining entries. 74bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette for (; j < count; j++) { 75bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette actions[j] = null; 76bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 77bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 78bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 79bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 80bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public void executeActions(Handler handler) { 81bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette synchronized (this) { 82bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction[] actions = mActions; 83bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette for (int i = 0, count = mCount; i < count; i++) { 84bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final HandlerAction handlerAction = actions[i]; 85bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette handler.postDelayed(handlerAction.action, handlerAction.delay); 86bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 87bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 88bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mActions = null; 89bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette mCount = 0; 90bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 91bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 92bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 93bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public int size() { 94bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return mCount; 95bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 96bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 97bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public Runnable getRunnable(int index) { 98bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (index >= mCount) { 99bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette throw new IndexOutOfBoundsException(); 100bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 101bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return mActions[index].action; 102bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 103bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 104bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public long getDelay(int index) { 105bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette if (index >= mCount) { 106bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette throw new IndexOutOfBoundsException(); 107bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 108bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return mActions[index].delay; 109bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 110bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 111bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette private static class HandlerAction { 112bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final Runnable action; 113bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette final long delay; 114bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 115bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public HandlerAction(Runnable action, long delay) { 116bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette this.action = action; 117bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette this.delay = delay; 118bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 119bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette 120bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette public boolean matches(Runnable otherAction) { 121bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette return otherAction == null && action == null 122bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette || action != null && action.equals(otherAction); 123bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 124bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette } 125bea0c7daa6611d8b96e1271f8854f500a87342fcAlan Viverette} 126