void
ClientLayerManager::GetFrameUniformity(FrameUniformityData* aOutData)
{
  MOZ_ASSERT(XRE_IsParentProcess(), "Frame Uniformity only supported in parent process");

  if (HasShadowManager()) {
    CompositorChild* child = GetRemoteRenderer();
    child->SendGetFrameUniformity(aOutData);
    return;
  }

  return LayerManager::GetFrameUniformity(aOutData);
}
GetFileOrDirectoryTask::GetFileOrDirectoryTask(
    FileSystemBase* aFileSystem,
    const FileSystemGetFileOrDirectoryParams& aParam,
    FileSystemRequestParent* aParent)
    : FileSystemTaskBase(aFileSystem, aParam, aParent)
    , mIsDirectory(false)
{
    MOZ_ASSERT(XRE_IsParentProcess(),
               "Only call from parent process!");
    MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    MOZ_ASSERT(aFileSystem);
    mTargetRealPath = aParam.realPath();
}
void
FileSystemTaskBase::SetRequestResult(const FileSystemResponseValue& aValue)
{
  MOZ_ASSERT(!XRE_IsParentProcess(),
             "Only call from child process!");
  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
  if (aValue.type() == FileSystemResponseValue::TFileSystemErrorResponse) {
    FileSystemErrorResponse r = aValue;
    mErrorValue = r.error();
  } else {
    SetSuccessRequestResult(aValue);
  }
}
void
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
{
  if (mLayersId != 0) {
    if (XRE_IsParentProcess()) {
      GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, OtherPid());
    } else if (XRE_IsContentProcess()) {
      ContentChild::GetSingleton()->SendDeallocateLayerTreeId(mLayersId);
    }
  }

  mFrameLoader = nullptr;
}
DOMLocalStorageManager::DOMLocalStorageManager()
  : DOMStorageManager(LocalStorage)
{
  NS_ASSERTION(!sSelf, "Somebody is trying to do_CreateInstance(\"@mozilla/dom/localStorage-manager;1\"");
  sSelf = this;

  if (!XRE_IsParentProcess()) {
    // Do this only on the child process.  The thread IPC bridge
    // is also used to communicate chrome observer notifications.
    // Note: must be called after we set sSelf
    DOMStorageCache::StartDatabase();
  }
}
uint32_t
MsaaIdGenerator::ResolveContentProcessID()
{
  if (XRE_IsParentProcess()) {
    return 0;
  }

  dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
  uint32_t result = contentChild->GetMsaaID();

  MOZ_ASSERT(result);
  return result;
}
Exemple #7
0
already_AddRefed<TextureClient>
AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTexture* aSurfTex,
                                               gfx::IntSize aSize,
                                               gl::OriginPos aOriginPos,
                                               ISurfaceAllocator* aAllocator,
                                               TextureFlags aFlags)
{
  MOZ_ASSERT(XRE_IsParentProcess(),
             "Can't pass an android surfaces between processes.");

  if (!aSurfTex || !XRE_IsParentProcess()) {
    return nullptr;
  }

  if (aOriginPos == gl::OriginPos::BottomLeft) {
    aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
  }

  return TextureClient::CreateWithData(
    new AndroidSurfaceTextureData(aSurfTex, aSize),
    aFlags, aAllocator
  );
}
Exemple #8
0
bool
DeviceManagerDx::CheckRemotePresentSupport()
{
  MOZ_ASSERT(XRE_IsParentProcess());

  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
  if (!adapter) {
    return false;
  }
  if (!D3D11Checks::DoesRemotePresentWork(adapter)) {
    return false;
  }
  return true;
}
Exemple #9
0
NS_IMETHODIMP
nsSpeechTask::SendAudio(JS::Handle<JS::Value> aData, JS::Handle<JS::Value> aLandmarks,
                        JSContext* aCx)
{
  MOZ_ASSERT(XRE_IsParentProcess());

  if(NS_WARN_IF(!(mStream))) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  if(NS_WARN_IF(mStream->IsDestroyed())) {
    return NS_ERROR_NOT_AVAILABLE;
  }
  if(NS_WARN_IF(!(mChannels))) {
    return NS_ERROR_FAILURE;
  }
  if(NS_WARN_IF(!(aData.isObject()))) {
    return NS_ERROR_INVALID_ARG;
  }

  if (mIndirectAudio) {
    NS_WARNING("Can't call SendAudio from an indirect audio speech service.");
    return NS_ERROR_FAILURE;
  }

  JS::Rooted<JSObject*> darray(aCx, &aData.toObject());
  JSAutoCompartment ac(aCx, darray);

  JS::Rooted<JSObject*> tsrc(aCx, nullptr);

  // Allow either Int16Array or plain JS Array
  if (JS_IsInt16Array(darray)) {
    tsrc = darray;
  } else if (JS_IsArrayObject(aCx, darray)) {
    tsrc = JS_NewInt16ArrayFromArray(aCx, darray);
  }

  if (!tsrc) {
    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
  }

  uint32_t dataLen = JS_GetTypedArrayLength(tsrc);
  nsRefPtr<mozilla::SharedBuffer> samples;
  {
    JS::AutoCheckCannotGC nogc;
    samples = makeSamples(JS_GetInt16ArrayData(tsrc, nogc), dataLen);
  }
  SendAudioImpl(samples, dataLen);

  return NS_OK;
}
already_AddRefed<TextureClient>
EGLImageTextureData::CreateTextureClient(EGLImageImage* aImage, gfx::IntSize aSize,
                                         LayersIPCChannel* aAllocator, TextureFlags aFlags)
{
  MOZ_ASSERT(XRE_IsParentProcess(),
             "Can't pass an `EGLImage` between processes.");

  if (!aImage || !XRE_IsParentProcess()) {
    return nullptr;
  }

  // XXX - This is quite sad and slow.
  aFlags |= TextureFlags::DEALLOCATE_CLIENT;

  if (aImage->GetOriginPos() == gl::OriginPos::BottomLeft) {
    aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
  }

  return TextureClient::CreateWithData(
    new EGLImageTextureData(aImage, aSize),
    aFlags, aAllocator
  );
}
void
GetDirectoryListingTask::HandlerCallback()
{
  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
  if (mFileSystem->IsShutdown()) {
    mPromise = nullptr;
    return;
  }

  if (HasError()) {
    mPromise->MaybeReject(mErrorValue);
    mPromise = nullptr;
    return;
  }

  size_t count = mTargetBlobImpls.Length();

  Sequence<OwningFileOrDirectory> listing;

  if (!listing.SetLength(count, mozilla::fallible_t())) {
    mPromise->MaybeReject(NS_ERROR_FAILURE);
    mPromise = nullptr;
    return;
  }

  for (unsigned i = 0; i < count; i++) {
    if (mTargetBlobImpls[i]->IsDirectory()) {
      nsAutoString name;
      mTargetBlobImpls[i]->GetName(name);
      nsAutoString path(mTargetRealPath);
      path.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR);
      path.Append(name);
#ifdef DEBUG
      if (XRE_IsParentProcess()) {
        nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(path);
        bool exist;
        file->Exists(&exist);
        MOZ_ASSERT(exist);
      }
#endif
      listing[i].SetAsDirectory() = new Directory(mFileSystem, path);
    } else {
      listing[i].SetAsFile() = File::Create(mFileSystem->GetWindow(), mTargetBlobImpls[i]);
    }
  }

  mPromise->MaybeResolve(listing);
  mPromise = nullptr;
}
Exemple #12
0
VRManager::VRManager()
  : mInitialized(false)
  , mVRTestSystemCreated(false)
{
  MOZ_COUNT_CTOR(VRManager);
  MOZ_ASSERT(sVRManagerSingleton == nullptr);

  RefPtr<VRSystemManager> mgr;

  /**
   * We must add the VRDisplayManager's to mManagers in a careful order to
   * ensure that we don't detect the same VRDisplay from multiple API's.
   *
   * Oculus comes first, as it will only enumerate Oculus HMD's and is the
   * native interface for Oculus HMD's.
   *
   * OpenvR comes second, as it is the native interface for HTC Vive
   * which is the most common HMD at this time.
   *
   * OSVR will be used if Oculus SDK and OpenVR don't detect any HMDS,
   * to support everyone else.
   */

#if defined(XP_WIN)
  // The Oculus runtime is supported only on Windows
  mgr = VRSystemManagerOculus::Create();
  if (mgr) {
    mManagers.AppendElement(mgr);
  }
  // OpenVR is cross platform compatible, but supported only on Windows for now
  mgr = VRSystemManagerOpenVR::Create();
  if (mgr) {
    mManagers.AppendElement(mgr);
  }
#endif

#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
  // OSVR is cross platform compatible
  mgr = VRSystemManagerOSVR::Create();
  if (mgr) {
      mManagers.AppendElement(mgr);
  }
#endif
  // Enable gamepad extensions while VR is enabled.
  // Preference only can be set at the Parent process.
  if (XRE_IsParentProcess() && gfxPrefs::VREnabled()) {
    Preferences::SetBool("dom.gamepad.extensions.enabled", true);
  }
}
NS_IMETHODIMP
nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode)
{
    // Should only be called in the parent process.
    MOZ_ASSERT(XRE_IsParentProcess());

    if (aErrorCode == NS_ERROR_TRACKING_URI &&
        NS_SUCCEEDED(IsTrackerWhitelisted())) {
      LOG(("nsChannelClassifier[%p]:OnClassifyComplete tracker found "
           "in whitelist so we won't block it", this));
      aErrorCode = NS_OK;
    }

    if (mSuspendedChannel) {
      nsAutoCString errorName;
      if (LOG_ENABLED()) {
        GetErrorName(aErrorCode, errorName);
        LOG(("nsChannelClassifier[%p]:OnClassifyComplete %s (suspended channel)",
             this, errorName.get()));
      }
      MarkEntryClassified(aErrorCode);

      if (NS_FAILED(aErrorCode)) {
        if (LOG_ENABLED()) {
          nsCOMPtr<nsIURI> uri;
          mChannel->GetURI(getter_AddRefs(uri));
          LOG(("nsChannelClassifier[%p]: cancelling channel %p for %s "
               "with error code %s", this, mChannel.get(),
               uri->GetSpecOrDefault().get(), errorName.get()));
        }

        // Channel will be cancelled (page element blocked) due to tracking.
        // Do update the security state of the document and fire a security
        // change event.
        if (aErrorCode == NS_ERROR_TRACKING_URI) {
          SetBlockedTrackingContent(mChannel);
        }

        mChannel->Cancel(aErrorCode);
      }
      LOG(("nsChannelClassifier[%p]: resuming channel %p from "
           "OnClassifyComplete", this, mChannel.get()));
      mChannel->Resume();
    }

    mChannel = nullptr;

    return NS_OK;
}
Exemple #14
0
void nsVolume::Set(nsIVolume* aVolume)
{
  MOZ_ASSERT(NS_IsMainThread());

  aVolume->GetName(mName);
  aVolume->GetMountPoint(mMountPoint);
  aVolume->GetState(&mState);
  aVolume->GetIsFake(&mIsFake);
  aVolume->GetIsMediaPresent(&mIsMediaPresent);
  aVolume->GetIsSharing(&mIsSharing);
  aVolume->GetIsFormatting(&mIsFormatting);
  aVolume->GetIsUnmounting(&mIsUnmounting);
  aVolume->GetIsRemovable(&mIsRemovable);
  aVolume->GetIsHotSwappable(&mIsHotSwappable);

  int32_t volMountGeneration;
  aVolume->GetMountGeneration(&volMountGeneration);

  if (mState != nsIVolume::STATE_MOUNTED) {
    // Since we're not in the mounted state, we need to
    // forgot whatever mount generation we may have had.
    mMountGeneration = -1;
    return;
  }
  if (mMountGeneration == volMountGeneration) {
    // No change in mount generation, nothing else to do
    return;
  }

  mMountGeneration = volMountGeneration;

  if (!XRE_IsParentProcess()) {
    // Child processes just track the state, not maintain it.
    aVolume->GetIsMountLocked(&mMountLocked);
    return;
  }

  // Notify the Volume on IOThread whether the volume is locked or not.
  nsCOMPtr<nsIPowerManagerService> pmService =
    do_GetService(POWERMANAGERSERVICE_CONTRACTID);
  if (!pmService) {
    return;
  }
  nsString mountLockName;
  GetMountLockName(mountLockName);
  nsString mountLockState;
  pmService->GetWakeLockState(mountLockName, mountLockState);
  UpdateMountLock(mountLockState);
}
Exemple #15
0
void
nsSpeechTask::Resume()
{
  MOZ_ASSERT(XRE_IsParentProcess());

  if (mCallback) {
    DebugOnly<nsresult> rv = mCallback->OnResume();
    NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to call onResume() callback");
  }

  if (mStream) {
    mStream->ChangeExplicitBlockerCount(-1);
    DispatchResumeImpl(GetCurrentTime(), GetCurrentCharOffset());
  }
}
Exemple #16
0
already_AddRefed<nsIFile>
FileSystemBase::GetLocalFile(const nsAString& aRealPath) const
{
    MOZ_ASSERT(XRE_IsParentProcess(),
               "Should be on parent process!");
    nsAutoString localPath;
    FileSystemUtils::NormalizedPathToLocalPath(aRealPath, localPath);
    localPath = mLocalRootPath + localPath;
    nsCOMPtr<nsIFile> file;
    nsresult rv = NS_NewLocalFile(localPath, false, getter_AddRefs(file));
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return nullptr;
    }
    return file.forget();
}
void
D3D11LayersCrashGuard::Initialize()
{
  if (!XRE_IsParentProcess()) {
    // We assume the parent process already performed crash detection for
    // graphics devices.
    return;
  }

  DriverCrashGuard::Initialize();

  // If no telemetry states have been recorded, this will set the state to okay.
  // Otherwise, it will have no effect.
  RecordTelemetry(TelemetryState::Okay);
}
Exemple #18
0
nsPicoService*
nsPicoService::GetInstance()
{
  MOZ_ASSERT(NS_IsMainThread());
  if (!XRE_IsParentProcess()) {
    MOZ_ASSERT(false, "nsPicoService can only be started on main gecko process");
    return nullptr;
  }

  if (!sSingleton) {
    sSingleton = new nsPicoService();
  }

  return sSingleton;
}
FileSystemTaskParentBase::FileSystemTaskParentBase(FileSystemBase* aFileSystem,
                                                  const FileSystemParams& aParam,
                                                  FileSystemRequestParent* aParent)
  : mErrorValue(NS_OK)
  , mFileSystem(aFileSystem)
  , mRequestParent(aParent)
  , mBackgroundEventTarget(NS_GetCurrentThread())
{
  MOZ_ASSERT(XRE_IsParentProcess(),
             "Only call from parent process!");
  MOZ_ASSERT(aFileSystem, "aFileSystem should not be null.");
  MOZ_ASSERT(aParent);
  MOZ_ASSERT(mBackgroundEventTarget);
  AssertIsOnBackgroundThread();
}
void
CompositorVsyncDispatcher::ObserveVsync(bool aEnable)
{
  MOZ_ASSERT(NS_IsMainThread());
  MOZ_ASSERT(XRE_IsParentProcess());
  if (mDidShutdown) {
    return;
  }

  if (aEnable) {
    gfxPlatform::GetPlatform()->GetHardwareVsync()->AddCompositorVsyncDispatcher(this);
  } else {
    gfxPlatform::GetPlatform()->GetHardwareVsync()->RemoveCompositorVsyncDispatcher(this);
  }
}
void
CompositorVsyncDispatcher::Shutdown()
{
  // Need to explicitly remove CompositorVsyncDispatcher when the nsBaseWidget shuts down.
  // Otherwise, we would get dead vsync notifications between when the nsBaseWidget
  // shuts down and the CompositorParent shuts down.
  MOZ_ASSERT(XRE_IsParentProcess());
  MOZ_ASSERT(NS_IsMainThread());
  ObserveVsync(false);
  mDidShutdown = true;
  { // scope lock
    MutexAutoLock lock(mCompositorObserverLock);
    mCompositorVsyncObserver = nullptr;
  }
}
void BrowsingContext::Detach(bool aFromIPC) {
  MOZ_LOG(GetLog(), LogLevel::Debug,
          ("%s: Detaching 0x%08" PRIx64 " from 0x%08" PRIx64,
           XRE_IsParentProcess() ? "Parent" : "Child", Id(),
           mParent ? mParent->Id() : 0));

  RefPtr<BrowsingContext> kungFuDeathGrip(this);

  BrowsingContextMap<RefPtr>::Ptr p;
  if (sCachedBrowsingContexts && (p = sCachedBrowsingContexts->lookup(Id()))) {
    MOZ_DIAGNOSTIC_ASSERT(!mParent || !mParent->mChildren.Contains(this));
    MOZ_DIAGNOSTIC_ASSERT(!mGroup || !mGroup->Toplevels().Contains(this));
    sCachedBrowsingContexts->remove(p);
  } else {
    Children* children = nullptr;
    if (mParent) {
      children = &mParent->mChildren;
    } else if (mGroup) {
      children = &mGroup->Toplevels();
    }

    if (children) {
      // TODO(farre): This assert looks extremely fishy, I know, but
      // what we're actually saying is this: if we're detaching, but our
      // parent doesn't have any children, it is because we're being
      // detached by the cycle collector destroying docshells out of
      // order.
      MOZ_DIAGNOSTIC_ASSERT(children->IsEmpty() || children->Contains(this));

      children->RemoveElement(this);
    }
  }

  if (mGroup) {
    mGroup->Unregister(this);
  }

  // As our nsDocShell is going away, this should implicitly mark us as closed.
  // We directly set our member, rather than using a transaction as we're going
  // to send a `Detach` message to other processes either way.
  mClosed = true;

  if (!aFromIPC && XRE_IsContentProcess()) {
    auto cc = ContentChild::GetSingleton();
    MOZ_DIAGNOSTIC_ASSERT(cc);
    cc->SendDetachBrowsingContext(this, false /* aMoveToBFCache */);
  }
}
Exemple #23
0
static bool
InitLog(const char* aEnvVar, const char* aMsg, FILE** aResult)
{
  const char* value = getenv(aEnvVar);
  if (value) {
    if (nsCRT::strcmp(value, "1") == 0) {
      *aResult = stdout;
      fprintf(stdout, "### %s defined -- logging %s to stdout\n",
              aEnvVar, aMsg);
      return true;
    } else if (nsCRT::strcmp(value, "2") == 0) {
      *aResult = stderr;
      fprintf(stdout, "### %s defined -- logging %s to stderr\n",
              aEnvVar, aMsg);
      return true;
    } else {
      FILE* stream;
      nsAutoCString fname(value);
      if (!XRE_IsParentProcess()) {
        bool hasLogExtension =
          fname.RFind(".log", true, -1, 4) == kNotFound ? false : true;
        if (hasLogExtension) {
          fname.Cut(fname.Length() - 4, 4);
        }
        fname.Append('_');
        fname.Append((char*)XRE_ChildProcessTypeToString(XRE_GetProcessType()));
        fname.AppendLiteral("_pid");
        fname.AppendInt((uint32_t)getpid());
        if (hasLogExtension) {
          fname.AppendLiteral(".log");
        }
      }
      stream = ::fopen(fname.get(), "w" FOPEN_NO_INHERIT);
      if (stream) {
        MozillaRegisterDebugFD(fileno(stream));
        *aResult = stream;
        fprintf(stdout, "### %s defined -- logging %s to %s\n",
                aEnvVar, aMsg, fname.get());
      } else {
        fprintf(stdout, "### %s defined -- unable to log %s to %s\n",
                aEnvVar, aMsg, fname.get());
        MOZ_ASSERT(false, "Tried and failed to create an XPCOM log");
      }
      return stream != nullptr;
    }
  }
  return false;
}
void BrowsingContext::Transaction::Commit(BrowsingContext* aBrowsingContext) {
  if (XRE_IsContentProcess()) {
    ContentChild* cc = ContentChild::GetSingleton();
    cc->SendCommitBrowsingContextTransaction(aBrowsingContext, *this);
  } else {
    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
    for (auto iter = aBrowsingContext->Group()->ContentParentsIter();
         !iter.Done(); iter.Next()) {
      nsRefPtrHashKey<ContentParent>* entry = iter.Get();
      Unused << entry->GetKey()->SendCommitBrowsingContextTransaction(
          aBrowsingContext, *this);
    }
  }

  Apply(aBrowsingContext, nullptr);
}
/*static*/ sp<GraphicBuffer>
GetGraphicBufferFrom(MaybeMagicGrallocBufferHandle aHandle)
{
  if (aHandle.type() != MaybeMagicGrallocBufferHandle::TMagicGrallocBufferHandle) {
    if (aHandle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
      if (XRE_IsParentProcess()) {
        return SharedBufferManagerParent::GetGraphicBuffer(aHandle.get_GrallocBufferRef());
      }
      return SharedBufferManagerChild::GetSingleton()->GetGraphicBuffer(aHandle.get_GrallocBufferRef().mKey);
    }
  } else {
    MagicGrallocBufferHandle realHandle = aHandle.get_MagicGrallocBufferHandle();
    return realHandle.mGraphicBuffer;
  }
  return nullptr;
}
uint32_t
GamepadPlatformService::AddGamepad(const char* aID,
                                   GamepadMappingType aMapping,
                                   uint32_t aNumButtons, uint32_t aNumAxes)
{
  // This method is called by monitor thread populated in
  // platform-dependent backends
  MOZ_ASSERT(XRE_IsParentProcess());
  MOZ_ASSERT(!NS_IsMainThread());

  uint32_t index = ++mGamepadIndex;
  GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
                 aMapping, GamepadServiceType::Standard, aNumButtons, aNumAxes);
  NotifyGamepadChange<GamepadAdded>(a);
  return index;
}
void RemoteWorkerManager::LaunchNewContentProcess() {
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(XRE_IsParentProcess());

  // This runnable will spawn a new process if it doesn't exist yet.
  nsCOMPtr<nsIRunnable> r =
      NS_NewRunnableFunction("LaunchNewContentProcess", []() {
        RefPtr<ContentParent> unused =
            ContentParent::GetNewOrUsedBrowserProcess(
                nullptr, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
      });

  nsCOMPtr<nsIEventTarget> target =
      SystemGroup::EventTargetFor(TaskCategory::Other);
  target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}
Exemple #28
0
  nsresult OpenContentStream(bool async, nsIInputStream** stream,
                             nsIChannel** channel) override {
    nsAutoCString spec;
    mURI->GetSpec(spec);

    if (spec.EqualsASCII("about:crashparent") && XRE_IsParentProcess()) {
      MOZ_CRASH("Crash via about:crashparent");
    }

    if (spec.EqualsASCII("about:crashcontent") && XRE_IsContentProcess()) {
      MOZ_CRASH("Crash via about:crashcontent");
    }

    NS_WARNING("Unhandled about:crash* URI or wrong process");
    return NS_ERROR_NOT_IMPLEMENTED;
  }
// static
already_AddRefed<GamepadPlatformService>
GamepadPlatformService::GetParentService()
{
  //GamepadPlatformService can only be accessed in parent process
  MOZ_ASSERT(XRE_IsParentProcess());
  if (!gGamepadPlatformServiceSingleton) {
    // Only Background Thread can create new GamepadPlatformService instance.
    if (IsOnBackgroundThread()) {
      gGamepadPlatformServiceSingleton = new GamepadPlatformService();
    } else {
      return nullptr;
    }
  }
  RefPtr<GamepadPlatformService> service(gGamepadPlatformServiceSingleton);
  return service.forget();
}
NS_IMETHODIMP
U2FTokenManager::Cancel(uint64_t aTransactionId)
{
  MOZ_ASSERT(XRE_IsParentProcess());
  MOZ_ASSERT(NS_IsMainThread());

  if (!gBackgroundThread) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIRunnable> r(NewRunnableMethod<uint64_t>(
      "U2FTokenManager::RunCancel", this,
      &U2FTokenManager::RunCancel, aTransactionId));

  return gBackgroundThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
}