/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_plugins_PluginHangUIParent_h #define mozilla_plugins_PluginHangUIParent_h #include "nsString.h" #include "base/process.h" #include "base/process_util.h" #include "mozilla/Mutex.h" #include "mozilla/plugins/PluginMessageUtils.h" #include "MiniShmParent.h" namespace mozilla { namespace plugins { class PluginModuleChromeParent; /** * This class is responsible for launching and communicating with the * plugin-hang-ui process. * * NOTE: PluginHangUIParent is *not* an IPDL actor! In this case, "Parent" * is describing the fact that firefox is the parent process to the * plugin-hang-ui process, which is the PluginHangUIChild. * PluginHangUIParent and PluginHangUIChild are a matched pair. * @see PluginHangUIChild */ class PluginHangUIParent : public MiniShmObserver { public: PluginHangUIParent(PluginModuleChromeParent* aModule, const int32_t aHangUITimeoutPref, const int32_t aChildTimeoutPref); virtual ~PluginHangUIParent(); /** * Spawn the plugin-hang-ui.exe child process and terminate the given * plugin container process if the user elects to stop the hung plugin. * * @param aPluginName Human-readable name of the affected plugin. * @return true if the plugin hang ui process was successfully launched, * otherwise false. */ bool Init(const nsString& aPluginName); /** * If the Plugin Hang UI is being shown, send a cancel notification to the * Plugin Hang UI child process. * * @return true if the UI was shown and the cancel command was successfully * sent to the child process, otherwise false. */ bool Cancel(); /** * Returns whether the Plugin Hang UI is currently being displayed. * * @return true if the Plugin Hang UI is showing, otherwise false. */ bool IsShowing() const { return mIsShowing; } /** * Returns whether this Plugin Hang UI instance has been shown. Note * that this does not necessarily mean that the UI is showing right now. * * @return true if the Plugin Hang UI has shown, otherwise false. */ bool WasShown() const { return mIsShowing || mLastUserResponse != 0; } /** * Returns whether the user checked the "Don't ask me again" checkbox. * * @return true if the user does not want to see the Hang UI again. */ bool DontShowAgain() const; /** * Returns whether the user clicked stop during the last time that the * Plugin Hang UI was displayed, if applicable. * * @return true if the UI was shown and the user chose to stop the * plugin, otherwise false */ bool WasLastHangStopped() const; /** * @return unsigned int containing the response bits from the last * time the Plugin Hang UI ran. */ unsigned int LastUserResponse() const { return mLastUserResponse; } /** * @return unsigned int containing the number of milliseconds that * the Plugin Hang UI was displayed before the user responded. * Returns 0 if the Plugin Hang UI has not been shown or was cancelled. */ unsigned int LastShowDurationMs() const; virtual void OnMiniShmEvent(MiniShmBase* aMiniShmObj) override; virtual void OnMiniShmConnect(MiniShmBase* aMiniShmObj) override; private: nsresult GetHangUIOwnerWindowHandle(NativeWindowHandle& windowHandle); bool SendCancel(); bool RecvUserResponse(const unsigned int& aResponse); bool UnwatchHangUIChildProcess(bool aWait); static VOID CALLBACK SOnHangUIProcessExit(PVOID aContext, BOOLEAN aIsTimer); private: Mutex mMutex; PluginModuleChromeParent* mModule; const uint32_t mTimeoutPrefMs; const uint32_t mIPCTimeoutMs; MessageLoop* mMainThreadMessageLoop; bool mIsShowing; unsigned int mLastUserResponse; base::ProcessHandle mHangUIProcessHandle; NativeWindowHandle mMainWindowHandle; HANDLE mRegWait; HANDLE mShowEvent; DWORD mShowTicks; DWORD mResponseTicks; MiniShmParent mMiniShm; DISALLOW_COPY_AND_ASSIGN(PluginHangUIParent); }; } // namespace plugins } // namespace mozilla #endif // mozilla_plugins_PluginHangUIParent_h