1e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos/* 2e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * Copyright (C) 2017 The Android Open Source Project 3e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * 4e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 5e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * you may not use this file except in compliance with the License. 6e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * You may obtain a copy of the License at 7e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * 8e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * http://www.apache.org/licenses/LICENSE-2.0 9e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * 10e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * Unless required by applicable law or agreed to in writing, software 11e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 12e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * See the License for the specific language governing permissions and 14e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * limitations under the License 15e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos */ 16e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 17e1e0b483be87d23383832aa6b558364a730c690fAdrian Roospackage com.android.systemui.util.leak; 18e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 19e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport static org.junit.Assert.assertEquals; 20e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport static org.junit.Assert.assertNotSame; 21e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport static org.junit.Assert.assertTrue; 22e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 23e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport android.support.test.filters.SmallTest; 24e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport android.support.test.runner.AndroidJUnit4; 25e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 26fba8faf5c5f58f115fa3c099da9ef0953b484147Jason Monkimport com.android.systemui.SysuiTestCase; 27e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport com.android.systemui.util.leak.ReferenceTestUtils.CollectionWaiter; 28e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 29e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport org.junit.Before; 30e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport org.junit.Test; 31e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport org.junit.runner.RunWith; 32e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 33e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos@SmallTest 34e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos@RunWith(AndroidJUnit4.class) 35fba8faf5c5f58f115fa3c099da9ef0953b484147Jason Monkpublic class WeakIdentityHashMapTest extends SysuiTestCase { 36e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 37e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos WeakIdentityHashMap<Object, Object> mMap; 38e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 39e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Before 40e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void setup() { 41e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mMap = new WeakIdentityHashMap<>(); 42e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 43e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 440fded55c45c400354a71fac453af7511703868efSøren Gjesse private CollectionWaiter addObjectToMap(WeakIdentityHashMap<Object, Object> map) { 450fded55c45c400354a71fac453af7511703868efSøren Gjesse Object object = new Object(); 460fded55c45c400354a71fac453af7511703868efSøren Gjesse CollectionWaiter collectionWaiter = ReferenceTestUtils.createCollectionWaiter(object); 470fded55c45c400354a71fac453af7511703868efSøren Gjesse map.put(object, "value"); 480fded55c45c400354a71fac453af7511703868efSøren Gjesse return collectionWaiter; 490fded55c45c400354a71fac453af7511703868efSøren Gjesse } 500fded55c45c400354a71fac453af7511703868efSøren Gjesse 51e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 52e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void testUsesIdentity() { 53e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos String a1 = new String("a"); 54e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos String a2 = new String("a"); 55e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos assertNotSame(a1, a2); 56e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 57e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mMap.put(a1, "value1"); 58e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mMap.put(a2, "value2"); 59e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 60e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos assertEquals("value1", mMap.get(a1)); 61e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos assertEquals("value2", mMap.get(a2)); 62e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 63e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 64e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 65e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void testWeaklyReferences() { 660fded55c45c400354a71fac453af7511703868efSøren Gjesse // Allocate and add an object to the weak map in a separate method to avoid a live 670fded55c45c400354a71fac453af7511703868efSøren Gjesse // reference to the allocated object in a dex register. As R8 is used to compile this 680fded55c45c400354a71fac453af7511703868efSøren Gjesse // test the --dontoptimize flag is also required to ensure that the method is not 690fded55c45c400354a71fac453af7511703868efSøren Gjesse // inlined, as that would defeat the purpose of having the allocation in a separate 700fded55c45c400354a71fac453af7511703868efSøren Gjesse // method. 710fded55c45c400354a71fac453af7511703868efSøren Gjesse CollectionWaiter collectionWaiter = addObjectToMap(mMap); 72e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 73e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos // Wait until object has been collected. We'll also need to wait for mMap to become empty, 74e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos // because our collection waiter may be told about the collection earlier than mMap. 75e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos collectionWaiter.waitForCollection(); 76e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos ReferenceTestUtils.waitForCondition(mMap::isEmpty); 77e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 78e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos assertEquals(0, mMap.size()); 79e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos assertTrue(mMap.isEmpty()); 80e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 810fded55c45c400354a71fac453af7511703868efSøren Gjesse} 82