1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.common;
6
7import android.test.InstrumentationTestCase;
8import android.test.suitebuilder.annotation.SmallTest;
9
10import org.chromium.base.test.util.Feature;
11import org.chromium.content.browser.test.util.Criteria;
12import org.chromium.content.browser.test.util.CriteriaHelper;
13
14import java.util.concurrent.atomic.AtomicInteger;
15
16public class CleanupReferenceTest extends InstrumentationTestCase {
17
18    private static AtomicInteger sObjectCount = new AtomicInteger();
19
20    private static class ReferredObject {
21
22        private CleanupReference mRef;
23
24        // Remember: this MUST be a static class, to avoid an implicit ref back to the
25        // owning ReferredObject instance which would defeat GC of that object.
26        private static class DestroyRunnable implements Runnable {
27            @Override
28            public void run() {
29                sObjectCount.decrementAndGet();
30            }
31        };
32
33        public ReferredObject() {
34            sObjectCount.incrementAndGet();
35            mRef = new CleanupReference(this, new DestroyRunnable());
36        }
37    }
38
39    @Override
40    public void setUp() throws Exception {
41        super.setUp();
42        sObjectCount.set(0);
43    }
44
45    private void collectGarbage() {
46        // While this is only a 'hint' to the VM, it's generally effective and sufficient on
47        // dalvik. If this changes in future, maybe try allocating a few gargantuan objects
48        // too, to force the GC to work.
49        System.gc();
50    }
51
52    @SmallTest
53    @Feature({"AndroidWebView"})
54    public void testCreateSingle() throws Throwable {
55        assertEquals(0, sObjectCount.get());
56
57        ReferredObject instance = new ReferredObject();
58        assertEquals(1, sObjectCount.get());
59
60        instance = null;
61        collectGarbage();
62        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
63            @Override
64            public boolean isSatisfied() {
65                return sObjectCount.get() == 0;
66            }
67        }));
68    }
69
70    @SmallTest
71    @Feature({"AndroidWebView"})
72    public void testCreateMany() throws Throwable {
73        assertEquals(0, sObjectCount.get());
74
75        final int INSTANCE_COUNT = 20;
76        ReferredObject[] instances = new ReferredObject[INSTANCE_COUNT];
77
78        for (int i = 0; i < INSTANCE_COUNT; ++i) {
79            instances[i] = new ReferredObject();
80            assertEquals(i + 1, sObjectCount.get());
81        }
82
83        instances = null;
84        collectGarbage();
85        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
86            @Override
87            public boolean isSatisfied() {
88                return sObjectCount.get() == 0;
89            }
90        }));
91    }
92
93}
94