Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/gmp/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 25 kB image not shown  

Quelle  GMPChild.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */


#include "GMPChild.h"

#include "base/command_line.h"
#include "base/task.h"
#include "ChildProfilerController.h"
#include "ChromiumCDMAdapter.h"
#include "GeckoProfiler.h"
#ifdef XP_LINUX
#  include "dlfcn.h"
#  if defined(MOZ_SANDBOX)
#    include "mozilla/Sandbox.h"
#  endif  // defined(MOZ_SANDBOX)
#endif    // defined (XP_LINUX)
#include "gmp-video-decode.h"
#include "gmp-video-encode.h"
#include "GMPContentChild.h"
#include "GMPLoader.h"
#include "GMPLog.h"
#include "GMPPlatform.h"
#include "GMPProcessChild.h"
#include "GMPProcessParent.h"
#include "GMPUtils.h"
#include "GMPVideoDecoderChild.h"
#include "GMPVideoEncoderChild.h"
#include "GMPVideoHost.h"
#include "mozilla/Algorithm.h"
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/FOGIPC.h"
#include "mozilla/glean/GleanTestsTestMetrics.h"
#include "mozilla/ipc/CrashReporterClient.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/TextUtils.h"
#include "nsDebugImpl.h"
#include "nsExceptionHandler.h"
#include "nsIFile.h"
#include "nsReadableUtils.h"
#include "nsThreadManager.h"
#include "nsXULAppAPI.h"
#include "nsIXULRuntime.h"
#include "nsXPCOM.h"
#include "nsXPCOMPrivate.h"  // for XUL_DLL
#include "prio.h"
#ifdef XP_WIN
#  include <stdlib.h>  // for _exit()
#  include "nsIObserverService.h"
#  include "mozilla/Services.h"
#  include "mozilla/WinDllServices.h"
#  include "WinUtils.h"
#else
#  include <unistd.h>  // for _exit()
#endif

using namespace mozilla::ipc;

