bug 781971 - hack around plugin hangs r=surkov

This commit is contained in:
Trevor Saunders 2013-02-26 17:07:24 -05:00
Родитель 324cc006a6
Коммит 126a5f25c7
2 изменённых файлов: 83 добавлений и 0 удалений

Просмотреть файл

@ -37,6 +37,7 @@
#endif
#ifdef XP_WIN
#include "mozilla/a11y/Compatibility.h"
#include "HTMLWin32ObjectAccessible.h"
#endif
@ -63,6 +64,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Util.h"
#include "nsDeckFrame.h"
@ -210,6 +212,45 @@ nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell,
return nullptr;
}
#ifdef XP_WIN
static StaticAutoPtr<nsTArray<nsCOMPtr<nsIContent> > > sPendingPlugins;
static StaticAutoPtr<nsTArray<nsCOMPtr<nsITimer> > > sPluginTimers;
class PluginTimerCallBack MOZ_FINAL : public nsITimerCallback
{
public:
PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
NS_DECL_ISUPPORTS
NS_IMETHODIMP Notify(nsITimer* aTimer) MOZ_FINAL
{
nsIPresShell* ps = mContent->OwnerDoc()->GetShell();
if (ps) {
DocAccessible* doc = ps->GetDocAccessible();
if (doc) {
// Make sure that if we created an accessible for the plugin that wasn't
// a plugin accessible we remove it before creating the right accessible.
doc->RecreateAccessible(mContent);
sPluginTimers->RemoveElement(aTimer);
return NS_OK;
}
}
// We couldn't get a doc accessible so presumably the document went away.
// In this case don't leak our ref to the content or timer.
sPendingPlugins->RemoveElement(mContent);
sPluginTimers->RemoveElement(aTimer);
return NS_OK;
}
private:
nsCOMPtr<nsIContent> mContent;
};
NS_IMPL_ISUPPORTS1(PluginTimerCallBack, nsITimerCallback)
#endif
already_AddRefed<Accessible>
nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame,
nsIContent* aContent,
@ -225,6 +266,23 @@ nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame,
if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
pluginInstance) {
#ifdef XP_WIN
if (!sPendingPlugins->Contains(aContent) &&
(Preferences::GetBool("accessibility.delay_plugins") ||
Compatibility::IsJAWS() || Compatibility::IsWE())) {
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
nsRefPtr<PluginTimerCallBack> cb = new PluginTimerCallBack(aContent);
timer->InitWithCallback(cb, Preferences::GetUint("accessibility.delay_plugin_time"),
nsITimer::TYPE_ONE_SHOT);
sPluginTimers->AppendElement(timer);
sPendingPlugins->AppendElement(aContent);
return nullptr;
}
// We need to remove aContent from the pending plugins here to avoid
// reentrancy. When the timer fires it calls
// DocAccessible::ContentInserted() which does the work async.
sPendingPlugins->RemoveElement(aContent);
// Note: pluginPort will be null if windowless.
HWND pluginPort = nullptr;
aFrame->GetPluginPort(&pluginPort);
@ -1004,6 +1062,11 @@ nsAccessibilityService::Init()
NS_LITERAL_CSTRING("Active"));
#endif
#ifdef XP_WIN
sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >;
sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
#endif
gIsShutdown = false;
// Now its safe to start platform accessibility.
@ -1030,6 +1093,16 @@ nsAccessibilityService::Shutdown()
SelectionManager::Shutdown();
#ifdef XP_WIN
sPendingPlugins = nullptr;
uint32_t timerCount = sPluginTimers->Length();
for (uint32_t i = 0; i < timerCount; i++)
sPluginTimers->ElementAt(i)->Cancel();
sPluginTimers = nullptr;
#endif
// Application is going to be closed, shutdown accessibility and mark
// accessibility service as shutdown to prevent calls of its methods.
// Don't null accessibility service static member at this point to be safe

Просмотреть файл

@ -331,6 +331,16 @@ pref("accessibility.tabfocus_applies_to_xul", true);
// further checks.
pref("accessibility.force_disabled", 0);
#ifdef XP_WIN
// Some accessibility tools poke at windows in the plugin process during setup
// which can cause hangs. To hack around this set accessibility.delay_plugins
// to true, you can also try increasing accessibility.delay_plugin_time if your
// machine is slow and you still experience hangs.
// See bug 781791.
pref("accessibility.delay_plugins", false);
pref("accessibility.delay_plugin_time", 10000);
#endif
pref("focusmanager.testmode", false);
pref("accessibility.usetexttospeech", "");