1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17ab762bb740405d0fefcccf4a0899a234f995be13Narayan Kamathpackage org.apache.harmony.tests.java.lang.ref;
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.PhantomReference;
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.Reference;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.ReferenceQueue;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.SoftReference;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.ref.WeakReference;
2404ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilsonimport junit.framework.AssertionFailedError;
25fce022be38a2c79f9cdc8d9fea33c72cf2f16528Elliott Hughesimport libcore.java.lang.ref.FinalizationTester;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ReferenceTest extends junit.framework.TestCase {
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Object tmpA, tmpB, tmpC, obj;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    volatile Reference r;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
32f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /*
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * For test_subclass().
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static TestWeakReference twr;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static AssertionFailedError error;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static boolean testObjectFinalized;
38b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class TestWeakReference<T> extends WeakReference<T> {
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public volatile boolean clearSeen = false;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public volatile boolean enqueueSeen = false;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public TestWeakReference(T referent, ReferenceQueue<? super T> q) {
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(referent, q);
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void clear() {
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            clearSeen = true;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super.clear();
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public boolean enqueue() {
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            enqueueSeen = true;
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return super.enqueue();
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void doneSuite() {
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        tmpA = tmpB = obj = null;
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
63229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.ref.Reference#clear()
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void test_clear() {
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        tmpA = new Object();
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        tmpB = new Object();
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        tmpC = new Object();
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SoftReference sr = new SoftReference(tmpA, new ReferenceQueue());
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        WeakReference wr = new WeakReference(tmpB, new ReferenceQueue());
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        PhantomReference pr = new PhantomReference(tmpC, new ReferenceQueue());
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Start: Object not cleared.", (sr.get() != null)
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (wr.get() != null));
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertNull("Referent is not null.", pr.get());
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sr.clear();
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        wr.clear();
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pr.clear();
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("End: Object cleared.", (sr.get() == null)
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (wr.get() == null));
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertNull("Referent is not null.", pr.get());
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Must reference tmpA and tmpB so the jit does not optimize them away
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("should always pass", tmpA != sr.get() && tmpB != wr.get());
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
86229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.ref.Reference#enqueue()
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void test_enqueue() {
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ReferenceQueue rq = new ReferenceQueue();
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        obj = new Object();
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reference ref = new SoftReference(obj, rq);
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Enqueue failed.", (!ref.isEnqueued())
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && ((ref.enqueue()) && (ref.isEnqueued())));
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Not properly enqueued.", rq.poll().get() == obj);
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // This fails...
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should remain enqueued.", !ref.isEnqueued());
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Can not enqueue twice.", (!ref.enqueue())
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (rq.poll() == null));
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        rq = new ReferenceQueue();
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        obj = new Object();
102f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ref = new WeakReference(obj, rq);
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Enqueue failed2.", (!ref.isEnqueued())
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && ((ref.enqueue()) && (ref.isEnqueued())));
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Not properly enqueued2.", rq.poll().get() == obj);
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should remain enqueued2.", !ref.isEnqueued()); // This
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // fails.
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Can not enqueue twice2.", (!ref.enqueue())
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (rq.poll() == null));
111f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ref = new PhantomReference(obj, rq);
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Enqueue failed3.", (!ref.isEnqueued())
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && ((ref.enqueue()) && (ref.isEnqueued())));
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertNull("Not properly enqueued3.", rq.poll().get());
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should remain enqueued3.", !ref.isEnqueued()); // This
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // fails.
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Can not enqueue twice3.", (!ref.enqueue())
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                && (rq.poll() == null));
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
12204ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson    public void test_get_WeakReference() throws Exception {
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Test the general/overall functionality of Reference.
12404ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
12604ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        r = newWeakReference(queue);
127fce022be38a2c79f9cdc8d9fea33c72cf2f16528Elliott Hughes        FinalizationTester.induceFinalization();
12804ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        Reference ref = queue.remove();
12904ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNotNull("Object not enqueued.", ref);
13004ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertSame("Unexpected ref1", ref, r);
13104ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNull("Object could not be reclaimed1.", r.get());
132f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
13304ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        r = newWeakReference(queue);
134fce022be38a2c79f9cdc8d9fea33c72cf2f16528Elliott Hughes        FinalizationTester.induceFinalization();
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
13604ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        // wait for the reference queue thread to enqueue the newly-finalized object
13704ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        Thread.yield();
13804ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        Thread.sleep(200);
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
14004ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        ref = queue.poll();
14104ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNotNull("Object not enqueued.", ref);
14204ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertSame("Unexpected ref2", ref, r);
14304ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNull("Object could not be reclaimed.", ref.get());
14404ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNull("Object could not be reclaimed.", r.get());
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Makes sure that overridden versions of clear() and enqueue()
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * get called, and that clear/enqueue/finalize happen in the
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * right order for WeakReferences.
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
152229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.ref.Reference#clear()
153229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.ref.Reference#enqueue()
154229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.Object#finalize()
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void test_subclass() {
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        error = null;
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        testObjectFinalized = false;
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        twr = null;
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class TestObject {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public TestWeakReference testWeakReference = null;
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void setTestWeakReference(TestWeakReference twr) {
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                testWeakReference = twr;
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            protected void finalize() {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                testObjectFinalized = true;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReferenceQueue rq = new ReferenceQueue();
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class TestThread extends Thread {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void run() {
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Create the object in a separate thread to ensure it will be
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // gc'ed
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                TestObject testObj = new TestObject();
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                twr = new TestWeakReference(testObj, rq);
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                testObj.setTestWeakReference(twr);
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                testObj = null;
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reference ref;
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Thread t = new TestThread();
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            t.start();
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            t.join();
192fce022be38a2c79f9cdc8d9fea33c72cf2f16528Elliott Hughes            FinalizationTester.induceFinalization();
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ref = rq.remove(5000L);    // Give up after five seconds.
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertNotNull("Object not garbage collected.", ref);
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertTrue("Unexpected reference.", ref == twr);
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertNull("Object could not be reclaimed.", twr.get());
198b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath
199b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath            // enqueue() and clear() will not be called by the garbage collector. The GC
200b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath            // will perform the equivalent operations directly.
201b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath            assertFalse(twr.clearSeen);
202b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath            assertFalse(twr.enqueueSeen);
203b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath
204b9e360018745db5ef9dd3c9f8f096f0979e471afNarayan Kamath            assertTrue(testObjectFinalized);
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (InterruptedException e) {
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail("InterruptedException : " + e.getMessage());
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
212229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.ref.Reference#get()
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void test_get() {
21504ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        WeakReference ref = newWeakReference(null);
216f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
217fce022be38a2c79f9cdc8d9fea33c72cf2f16528Elliott Hughes        FinalizationTester.induceFinalization();
21804ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNull("get() doesn't return null after gc for WeakReference", ref.get());
219f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        obj = new Object();
22104ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        ref = new WeakReference<Object>(obj, new ReferenceQueue<Object>());
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ref.clear();
22304ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertNull("get() doesn't return null after clear for WeakReference", ref.get());
22404ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson    }
22504ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson
22604ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson    /**
22704ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson     * Helper method to prevent live-precise bugs from interfering with analysis
22804ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson     * of what is reachable. Do not inline this method; otherwise tests may fail
22904ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson     * on VMs that are not live-precise. http://b/4191345
23004ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson     */
23104ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson    private WeakReference<Object> newWeakReference(ReferenceQueue<Object> queue) {
23204ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        Object o = new Object();
23304ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        WeakReference<Object> ref = new WeakReference<Object>(o, queue);
23404ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        assertSame(o, ref.get());
23504ff663e6908ffd0cb65f321675e51b03f9fea1aJesse Wilson        return ref;
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
239229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * java.lang.ref.Reference#isEnqueued()
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void test_isEnqueued() {
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ReferenceQueue rq = new ReferenceQueue();
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        obj = new Object();
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reference ref = new SoftReference(obj, rq);
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should start off not enqueued.", !ref.isEnqueued());
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ref.enqueue();
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should now be enqueued.", ref.isEnqueued());
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ref.enqueue();
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should still be enqueued.", ref.isEnqueued());
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        rq.poll();
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // This fails ...
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue("Should now be not enqueued.", !ref.isEnqueued());
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /* Contrives a situation where the only reference to a string
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is a WeakReference from an object that is being finalized.
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks to make sure that the referent of the WeakReference
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is still pointing to a valid object.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void test_finalizeReferenceInteraction() {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        error = null;
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        testObjectFinalized = false;
263f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class TestObject {
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            WeakReference<String> stringRef;
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public TestObject(String referent) {
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                stringRef = new WeakReference<String>(referent);
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            protected void finalize() {
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    /* If a VM bug has caused the referent to get
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     * freed without the reference getting cleared,
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     * looking it up, assigning it to a local and
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     * doing a GC should cause some sort of exception.
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     */
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String s = stringRef.get();
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    System.gc();
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    testObjectFinalized = true;
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (Throwable t) {
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    error = new AssertionFailedError("something threw '" + t +
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            "' in finalize()");
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class TestThread extends Thread {
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void run() {
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Create the object in a separate thread to ensure it will be
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // gc'ed
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                TestObject testObj = new TestObject(new String("sup /b/"));
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Thread t = new TestThread();
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            t.start();
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            t.join();
300fce022be38a2c79f9cdc8d9fea33c72cf2f16528Elliott Hughes            FinalizationTester.induceFinalization();
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Thread.sleep(1000);
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (error != null) {
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw error;
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertTrue("finalize() should have been called.",
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    testObjectFinalized);
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (InterruptedException e) {
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail("InterruptedException : " + e.getMessage());
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void setUp() {
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void tearDown() {
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
319