1/* 2 * Copyright (C) 2015 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 */ 16package com.android.internal.util; 17 18import junit.framework.TestCase; 19 20import org.junit.Test; 21 22import java.util.ArrayList; 23 24import static org.junit.Assert.assertEquals; 25import static org.junit.Assert.assertFalse; 26import static org.junit.Assert.assertNotNull; 27import static org.junit.Assert.assertTrue; 28 29public class CallbackRegistryTest extends TestCase { 30 31 final Integer callback1 = 1; 32 final Integer callback2 = 2; 33 final Integer callback3 = 3; 34 CallbackRegistry<Integer, CallbackRegistryTest, Integer> registry; 35 int notify1; 36 int notify2; 37 int notify3; 38 int[] deepNotifyCount = new int[300]; 39 Integer argValue; 40 41 private void addNotifyCount(Integer callback) { 42 if (callback == callback1) { 43 notify1++; 44 } else if (callback == callback2) { 45 notify2++; 46 } else if (callback == callback3) { 47 notify3++; 48 } 49 deepNotifyCount[callback]++; 50 } 51 52 public void testAddListener() { 53 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 54 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 55 @Override 56 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 57 int arg, Integer arg2) { 58 } 59 }; 60 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 61 Integer callback = 0; 62 63 assertNotNull(registry.copyListeners()); 64 assertEquals(0, registry.copyListeners().size()); 65 66 registry.add(callback); 67 ArrayList<Integer> callbacks = registry.copyListeners(); 68 assertEquals(1, callbacks.size()); 69 assertEquals(callback, callbacks.get(0)); 70 71 registry.add(callback); 72 callbacks = registry.copyListeners(); 73 assertEquals(1, callbacks.size()); 74 assertEquals(callback, callbacks.get(0)); 75 76 Integer otherListener = 1; 77 registry.add(otherListener); 78 callbacks = registry.copyListeners(); 79 assertEquals(2, callbacks.size()); 80 assertEquals(callback, callbacks.get(0)); 81 assertEquals(otherListener, callbacks.get(1)); 82 83 registry.remove(callback); 84 registry.add(callback); 85 callbacks = registry.copyListeners(); 86 assertEquals(2, callbacks.size()); 87 assertEquals(callback, callbacks.get(1)); 88 assertEquals(otherListener, callbacks.get(0)); 89 } 90 91 public void testSimpleNotify() { 92 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 93 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 94 @Override 95 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 96 int arg1, Integer arg) { 97 assertEquals(arg1, (int) arg); 98 addNotifyCount(callback); 99 argValue = arg; 100 } 101 }; 102 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 103 registry.add(callback2); 104 Integer arg = 1; 105 registry.notifyCallbacks(this, arg, arg); 106 assertEquals(arg, argValue); 107 assertEquals(1, notify2); 108 } 109 110 public void testRemoveWhileNotifying() { 111 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 112 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 113 @Override 114 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 115 int arg1, Integer arg) { 116 addNotifyCount(callback); 117 if (callback == callback1) { 118 registry.remove(callback1); 119 registry.remove(callback2); 120 } 121 } 122 }; 123 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 124 registry.add(callback1); 125 registry.add(callback2); 126 registry.add(callback3); 127 registry.notifyCallbacks(this, 0, null); 128 assertEquals(1, notify1); 129 assertEquals(1, notify2); 130 assertEquals(1, notify3); 131 132 ArrayList<Integer> callbacks = registry.copyListeners(); 133 assertEquals(1, callbacks.size()); 134 assertEquals(callback3, callbacks.get(0)); 135 } 136 137 public void testDeepRemoveWhileNotifying() { 138 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 139 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 140 @Override 141 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 142 int arg1, Integer arg) { 143 addNotifyCount(callback); 144 registry.remove(callback); 145 registry.notifyCallbacks(CallbackRegistryTest.this, arg1, null); 146 } 147 }; 148 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 149 registry.add(callback1); 150 registry.add(callback2); 151 registry.add(callback3); 152 registry.notifyCallbacks(this, 0, null); 153 assertEquals(1, notify1); 154 assertEquals(2, notify2); 155 assertEquals(3, notify3); 156 157 ArrayList<Integer> callbacks = registry.copyListeners(); 158 assertEquals(0, callbacks.size()); 159 } 160 161 public void testAddRemovedListener() { 162 163 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 164 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 165 @Override 166 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 167 int arg1, Integer arg) { 168 addNotifyCount(callback); 169 if (callback == callback1) { 170 registry.remove(callback2); 171 } else if (callback == callback3) { 172 registry.add(callback2); 173 } 174 } 175 }; 176 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 177 178 registry.add(callback1); 179 registry.add(callback2); 180 registry.add(callback3); 181 registry.notifyCallbacks(this, 0, null); 182 183 ArrayList<Integer> callbacks = registry.copyListeners(); 184 assertEquals(3, callbacks.size()); 185 assertEquals(callback1, callbacks.get(0)); 186 assertEquals(callback3, callbacks.get(1)); 187 assertEquals(callback2, callbacks.get(2)); 188 assertEquals(1, notify1); 189 assertEquals(1, notify2); 190 assertEquals(1, notify3); 191 } 192 193 public void testVeryDeepRemoveWhileNotifying() { 194 final Integer[] callbacks = new Integer[deepNotifyCount.length]; 195 for (int i = 0; i < callbacks.length; i++) { 196 callbacks[i] = i; 197 } 198 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 199 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 200 @Override 201 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 202 int arg1, Integer arg) { 203 addNotifyCount(callback); 204 registry.remove(callback); 205 registry.remove(callbacks[callbacks.length - callback - 1]); 206 registry.notifyCallbacks(CallbackRegistryTest.this, arg1, null); 207 } 208 }; 209 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 210 for (int i = 0; i < callbacks.length; i++) { 211 registry.add(callbacks[i]); 212 } 213 registry.notifyCallbacks(this, 0, null); 214 for (int i = 0; i < deepNotifyCount.length; i++) { 215 int expectedCount = Math.min(i + 1, deepNotifyCount.length - i); 216 assertEquals(expectedCount, deepNotifyCount[i]); 217 } 218 219 ArrayList<Integer> callbackList = registry.copyListeners(); 220 assertEquals(0, callbackList.size()); 221 } 222 223 public void testClear() { 224 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 225 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 226 @Override 227 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 228 int arg1, Integer arg) { 229 addNotifyCount(callback); 230 } 231 }; 232 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 233 for (int i = 0; i < deepNotifyCount.length; i++) { 234 registry.add(i); 235 } 236 registry.clear(); 237 238 ArrayList<Integer> callbackList = registry.copyListeners(); 239 assertEquals(0, callbackList.size()); 240 241 registry.notifyCallbacks(this, 0, null); 242 for (int i = 0; i < deepNotifyCount.length; i++) { 243 assertEquals(0, deepNotifyCount[i]); 244 } 245 } 246 247 public void testNestedClear() { 248 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 249 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 250 @Override 251 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 252 int arg1, Integer arg) { 253 addNotifyCount(callback); 254 registry.clear(); 255 } 256 }; 257 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 258 for (int i = 0; i < deepNotifyCount.length; i++) { 259 registry.add(i); 260 } 261 registry.notifyCallbacks(this, 0, null); 262 for (int i = 0; i < deepNotifyCount.length; i++) { 263 assertEquals(1, deepNotifyCount[i]); 264 } 265 266 ArrayList<Integer> callbackList = registry.copyListeners(); 267 assertEquals(0, callbackList.size()); 268 } 269 270 public void testIsEmpty() throws Exception { 271 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 272 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 273 @Override 274 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 275 int arg, Integer arg2) { 276 } 277 }; 278 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 279 Integer callback = 0; 280 281 assertTrue(registry.isEmpty()); 282 registry.add(callback); 283 assertFalse(registry.isEmpty()); 284 } 285 286 public void testClone() throws Exception { 287 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 288 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 289 @Override 290 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 291 int arg, Integer arg2) { 292 } 293 }; 294 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 295 296 assertTrue(registry.isEmpty()); 297 CallbackRegistry<Integer, CallbackRegistryTest, Integer> registry2 = registry.clone(); 298 Integer callback = 0; 299 registry.add(callback); 300 assertFalse(registry.isEmpty()); 301 assertTrue(registry2.isEmpty()); 302 registry2 = registry.clone(); 303 assertFalse(registry2.isEmpty()); 304 } 305} 306