DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (6863f516ba38)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/* -*- 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