namespace mozilla {
namespace gmp {

#define GMP_CHILD_LOG(loglevel, x, ...) \
  MOZ_LOG(                              \
      GetGMPLog(), (loglevel),          \
      ("GMPChild[pid=%d] " x, (int)base::GetCurrentProcId(), ##__VA_ARGS__))

#define GMP_CHILD_LOG_DEBUG(x, ...) \
  GMP_CHILD_LOG(LogLevel::Debug, x, ##__VA_ARGS__)

GMPChild::GMPChild()
    : mGMPMessageLoop(MessageLoop::current()), mGMPLoader(nullptr) {
  GMP_CHILD_LOG_DEBUG("GMPChild ctor");
  nsDebugImpl::SetMultiprocessMode("GMP");
}

GMPChild::~GMPChild() {
  GMP_CHILD_LOG_DEBUG("GMPChild dtor");
#ifdef XP_LINUX
  for (auto& libHandle : mLibHandles) {
    dlclose(libHandle);
  }
#endif
}

bool GMPChild::Init(const nsAString& aPluginPath, const char* aParentBuildID,
                    mozilla::ipc::UntypedEndpoint&& aEndpoint) {
  GMP_CHILD_LOG_DEBUG("%s pluginPath=%s useXpcom=%d, useNativeEvent=%d",
                      __FUNCTION__, NS_ConvertUTF16toUTF8(aPluginPath).get(),
                      GMPProcessChild::UseXPCOM(),
                      GMPProcessChild::UseNativeEventProcessing());

  // GMPChild needs nsThreadManager to create the ProfilerChild thread.
  // It is also used on debug builds for the sandbox tests.
  if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) {
    return false;
  }

  if (NS_WARN_IF(!aEndpoint.Bind(this))) {
    return false;
  }

  // This must be checked before any IPDL message, which may hit sentinel
  // errors due to parent and content processes having different
  // versions.
  MessageChannel* channel = GetIPCChannel();
  if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
    // We need to quit this process if the buildID doesn't match the parent's.
    // This can occur when an update occurred in the background.
    ipc::ProcessChild::QuickExit();
  }

  CrashReporterClient::InitSingleton(this);

  if (GMPProcessChild::UseXPCOM()) {
    if (NS_WARN_IF(NS_FAILED(NS_InitMinimalXPCOM()))) {
      return false;
    }
  } else {
    BackgroundHangMonitor::Startup();
  }

  mPluginPath = aPluginPath;

  nsAutoCString processName("GMPlugin Process");

  nsAutoCString pluginName;
  if (GetPluginName(pluginName)) {
    processName.AppendLiteral(" (");
    processName.Append(pluginName);
    processName.AppendLiteral(")");
  }

  profiler_set_process_name(processName);

  return true;
}

void GMPChild::Shutdown() {
  if (GMPProcessChild::UseXPCOM()) {
    NS_ShutdownXPCOM(nullptr);
  } else {
    BackgroundHangMonitor::Shutdown();
  }
}

mozilla::ipc::IPCResult GMPChild::RecvProvideStorageId(
    const nsCString& aStorageId) {
  GMP_CHILD_LOG_DEBUG("%s", __FUNCTION__);
  mStorageId = aStorageId;
  return IPC_OK();
}

GMPErr GMPChild::GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI,
                        const nsACString& aKeySystem) {
  if (!mGMPLoader) {
    return GMPGenericErr;
  }
  return mGMPLoader->GetAPI(aAPIName, aHostAPI, aPluginAPI, aKeySystem);
}

mozilla::ipc::IPCResult GMPChild::RecvPreloadLibs(const nsCString& aLibs) {
  // Pre-load libraries that may need to be used by the EME plugin but that
  // can't be loaded after the sandbox has started.
#ifdef XP_WIN
  // Items in this must be lowercase!
  constexpr static const char16_t* whitelist[] = {
      u"dxva2.dll",        // Get monitor information
      u"evr.dll",          // MFGetStrideForBitmapInfoHeader
      u"freebl3.dll",      // NSS for clearkey CDM
      u"mfplat.dll",       // MFCreateSample, MFCreateAlignedMemoryBuffer,
                           // MFCreateMediaType
      u"msmpeg2vdec.dll",  // H.264 decoder
      u"nss3.dll",         // NSS for clearkey CDM
      u"ole32.dll",        // required for OPM
      u"oleaut32.dll",     // For _bstr_t use in libwebrtc, see bug 1788592
      u"psapi.dll",        // For GetMappedFileNameW, see bug 1383611
      u"shell32.dll",      // Dependency for widevine
      u"softokn3.dll",     // NSS for clearkey CDM
      u"winmm.dll",        // Dependency for widevine
  };
  constexpr static bool (*IsASCII)(const char16_t*) =
      IsAsciiNullTerminated<char16_t>;
  static_assert(AllOf(std::begin(whitelist), std::end(whitelist), IsASCII),
                "Items in the whitelist must not contain non-ASCII "
                "characters!");

  nsTArray<nsCString> libs;
  SplitAt(", ", aLibs, libs);
  for (nsCString lib : libs) {
    ToLowerCase(lib);
    for (const char16_t* whiteListedLib : whitelist) {
      if (nsDependentString(whiteListedLib)
              .EqualsASCII(lib.Data(), lib.Length())) {
        LoadLibraryW(char16ptr_t(whiteListedLib));
        break;
      }
    }
  }
#elif defined(XP_LINUX)
  constexpr static const char* whitelist[] = {
      // NSS libraries used by clearkey.
      "libfreeblpriv3.so",
      "libsoftokn3.so",
      // glibc libraries merged into libc.so.6; see bug 1725828 and
      // the corresponding code in GMPParent.cpp.
      "libdl.so.2",
      "libpthread.so.0",
      "librt.so.1",
  };

  nsTArray<nsCString> libs;
  SplitAt(", ", aLibs, libs);
  for (const nsCString& lib : libs) {
    for (const char* whiteListedLib : whitelist) {
      if (lib.EqualsASCII(whiteListedLib)) {
        auto libHandle = dlopen(whiteListedLib, RTLD_NOW | RTLD_GLOBAL);
        if (libHandle) {
          mLibHandles.AppendElement(libHandle);
        } else {
          // TODO(bug 1698718): remove the logging once we've identified
          // the cause of the load failure.
          const char* error = dlerror();
          if (error) {
            // We should always have an error, but gracefully handle just in
            // case.
            nsAutoCString nsError{error};
            CrashReporter::AppendAppNotesToCrashReport(nsError);
          }
          // End bug 1698718 logging.

          MOZ_CRASH("Couldn't load lib needed by media plugin");
        }
      }
    }
  }
#endif
  return IPC_OK();
}

bool GMPChild::GetUTF8LibPath(nsACString& aOutLibPath) {
  nsCOMPtr<nsIFile> libFile;

#define GMP_PATH_CRASH(explain)                           \
  do {                                                    \
    nsAutoString path;                                    \
    if (!libFile || NS_FAILED(libFile->GetPath(path))) {  \
      path = mPluginPath;                                 \
    }                                                     \
    CrashReporter::RecordAnnotationNSString(              \
        CrashReporter::Annotation::GMPLibraryPath, path); \
    MOZ_CRASH(explain);                                   \
  } while (false)

  nsresult rv = NS_NewLocalFile(mPluginPath, getter_AddRefs(libFile));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    GMP_PATH_CRASH("Failed to create file for plugin path");
    return false;
  }

