1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #import "config.h" 27 #import "PluginProcessProxy.h" 28 29 #if ENABLE(PLUGIN_PROCESS) 30 31 #import "PluginProcessCreationParameters.h" 32 #import "WebKitSystemInterface.h" 33 34 @interface WKPlaceholderModalWindow : NSWindow 35 @end 36 37 @implementation WKPlaceholderModalWindow 38 39 // Prevent NSApp from calling requestUserAttention: when the window is shown 40 // modally, even if the app is inactive. See 6823049. 41 - (BOOL)_wantsUserAttention 42 { 43 return NO; 44 } 45 46 @end 47 48 namespace WebKit { 49 50 bool PluginProcessProxy::pluginNeedsExecutableHeap(const PluginInfoStore::Plugin& pluginInfo) 51 { 52 static bool forceNonexecutableHeapForPlugins = [[NSUserDefaults standardUserDefaults] boolForKey:@"ForceNonexecutableHeapForPlugins"]; 53 if (forceNonexecutableHeapForPlugins) 54 return false; 55 56 if (pluginInfo.bundleIdentifier == "com.apple.QuickTime Plugin.plugin") 57 return false; 58 59 return true; 60 } 61 62 void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters& parameters) 63 { 64 #if USE(ACCELERATED_COMPOSITING) && HAVE(HOSTED_CORE_ANIMATION) 65 parameters.parentProcessName = [[NSProcessInfo processInfo] processName]; 66 mach_port_t renderServerPort = WKInitializeRenderServer(); 67 if (renderServerPort != MACH_PORT_NULL) 68 parameters.acceleratedCompositingPort = CoreIPC::MachPort(renderServerPort, MACH_MSG_TYPE_COPY_SEND); 69 #endif 70 } 71 72 bool PluginProcessProxy::getPluginProcessSerialNumber(ProcessSerialNumber& pluginProcessSerialNumber) 73 { 74 pid_t pluginProcessPID = m_processLauncher->processIdentifier(); 75 return GetProcessForPID(pluginProcessPID, &pluginProcessSerialNumber) == noErr; 76 } 77 78 void PluginProcessProxy::makePluginProcessTheFrontProcess() 79 { 80 ProcessSerialNumber pluginProcessSerialNumber; 81 if (!getPluginProcessSerialNumber(pluginProcessSerialNumber)) 82 return; 83 84 SetFrontProcess(&pluginProcessSerialNumber); 85 } 86 87 void PluginProcessProxy::makeUIProcessTheFrontProcess() 88 { 89 ProcessSerialNumber processSerialNumber; 90 GetCurrentProcess(&processSerialNumber); 91 SetFrontProcess(&processSerialNumber); 92 } 93 94 void PluginProcessProxy::setFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) 95 { 96 if (m_fullscreenWindowIsShowing == fullscreenWindowIsShowing) 97 return; 98 99 m_fullscreenWindowIsShowing = fullscreenWindowIsShowing; 100 if (m_fullscreenWindowIsShowing) 101 enterFullscreen(); 102 else 103 exitFullscreen(); 104 } 105 106 void PluginProcessProxy::enterFullscreen() 107 { 108 // Get the current presentation options. 109 m_preFullscreenAppPresentationOptions = [NSApp presentationOptions]; 110 111 // Figure out which presentation options to use. 112 unsigned presentationOptions = m_preFullscreenAppPresentationOptions & ~(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar); 113 presentationOptions |= NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; 114 115 [NSApp setPresentationOptions:presentationOptions]; 116 makePluginProcessTheFrontProcess(); 117 } 118 119 void PluginProcessProxy::exitFullscreen() 120 { 121 // If the plug-in host is the current application then we should bring ourselves to the front when it exits full-screen mode. 122 ProcessSerialNumber frontProcessSerialNumber; 123 GetFrontProcess(&frontProcessSerialNumber); 124 125 // The UI process must be the front process in order to change the presentation mode. 126 makeUIProcessTheFrontProcess(); 127 [NSApp setPresentationOptions:m_preFullscreenAppPresentationOptions]; 128 129 ProcessSerialNumber pluginProcessSerialNumber; 130 if (!getPluginProcessSerialNumber(pluginProcessSerialNumber)) 131 return; 132 133 // If the plug-in process was not the front process, switch back to the previous front process. 134 // (Otherwise we'll keep the UI process as the front process). 135 Boolean isPluginProcessFrontProcess; 136 SameProcess(&frontProcessSerialNumber, &pluginProcessSerialNumber, &isPluginProcessFrontProcess); 137 if (!isPluginProcessFrontProcess) 138 SetFrontProcess(&frontProcessSerialNumber); 139 } 140 141 void PluginProcessProxy::setModalWindowIsShowing(bool modalWindowIsShowing) 142 { 143 if (modalWindowIsShowing == m_modalWindowIsShowing) 144 return; 145 146 m_modalWindowIsShowing = modalWindowIsShowing; 147 148 if (m_modalWindowIsShowing) 149 beginModal(); 150 else 151 endModal(); 152 } 153 154 void PluginProcessProxy::beginModal() 155 { 156 ASSERT(!m_placeholderWindow); 157 ASSERT(!m_activationObserver); 158 159 m_placeholderWindow.adoptNS([[WKPlaceholderModalWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); 160 161 m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification object:NSApp queue:nil 162 usingBlock:^(NSNotification *){ applicationDidBecomeActive(); }]; 163 164 [NSApp runModalForWindow:m_placeholderWindow.get()]; 165 166 [m_placeholderWindow.get() orderOut:nil]; 167 m_placeholderWindow = nullptr; 168 } 169 170 void PluginProcessProxy::endModal() 171 { 172 ASSERT(m_placeholderWindow); 173 ASSERT(m_activationObserver); 174 175 [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()]; 176 m_activationObserver = nullptr; 177 178 [NSApp stopModal]; 179 180 makeUIProcessTheFrontProcess(); 181 } 182 183 void PluginProcessProxy::applicationDidBecomeActive() 184 { 185 makePluginProcessTheFrontProcess(); 186 } 187 188 189 } // namespace WebKit 190 191 #endif // ENABLE(PLUGIN_PROCESS) 192