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 (5350524bb654)

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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/* -*- 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