  nsCOMPtr<nsIFile> parent;
  rv = libFile->GetParent(getter_AddRefs(parent));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    GMP_PATH_CRASH("Failed to get parent file for plugin file");
    return false;
  }

  nsAutoString parentLeafName;
  rv = parent->GetLeafName(parentLeafName);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    GMP_PATH_CRASH("Failed to get leaf for plugin file");
    return false;
  }

  nsAutoString baseName;
  baseName = Substring(parentLeafName, 4, parentLeafName.Length() - 1);

#if defined(XP_MACOSX)
  nsAutoString binaryName = u"lib"_ns + baseName + u".dylib"_ns;
#elif defined(XP_UNIX)
  nsAutoString binaryName = u"lib"_ns + baseName + u".so"_ns;
#elif defined(XP_WIN)
  nsAutoString binaryName = baseName + u".dll"_ns;
#else
#  error not defined
#endif
  rv = libFile->AppendRelativePath(binaryName);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    GMP_PATH_CRASH("Failed to append lib to plugin file");
    return false;
  }

  if (NS_WARN_IF(!FileExists(libFile))) {
    GMP_PATH_CRASH("Plugin file does not exist");
    return false;
  }

  nsAutoString path;
  rv = libFile->GetPath(path);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    GMP_PATH_CRASH("Failed to get path for plugin file");
    return false;
  }

  CopyUTF16toUTF8(path, aOutLibPath);
  return true;
}

bool GMPChild::GetPluginName(nsACString& aPluginName) const {
  // Extract the plugin directory name if possible.
  nsCOMPtr<nsIFile> libFile;
  nsresult rv = NS_NewLocalFile(mPluginPath, getter_AddRefs(libFile));
  NS_ENSURE_SUCCESS(rv, false);

  nsCOMPtr<nsIFile> parent;
  rv = libFile->GetParent(getter_AddRefs(parent));
  NS_ENSURE_SUCCESS(rv, false);

  nsAutoString parentLeafName;
  rv = parent->GetLeafName(parentLeafName);
  NS_ENSURE_SUCCESS(rv, false);

  aPluginName.Assign(NS_ConvertUTF16toUTF8(parentLeafName));
  return true;
}

static nsCOMPtr<nsIFile> AppendFile(nsCOMPtr<nsIFile>&& aFile,
                                    const nsString& aStr) {
  return (aFile && NS_SUCCEEDED(aFile->Append(aStr))) ? aFile : nullptr;
}

static nsCOMPtr<nsIFile> CloneFile(const nsCOMPtr<nsIFile>& aFile) {
  nsCOMPtr<nsIFile> clone;
  return (aFile && NS_SUCCEEDED(aFile->Clone(getter_AddRefs(clone)))) ? clone
                                                                      : nullptr;
}

static nsCOMPtr<nsIFile> GetParentFile(const nsCOMPtr<nsIFile>& aFile) {
  nsCOMPtr<nsIFile> parent;
  return (aFile && NS_SUCCEEDED(aFile->GetParent(getter_AddRefs(parent))))
             ? parent
             : nullptr;
}

#if defined(XP_WIN)
static bool IsFileLeafEqualToASCII(const nsCOMPtr<nsIFile>& aFile,
                                   const char* aStr) {
  nsAutoString leafName;
  return aFile && NS_SUCCEEDED(aFile->GetLeafName(leafName)) &&
         leafName.EqualsASCII(aStr);
}
#endif

