Home | History | Annotate | Download | only in mac
      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