diff options
author | Tomasz Zarna | 2015-03-02 22:29:55 +0000 |
---|---|---|
committer | Tomasz Zarna | 2015-03-09 22:40:43 +0000 |
commit | 9d695146acd12a05118545b9ac3c77c121fd478f (patch) | |
tree | 262b1e6edb11a325ccddfbb2829bbf0f290b1bd2 | |
parent | 70910bd253f734db09383844efb0f1f75c414962 (diff) | |
download | eclipse.platform.ui-9d695146acd12a05118545b9ac3c77c121fd478f.tar.gz eclipse.platform.ui-9d695146acd12a05118545b9ac3c77c121fd478f.tar.xz eclipse.platform.ui-9d695146acd12a05118545b9ac3c77c121fd478f.zip |
Bug 439041: [Progress] MemoryLeak in ProgressAnimationItem
Change-Id: I646b9a16f4b294a3341dd56205d47160333bbbb0
Signed-off-by: Tomasz Zarna <tomasz.zarna@tasktop.com>
3 files changed, 147 insertions, 7 deletions
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressAnimationItem.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressAnimationItem.java index c3cf6c95b10..3d95984e69c 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressAnimationItem.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/progress/ProgressAnimationItem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2014 IBM Corporation and others. + * Copyright (c) 2004, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -25,6 +25,7 @@ import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.accessibility.AccessibleAdapter; import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.accessibility.AccessibleListener; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MouseAdapter; @@ -76,6 +77,8 @@ public class ProgressAnimationItem extends AnimationItem implements // ProgressBar flags private int flags; + private AccessibleListener currentAccessibleListener; + /** * Create an instance of the receiver in the supplied region. * @@ -264,12 +267,15 @@ public class ProgressAnimationItem extends AnimationItem implements toolbar.setVisible(true); toolbar.getParent().layout(); // must layout - toolbar.getAccessible().addAccessibleListener(new AccessibleAdapter() { - @Override + if (currentAccessibleListener != null) + toolbar.getAccessible().removeAccessibleListener(currentAccessibleListener); + currentAccessibleListener = new AccessibleAdapter() { + @Override public void getName(AccessibleEvent e) { - e.result = tt; - } - }); + e.result = tt; + } + }; + toolbar.getAccessible().addAccessibleListener(currentAccessibleListener); } /* diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressAnimationItemTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressAnimationItemTest.java new file mode 100644 index 00000000000..0d736cbe06d --- /dev/null +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressAnimationItemTest.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2015 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.tests.progress; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Vector; + +import junit.framework.TestCase; + +import org.eclipse.core.runtime.Status; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.Accessible; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.progress.FinishedJobs; +import org.eclipse.ui.internal.progress.ProgressAnimationItem; +import org.eclipse.ui.internal.progress.ProgressManager; +import org.eclipse.ui.internal.progress.ProgressRegion; +import org.eclipse.ui.progress.IProgressConstants; + +public class ProgressAnimationItemTest extends TestCase { + private Shell shell; + private ProgressAnimationItem animationItem; + + public ProgressAnimationItemTest(String testName) { + super(testName); + } + + @Override + protected void setUp() throws Exception { + Display display = PlatformUI.getWorkbench().getDisplay(); + shell = new Shell(display); + shell.setSize(400, 300); + shell.setLayout(new FillLayout()); + shell.open(); + Composite composite = new Composite(shell, SWT.V_SCROLL); + animationItem = createProgressAnimationItem(composite); + } + + @Override + protected void tearDown() throws Exception { + FinishedJobs.getInstance().clearAll(); + shell.dispose(); + } + + public void testSingleJobRefreshOnce() throws Exception { + createAndScheduleJob(); + + refresh(); + + assertSingleAccessibleListener(); + } + + public void testTwoJobsRefreshOnce() throws Exception { + createAndScheduleJob(); + createAndScheduleJob(); + + refresh(); + + assertSingleAccessibleListener(); + } + + public void testSingleJobRefreshTwice() throws Exception { + createAndScheduleJob(); + + refresh(); + refresh(); + + assertSingleAccessibleListener(); + } + + private ProgressAnimationItem createProgressAnimationItem(Composite composite) { + ProgressRegion progressRegion = new ProgressRegion(); + progressRegion.createContents(composite, null); + return (ProgressAnimationItem) progressRegion.getAnimationItem(); + } + + private static void createAndScheduleJob() throws InterruptedException { + DummyJob job = new DummyJob("Keep me", Status.OK_STATUS); + job.setProperty(IProgressConstants.KEEP_PROPERTY, true); + ExtendedJobInfo info = new ExtendedJobInfo(job); + ProgressManager.getInstance().addJobInfo(info); + job.schedule(); + job.join(); + } + + private void refresh() throws Exception { + Method m = ProgressAnimationItem.class.getDeclaredMethod("refresh"); + m.setAccessible(true); + m.invoke(animationItem); + } + + private void assertSingleAccessibleListener() throws Exception { + assertEquals(1, getAccessibleListenersSize(getToolBar(animationItem).getAccessible())); + } + + private ToolBar getToolBar(ProgressAnimationItem animationItem) { + Composite top = (Composite) animationItem.getControl(); + for (Control child : top.getChildren()) { + if (child instanceof ToolBar) { + return (ToolBar) child; + } + } + return null; + } + + /** + * Loads, using reflection, the internal accessible listeners vector from + * inside the Accessible and returns its size. If the collection is null, + * returns 0. + */ + private static int getAccessibleListenersSize(Accessible accessible) throws Exception { + Field f = Accessible.class.getDeclaredField("accessibleListeners"); + f.setAccessible(true); + Vector accessibleListeners = (Vector) f.get(accessible); + return accessibleListeners == null ? 0 : accessibleListeners.size(); + } + +} diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressTestSuite.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressTestSuite.java index 3563b84d8b6..4ec449b1278 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressTestSuite.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/progress/ProgressTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 IBM Corporation and others. + * Copyright (c) 2009, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -35,5 +35,6 @@ public class ProgressTestSuite extends TestSuite { addTest(new TestSuite(ProgressViewTests.class)); addTest(new TestSuite(JobInfoTest.class)); addTest(new TestSuite(JobInfoTestOrdering.class)); + addTest(new TestSuite(ProgressAnimationItemTest.class)); } } |