#if defined(XP_WIN)
#  define FIREFOX_FILE MOZ_APP_NAME u".exe"_ns
#else
#  define FIREFOX_FILE MOZ_APP_NAME u""_ns
#endif
#define XUL_LIB_FILE XUL_DLL u""_ns

static nsCOMPtr<nsIFile> GetFirefoxAppPath(
    nsCOMPtr<nsIFile> aPluginContainerPath) {
  MOZ_ASSERT(aPluginContainerPath);
#if defined(XP_MACOSX)
  // On MacOS the firefox binary is a few parent directories up from
  // plugin-container.
  // aPluginContainerPath will end with something like:
  // xxxx/NightlyDebug.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container
  nsCOMPtr<nsIFile> path = aPluginContainerPath;
  for (int i = 0; i < 4; i++) {
    path = GetParentFile(path);
  }
  return path;
#else
  nsCOMPtr<nsIFile> parent = GetParentFile(aPluginContainerPath);
#  if XP_WIN
  if (IsFileLeafEqualToASCII(parent, "i686")) {
    // We must be on Windows on ARM64, where the plugin-container path will
    // be in the 'i686' subdir. The firefox.exe is in the parent directory.
    parent = GetParentFile(parent);
  }
#  endif
  return parent;
#endif
}

#if defined(XP_MACOSX)
static bool GetSigPath(const int aRelativeLayers,
                       const nsString& aTargetSigFileName,
                       nsCOMPtr<nsIFile> aExecutablePath,
                       nsCOMPtr<nsIFile>& aOutSigPath) {
  // The sig file will be located in
  // xxxx/NightlyDebug.app/Contents/Resources/XUL.sig
  // xxxx/NightlyDebug.app/Contents/Resources/firefox.sig
  // xxxx/NightlyDebug.app/Contents/MacOS/plugin-container.app/Contents/Resources/plugin-container.sig
  // On MacOS the sig file is a few parent directories up from
  // its executable file.
  // Start to search the path from the path of the executable file we provided.
  MOZ_ASSERT(aExecutablePath);
  nsCOMPtr<nsIFile> path = aExecutablePath;
  for (int i = 0; i < aRelativeLayers; i++) {
    nsCOMPtr<nsIFile> parent;
    if (NS_WARN_IF(NS_FAILED(path->GetParent(getter_AddRefs(parent))))) {
      return false;
    }
    path = parent;
  }
  MOZ_ASSERT(path);
  aOutSigPath = path;
  return NS_SUCCEEDED(path->Append(u"Resources"_ns)) &&
         NS_SUCCEEDED(path->Append(aTargetSigFileName));
}
#endif

static bool AppendHostPath(nsCOMPtr<nsIFile>& aFile,
                           nsTArray<std::pair<nsCString, nsCString>>& aPaths) {
  nsString str;
  if (!FileExists(aFile) || NS_FAILED(aFile->GetPath(str))) {
    return false;
  }

  nsCString filePath = NS_ConvertUTF16toUTF8(str);
  nsCString sigFilePath;
#if defined(XP_MACOSX)
  nsAutoString binary;
  if (NS_FAILED(aFile->GetLeafName(binary))) {
    return false;
  }
  binary.Append(u".sig"_ns);
  nsCOMPtr<nsIFile> sigFile;
  if (GetSigPath(2, binary, aFile, sigFile) &&
      NS_SUCCEEDED(sigFile->GetPath(str))) {
    CopyUTF16toUTF8(str, sigFilePath);
  } else {
    // Cannot successfully get the sig file path.
    // Assume it is located at the same place as plugin-container
    // alternatively.
    sigFilePath = nsCString(NS_ConvertUTF16toUTF8(str) + ".sig"_ns);
  }
#else
  sigFilePath = nsCString(NS_ConvertUTF16toUTF8(str) + ".sig"_ns);
#endif
  aPaths.AppendElement(
      std::make_pair(std::move(filePath), std::move(sigFilePath)));
  return true;
}

