Merge backouts

This commit is contained in:
Benjamin Smedberg 2010-01-27 13:21:25 -05:00
commit ea8ba10a39
17 changed files with 333 additions and 22 deletions

View File

@ -508,7 +508,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
pHandle = self.ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid)
if not pHandle:
return False
pExitCode = self.wintypes.DWORD()
pExitCode = ctypes.wintypes.DWORD()
self.ctypes.windll.kernel32.GetExitCodeProcess(pHandle, self.ctypes.byref(pExitCode))
self.ctypes.windll.kernel32.CloseHandle(pHandle)
if (pExitCode.value == STILL_ACTIVE):

View File

@ -87,6 +87,7 @@ BrowserStreamChild::StreamConstructed(
{
NPError rv = NPERR_NO_ERROR;
*stype = NP_NORMAL;
rv = mInstance->mPluginIface->newstream(
&mInstance->mData, const_cast<char*>(NullableStringGet(mimeType)),
&mStream, seekable, stype);

View File

@ -161,6 +161,11 @@ parent:
rpc PPluginStream(nsCString mimeType,
nsCString target)
returns (NPError result);
parent:
rpc PluginGotFocus();
child:
rpc SetPluginFocus();
};
} // namespace plugins

View File

@ -684,6 +684,18 @@ PluginInstanceChild::PluginWindowProc(HWND hWnd,
NS_ASSERTION(self->mPluginWindowHWND == hWnd, "Wrong window!");
// The plugin received keyboard focus, let the parent know so the dom is up to date.
if (message == WM_MOUSEACTIVATE)
self->CallPluginGotFocus();
// Prevent lockups due to plugins making rpc calls when the parent
// is making a synchronous SetFocus api call. (bug 541362) Add more
// windowing events as needed for other api.
if (message == WM_KILLFOCUS &&
((InSendMessageEx(NULL) & (ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND)) {
ReplyMessage(0); // Unblock the caller
}
LRESULT res = CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
lParam);
@ -872,6 +884,23 @@ PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
#endif // OS_WIN
bool
PluginInstanceChild::AnswerSetPluginFocus()
{
PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s", FULLFUNCTION));
#if defined(OS_WIN)
// Parent is letting us know something set focus to the plugin.
if (::GetFocus() == mPluginWindowHWND)
return true;
::SetFocus(mPluginWindowHWND);
return true;
#else
NS_NOTREACHED("PluginInstanceChild::AnswerSetPluginFocus not implemented!");
return false;
#endif
}
PPluginScriptableObjectChild*
PluginInstanceChild::AllocPPluginScriptableObject()
{

View File

@ -145,6 +145,9 @@ protected:
NS_OVERRIDE virtual bool
DeallocPStreamNotify(PStreamNotifyChild* notifyData);
virtual bool
AnswerSetPluginFocus();
public:
PluginInstanceChild(const NPPluginFuncs* aPluginIface);

View File

@ -48,6 +48,11 @@
#if defined(OS_WIN)
#include <windowsx.h>
// Plugin focus event for widget.
extern const PRUnichar* kOOPPPluginFocusEventId;
UINT gOOPPPluginFocusEvent =
RegisterWindowMessage(kOOPPPluginFocusEventId);
#endif
using namespace mozilla::plugins;
@ -55,10 +60,14 @@ using namespace mozilla::plugins;
PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
NPP npp,
const NPNetscapeFuncs* npniface)
: mParent(parent),
mNPP(npp),
mNPNIface(npniface),
mWindowType(NPWindowTypeWindow)
: mParent(parent)
, mNPP(npp)
, mNPNIface(npniface)
, mWindowType(NPWindowTypeWindow)
#if defined(OS_WIN)
, mPluginHWND(NULL)
, mPluginWndProc(NULL)
#endif // defined(XP_WIN)
{
}
@ -99,6 +108,7 @@ PluginInstanceParent::Destroy()
#if defined(OS_WIN)
SharedSurfaceRelease();
UnsubclassPluginWindow();
#endif
return retval;
@ -360,6 +370,8 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
}
}
else {
SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
window.window = reinterpret_cast<unsigned long>(aWindow->window);
window.x = aWindow->x;
window.y = aWindow->y;
@ -832,6 +844,86 @@ PluginInstanceParent::AnswerNPN_GetAuthenticationInfo(const nsCString& protocol,
#if defined(OS_WIN)
/*
plugin focus changes between processes
focus from dom -> child:
Focs manager calls on widget to set the focus on the window.
We pick up the resulting wm_setfocus event here, and forward
that over ipc to the child which calls set focus on itself.
focus from child -> focus manager:
Child picks up the local wm_setfocus and sends it via ipc over
here. We then post a custom event to widget/src/windows/nswindow
which fires off a gui event letting the browser know.
*/
static const PRUnichar kPluginInstanceParentProperty[] =
L"PluginInstanceParentProperty";
// static
LRESULT CALLBACK
PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
::GetPropW(hWnd, kPluginInstanceParentProperty));
if (!self) {
NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
return DefWindowProc(hWnd, message, wParam, lParam);
}
NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
switch (message) {
case WM_SETFOCUS:
self->CallSetPluginFocus();
break;
case WM_CLOSE:
self->UnsubclassPluginWindow();
break;
}
return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
lParam);
}
void
PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
{
NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
"PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
if (!mPluginHWND) {
mPluginHWND = aWnd;
mPluginWndProc =
(WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
reinterpret_cast<LONG>(PluginWindowHookProc));
bool bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
NS_ASSERTION(mPluginWndProc,
"PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
NS_ASSERTION(bRes,
"PluginInstanceParent::SubclassPluginWindow failed to set prop!");
}
}
void
PluginInstanceParent::UnsubclassPluginWindow()
{
if (mPluginHWND && mPluginWndProc) {
::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
reinterpret_cast<LONG>(mPluginWndProc));
::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
mPluginWndProc = NULL;
mPluginHWND = NULL;
}
}
/* windowless drawing helpers */
/*
@ -956,3 +1048,21 @@ PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
}
#endif // defined(OS_WIN)
bool
PluginInstanceParent::AnswerPluginGotFocus()
{
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
// Currently only in use on windows - an rpc event we receive from the
// child when it's plugin window (or one of it's children) receives keyboard
// focus. We forward the event down to widget so the dom/focus manager can
// be updated.
#if defined(OS_WIN)
::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, 0, 0);
return true;
#else
NS_NOTREACHED("PluginInstanceParent::AnswerPluginGotFocus not implemented!");
return false;
#endif
}

View File

@ -222,6 +222,9 @@ public:
return mNPP;
}
virtual bool
AnswerPluginGotFocus();
private:
bool InternalGetValueForNPObject(NPNVariable aVariable,
PPluginScriptableObjectParent** aValue,
@ -242,11 +245,18 @@ private:
void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
void SharedSurfaceAfterPaint(NPEvent* npevent);
void SharedSurfaceRelease();
// Used in handling parent/child forwarding of events.
static LRESULT CALLBACK PluginWindowHookProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void SubclassPluginWindow(HWND aWnd);
void UnsubclassPluginWindow();
private:
gfx::SharedDIBWin mSharedSurfaceDib;
nsIntRect mPluginPort;
nsIntRect mSharedSize;
HWND mPluginHWND;
WNDPROC mPluginWndProc;
#endif // defined(XP_WIN)
};

View File

@ -102,8 +102,21 @@ void Thread::Stop() {
DCHECK_NE(thread_id_, PlatformThread::CurrentId());
// StopSoon may have already been called.
if (message_loop_)
if (message_loop_) {
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | process %d | posted quit task to other thread\n", getpid());
#endif
message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
}
// Wait for the thread to exit. It should already have terminated but make
// sure this assumption is valid.
@ -111,8 +124,29 @@ void Thread::Stop() {
// TODO(darin): Unfortunately, we need to keep message_loop_ around until
// the thread exits. Some consumers are abusing the API. Make them stop.
//
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | process %d | joining other thread\n", getpid());
#endif
PlatformThread::Join(thread_);
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | process %d | other thread joined\n", getpid());
#endif
// The thread can't receive messages anymore.
message_loop_ = NULL;

View File

@ -29,9 +29,28 @@ ChildProcess::~ChildProcess() {
// notice shutdown before the render process begins waiting for them to exit.
shutdown_event_.Signal();
if (child_thread_.get())
if (child_thread_.get()) {
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | plugin process %d | IO thread is Stop()ing XPCOM thread\n", getpid());
#endif
child_thread_->Stop();
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | plugin process %d | XPCOM thread has been Stop()d\n", getpid());
#endif
}
child_process_ = NULL;
}

View File

@ -381,6 +381,15 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
return false;
}
} else if (bytes_read == 0) {
printf("TEST-UNEXPECTED-FAIL | process %d | read 0 bytes from pipe, it's closed\n", getpid());
// The pipe has closed...
Close();
return false;
@ -697,7 +706,20 @@ void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) {
if (!waiting_connect_ && fd == pipe_) {
if (!ProcessIncomingMessages()) {
Close();
printf("TEST-UNEXPECTED-FAIL | process %d | notifying client of channel error (read)\n", getpid());
listener_->OnChannelError();
printf("TEST-UNEXPECTED-FAIL | process %d | client notified(read)\n", getpid());
}
}
@ -715,8 +737,29 @@ void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) {
// Called by libevent when we can write to the pipe without blocking.
void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) {
if (!ProcessOutgoingMessages()) {
printf("TEST-UNEXPECTED-FAIL | process %d | failed to process outgoing messages\n", getpid());
Close();
printf("TEST-UNEXPECTED-FAIL | process %d | notifying client of channel error (write)\n", getpid());
listener_->OnChannelError();
printf("TEST-UNEXPECTED-FAIL | process %d | client notified(write)\n", getpid());
}
}
@ -728,7 +771,21 @@ void Channel::ChannelImpl::Close() {
server_listen_connection_watcher_.StopWatchingFileDescriptor();
if (server_listen_pipe_ != -1) {
printf("TEST-UNEXPECTED-FAIL | process %d | closing pipe\n", getpid());
HANDLE_EINTR(close(server_listen_pipe_));
printf("TEST-UNEXPECTED-FAIL | process %d | pipe closed\n", getpid());
server_listen_pipe_ = -1;
}

View File

@ -73,6 +73,15 @@ AsyncChannel::AsyncChannel(AsyncListener* aListener)
AsyncChannel::~AsyncChannel()
{
MOZ_COUNT_DTOR(AsyncChannel);
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | process %d | ~AsyncChannel()\n", getpid());
#endif
Clear();
}

View File

@ -306,17 +306,19 @@ static LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
#ifndef WINCE
case WM_MOUSEACTIVATE: {
// If a child window of this plug-in is already focused,
// don't focus the parent to avoid focus dance.
// The following WM_SETFOCUS message will give the focus
// to the appropriate window anyway.
// don't focus the parent to avoid focus dance. We'll
// receive a follow up WM_SETFOCUS which will notify
// the appropriate window anyway.
HWND focusedWnd = ::GetFocus();
if (!::IsChild((HWND)win->window, focusedWnd)) {
// This seems to be the only way we're
// notified when a child window that doesn't have this handler proc
// (read as: windows created by plugins like Adobe Acrobat)
// has been activated via clicking.
// should be handled here because some plugins won't forward
// messages to original WinProc.
// Notify the dom / focus manager the plugin has focus when one of
// it's child windows receives it. OOPP specific - this code is
// critical in notifying the dom of focus changes when the plugin
// window in the child process receives focus via a mouse click.
// WM_MOUSEACTIVATE is sent by nsWindow via a custom window event
// sent from PluginInstanceParent in response to focus events sent
// from the child. (bug 540052) Note, this gui event could also be
// sent directly from widget.
nsCOMPtr<nsIWidget> widget;
win->GetPluginWidget(getter_AddRefs(widget));
if (widget) {

View File

@ -368,6 +368,14 @@ XRE_InitChildProcess(int aArgc,
sIOMessageLoop->Run();
#ifdef OS_LINUX
printf("TEST-UNEXPECTED-FAIL | plugin process %d | broke out of IO event loop\n", getpid());
#endif
sIOMessageLoop = nsnull;
}

View File

@ -209,10 +209,6 @@
#include "nsGfxCIID.h"
#endif
// A magic APP message that can be sent to quit, sort of like a QUERYENDSESSION/ENDSESSION,
// but without the query.
#define MOZ_WM_APP_QUIT (WM_APP+0x0300)
/**************************************************************
**************************************************************
**
@ -282,6 +278,13 @@ LPFNLRESULTFROMOBJECT
nsWindow::sLresultFromObject = 0;
#endif // ACCESSIBILITY
#ifdef MOZ_IPC
// Used in OOPP plugin focus processing.
const PRUnichar* kOOPPPluginFocusEventId = L"OOPP Plugin Focus Widget Event";
PRUint32 nsWindow::sOOPPPluginFocusEvent =
RegisterWindowMessageW(kOOPPPluginFocusEventId);
#endif
/**************************************************************
*
* SECTION: globals variables
@ -330,7 +333,6 @@ static void UpdateLastInputEventTime() {
is->IdleTimeWasModified();
}
// Global user preference for disabling native theme. Used
// in NativeWindowTheme.
PRBool gDisableNativeTheme = PR_FALSE;
@ -4606,6 +4608,15 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
if (msg == nsAppShell::GetTaskbarButtonCreatedMessage())
SetHasTaskbarIconBeenCreated();
#endif
#ifdef MOZ_IPC
if (msg == sOOPPPluginFocusEvent) {
// With OOPP, the plugin window exists in another process and is a child of
// this window. This window is a placeholder plugin window for the dom. We
// receive this event when the child window receives focus. (sent from
// PluginInstanceParent.cpp)
::SendMessage(mWnd, WM_MOUSEACTIVATE, 0, 0); // See nsPluginNativeWindowWin.cpp
}
#endif
}
break;

View File

@ -446,6 +446,9 @@ protected:
static PRBool sJustGotActivate;
static int sTrimOnMinimize;
static PRBool sTrackPointHack;
#ifdef MOZ_IPC
static PRUint32 sOOPPPluginFocusEvent;
#endif
// Hook Data Memebers for Dropdowns. sProcessHook Tells the
// hook methods whether they should be processing the hook

View File

@ -53,6 +53,10 @@
*
**************************************************************/
// A magic APP message that can be sent to quit, sort of like a QUERYENDSESSION/ENDSESSION,
// but without the query.
#define MOZ_WM_APP_QUIT (WM_APP+0x0300)
// GetWindowsVersion constants
#define WIN2K_VERSION 0x500
#define WINXP_VERSION 0x501

View File

@ -620,6 +620,12 @@ static PRBool LogThisObj(PRInt32 aSerialNumber)
return nsnull != PL_HashTableLookup(gObjectsToLog, (const void*)(aSerialNumber));
}
#ifdef XP_WIN
#define FOPEN_NO_INHERIT "N"
#else
#define FOPEN_NO_INHERIT
#endif
static PRBool InitLog(const char* envVar, const char* msg, FILE* *result)
{
const char* value = getenv(envVar);
@ -653,7 +659,7 @@ static PRBool InitLog(const char* envVar, const char* msg, FILE* *result)
fname.AppendLiteral(".log");
}
#endif
stream = ::fopen(fname.get(), "w");
stream = ::fopen(fname.get(), "w" FOPEN_NO_INHERIT);
if (stream != NULL) {
*result = stream;
fprintf(stdout, "### %s defined -- logging %s to %s\n",