nsTArray<std::pair<nsCString, nsCString>>
GMPChild::MakeCDMHostVerificationPaths(const nsACString& aPluginLibPath) {
  // Record the file path and its sig file path.
  nsTArray<std::pair<nsCString, nsCString>> paths;
  // Plugin binary path.
  paths.AppendElement(
      std::make_pair(nsCString(aPluginLibPath), aPluginLibPath + ".sig"_ns));

  // Plugin-container binary path.
  // Note: clang won't let us initialize an nsString from a wstring, so we
  // need to go through UTF8 to get to an nsString.
  const std::string pluginContainer =
      WideToUTF8(CommandLine::ForCurrentProcess()->program());
  nsString str;

  CopyUTF8toUTF16(nsDependentCString(pluginContainer.c_str()), str);
  nsCOMPtr<nsIFile> path;
  if (NS_FAILED(NS_NewLocalFile(str, getter_AddRefs(path))) ||
      !AppendHostPath(path, paths)) {
    // Without successfully determining plugin-container's path, we can't
    // determine libxul's or Firefox's. So give up.
    return paths;
  }

#if defined(XP_WIN)
  // On Windows on ARM64, we should also append the x86 plugin-container's
  // xul.dll.
  const bool isWindowsOnARM64 =
      IsFileLeafEqualToASCII(GetParentFile(path), "i686");
  if (isWindowsOnARM64) {
    nsCOMPtr<nsIFile> x86XulPath =
        AppendFile(GetParentFile(path), XUL_LIB_FILE);
    if (!AppendHostPath(x86XulPath, paths)) {
      return paths;
    }
  }
#endif

  // Firefox application binary path.
  nsCOMPtr<nsIFile> appDir = GetFirefoxAppPath(path);
  path = AppendFile(CloneFile(appDir), FIREFOX_FILE);
  if (!AppendHostPath(path, paths)) {
    return paths;
  }

  // Libxul path. Note: re-using 'appDir' var here, as we assume libxul is in
  // the same directory as Firefox executable.
  appDir->GetPath(str);
  path = AppendFile(CloneFile(appDir), XUL_LIB_FILE);
  if (!AppendHostPath(path, paths)) {
    return paths;
  }

  return paths;
}

static auto ToCString(const nsTArray<std::pair<nsCString, nsCString>>& aPairs) {
  return StringJoin(","_ns, aPairs, [](nsACString& dest, const auto& p) {
    dest.AppendPrintf("(%s,%s)", p.first.get(), p.second.get());
  });
}

mozilla::ipc::IPCResult GMPChild::RecvStartPlugin(const nsString& aAdapter) {
  GMP_CHILD_LOG_DEBUG("%s", __FUNCTION__);

  nsAutoCString libPath;
  if (!GetUTF8LibPath(libPath)) {
    CrashReporter::RecordAnnotationNSCString(
        CrashReporter::Annotation::GMPLibraryPath,
        NS_ConvertUTF16toUTF8(mPluginPath));

#ifdef XP_WIN
    GMP_CHILD_LOG(LogLevel::Error, "Failed to get lib path with error(%lu).",
                  GetLastError());
#endif
    return IPC_FAIL(this"Failed to get lib path.");
  }

  auto platformAPI = new GMPPlatformAPI();
  InitPlatformAPI(*platformAPI, this);

  mGMPLoader = MakeUnique<GMPLoader>();
#if defined(MOZ_SANDBOX) && !defined(XP_MACOSX)
  if (!mGMPLoader->CanSandbox()) {
    GMP_CHILD_LOG_DEBUG("%s Can't sandbox GMP, failing", __FUNCTION__);
    delete platformAPI;
    return IPC_FAIL(this"Can't sandbox GMP.");
  }
#endif

  GMPAdapter* adapter = nullptr;
  if (aAdapter.EqualsLiteral("chromium")) {
    auto&& paths = MakeCDMHostVerificationPaths(libPath);
    GMP_CHILD_LOG_DEBUG("%s CDM host paths=%s", __func__,
                        ToCString(paths).get());
    adapter = new ChromiumCDMAdapter(std::move(paths));
  }

  if (!mGMPLoader->Load(libPath.get(), libPath.Length(), platformAPI,
                        adapter)) {
#ifdef XP_WIN

    NS_WARNING(
        nsPrintfCString("Failed to load GMP with error(%lu).", GetLastError())
            .get());
#else
    NS_WARNING("Failed to load GMP");
#endif
    delete platformAPI;
    CrashReporter::RecordAnnotationNSCString(
        CrashReporter::Annotation::GMPLibraryPath,
        NS_ConvertUTF16toUTF8(mPluginPath));

    return IPC_FAIL(this"Failed to load GMP.");
  }

  return IPC_OK();
}

MessageLoop* GMPChild::GMPMessageLoop() { return mGMPMessageLoop; }

void GMPChild::ActorDestroy(ActorDestroyReason aWhy) {
  GMP_CHILD_LOG_DEBUG("%s reason=%d", __FUNCTION__, aWhy);

#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
  DestroySandboxProfiler();
#endif

  for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
    MOZ_ASSERT_IF(aWhy == NormalShutdown,
                  !mGMPContentChildren[i - 1]->IsUsed());
    mGMPContentChildren[i - 1]->Close();
  }

  if (mGMPLoader) {
    mGMPLoader->Shutdown();
  }

  ShutdownPlatformAPI();

  if (AbnormalShutdown == aWhy) {
    NS_WARNING("Abnormal shutdown of GMP process!");
    ProcessChild::QuickExit();
  }

  // Send the last bits of Glean data over to the main process.
  glean::FlushFOGData(
      [](ByteBuf&& aBuf) { glean::SendFOGData(std::move(aBuf)); });

  if (mProfilerController) {
    mProfilerController->Shutdown();
    mProfilerController = nullptr;
  }

  CrashReporterClient::DestroySingleton();

  XRE_ShutdownChildProcess();
}

void GMPChild::ProcessingError(Result aCode, const char* aReason) {
  switch (aCode) {
    case MsgDropped:
      _exit(0);  // Don't trigger a crash report.
    case MsgNotKnown:
      MOZ_CRASH("aborting because of MsgNotKnown");
    case MsgNotAllowed:
      MOZ_CRASH("aborting because of MsgNotAllowed");
    case MsgPayloadError:
      MOZ_CRASH("aborting because of MsgPayloadError");
    case MsgProcessingError:
      MOZ_CRASH("aborting because of MsgProcessingError");
    case MsgValueError:
      MOZ_CRASH("aborting because of MsgValueError");
    default:
      MOZ_CRASH("not reached");
  }
}

PGMPTimerChild* GMPChild::AllocPGMPTimerChild() {
  return new GMPTimerChild(this);
}

bool GMPChild::DeallocPGMPTimerChild(PGMPTimerChild* aActor) {
  MOZ_ASSERT(mTimerChild == static_cast<GMPTimerChild*>(aActor));
  mTimerChild = nullptr;
  return true;
}

GMPTimerChild* GMPChild::GetGMPTimers() {
  if (!mTimerChild) {
    PGMPTimerChild* sc = SendPGMPTimerConstructor();
    if (!sc) {
      return nullptr;
    }
    mTimerChild = static_cast<GMPTimerChild*>(sc);
  }
  return mTimerChild;
}

PGMPStorageChild* GMPChild::AllocPGMPStorageChild() {
  return new GMPStorageChild(this);
}

bool GMPChild::DeallocPGMPStorageChild(PGMPStorageChild* aActor) {
  mStorage = nullptr;
  return true;
}

GMPStorageChild* GMPChild::GetGMPStorage() {
  if (!mStorage) {
    PGMPStorageChild* sc = SendPGMPStorageConstructor();
    if (!sc) {
      return nullptr;
    }
    mStorage = static_cast<GMPStorageChild*>(sc);
  }
  return mStorage;
}

mozilla::ipc::IPCResult GMPChild::RecvCrashPluginNow() {
  MOZ_CRASH();
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvCloseActive() {
  for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
    mGMPContentChildren[i - 1]->CloseActive();
  }
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvInitGMPContentChild(
    Endpoint<PGMPContentChild>&& aEndpoint) {
  GMPContentChild* child =
      mGMPContentChildren.AppendElement(new GMPContentChild(this))->get();
  aEndpoint.Bind(child);
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvFlushFOGData(
    FlushFOGDataResolver&& aResolver) {
  GMP_CHILD_LOG_DEBUG("GMPChild RecvFlushFOGData");
  glean::FlushFOGData(std::move(aResolver));
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvTestTriggerMetrics(
    TestTriggerMetricsResolver&& aResolve) {
  GMP_CHILD_LOG_DEBUG("GMPChild RecvTestTriggerMetrics");
  mozilla::glean::test_only_ipc::a_counter.Add(
      nsIXULRuntime::PROCESS_TYPE_GMPLUGIN);
  aResolve(true);
  return IPC_OK();
}

void GMPChild::GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild) {
  for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
    RefPtr<GMPContentChild>& destroyedActor = mGMPContentChildren[i - 1];
    if (destroyedActor.get() == aGMPContentChild) {
      SendPGMPContentChildDestroyed();
      mGMPContentChildren.RemoveElementAt(i - 1);
      break;
    }
  }
}

mozilla::ipc::IPCResult GMPChild::RecvInitProfiler(
    Endpoint<PProfilerChild>&& aEndpoint) {
  mProfilerController =
      mozilla::ChildProfilerController::Create(std::move(aEndpoint));
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvPreferenceUpdate(const Pref& aPref) {
  Preferences::SetPreference(aPref);
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvShutdown(ShutdownResolver&& aResolver) {
  if (!mProfilerController) {
    aResolver(""_ns);
    return IPC_OK();
  }

  const bool isProfiling = profiler_is_active();
  CrashReporter::RecordAnnotationCString(
      CrashReporter::Annotation::ProfilerChildShutdownPhase,
      isProfiling ? "Profiling - GrabShutdownProfileAndShutdown"
                  : "Not profiling - GrabShutdownProfileAndShutdown");
  ProfileAndAdditionalInformation shutdownProfileAndAdditionalInformation =
      mProfilerController->GrabShutdownProfileAndShutdown();
  CrashReporter::RecordAnnotationCString(
      CrashReporter::Annotation::ProfilerChildShutdownPhase,
      isProfiling ? "Profiling - Destroying ChildProfilerController"
                  : "Not profiling - Destroying ChildProfilerController");
  mProfilerController = nullptr;
  CrashReporter::RecordAnnotationCString(
      CrashReporter::Annotation::ProfilerChildShutdownPhase,
      isProfiling ? "Profiling - SendShutdownProfile (resovling)"
                  : "Not profiling - SendShutdownProfile (resolving)");
  if (const size_t len = shutdownProfileAndAdditionalInformation.SizeOf();
      len >= size_t(IPC::Channel::kMaximumMessageSize)) {
    shutdownProfileAndAdditionalInformation.mProfile =
        nsPrintfCString("*Profile from pid %u bigger (%zu) than IPC max (%zu)",
                        unsigned(profiler_current_process_id().ToNumber()), len,
                        size_t(IPC::Channel::kMaximumMessageSize));
  }
  // Send the shutdown profile to the parent process through our own
  // message channel, which we know will survive for long enough.
  aResolver(shutdownProfileAndAdditionalInformation.mProfile);
  CrashReporter::RecordAnnotationCString(
      CrashReporter::Annotation::ProfilerChildShutdownPhase,
      isProfiling ? "Profiling - SendShutdownProfile (resolved)"
                  : "Not profiling - SendShutdownProfile (resolved)");
  return IPC_OK();
}

#if defined(XP_WIN)
mozilla::ipc::IPCResult GMPChild::RecvInitDllServices(
    const bool& aCanRecordReleaseTelemetry,
    const bool& aIsReadyForBackgroundProcessing) {
  if (aCanRecordReleaseTelemetry) {
    RefPtr<DllServices> dllSvc(DllServices::Get());
    dllSvc->StartUntrustedModulesProcessor(aIsReadyForBackgroundProcessing);
  }
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvGetUntrustedModulesData(
    GetUntrustedModulesDataResolver&& aResolver) {
  RefPtr<DllServices> dllSvc(DllServices::Get());
  dllSvc->GetUntrustedModulesData()->Then(
      GetMainThreadSerialEventTarget(), __func__,
      [aResolver](Maybe<UntrustedModulesData>&& aData) {
        aResolver(std::move(aData));
      },
      [aResolver](nsresult aReason) { aResolver(Nothing()); });
  return IPC_OK();
}

mozilla::ipc::IPCResult GMPChild::RecvUnblockUntrustedModulesThread() {
  if (nsCOMPtr<nsIObserverService> obs =
          mozilla::services::GetObserverService()) {
    obs->NotifyObservers(nullptr, "unblock-untrusted-modules-thread", nullptr);
  }
  return IPC_OK();
}
#endif  // defined(XP_WIN)

}  // namespace gmp
}  // namespace mozilla

#undef GMP_CHILD_LOG_DEBUG
#undef __CLASS__

Messung V0.5
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.