tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GMPStorageParent.cpp (5910B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "GMPStorageParent.h"
      7 
      8 #include "GMPParent.h"
      9 #include "gmp-storage.h"
     10 
     11 namespace mozilla {
     12 
     13 #ifdef LOG
     14 #  undef LOG
     15 #endif
     16 
     17 extern LogModule* GetGMPLog();
     18 
     19 #define LOGD(msg) MOZ_LOG(GetGMPLog(), mozilla::LogLevel::Debug, msg)
     20 #define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
     21 
     22 namespace gmp {
     23 
     24 GMPStorageParent::GMPStorageParent(const nsACString& aNodeId,
     25                                   GMPParent* aPlugin)
     26    : mNodeId(aNodeId), mPlugin(aPlugin), mShutdown(true) {}
     27 
     28 nsresult GMPStorageParent::Init() {
     29  LOGD(("GMPStorageParent[%p]::Init()", this));
     30 
     31  if (NS_WARN_IF(mNodeId.IsEmpty())) {
     32    return NS_ERROR_FAILURE;
     33  }
     34  RefPtr<GeckoMediaPluginServiceParent> mps(
     35      GeckoMediaPluginServiceParent::GetSingleton());
     36  if (NS_WARN_IF(!mps)) {
     37    return NS_ERROR_FAILURE;
     38  }
     39 
     40  bool persistent = false;
     41  if (NS_WARN_IF(
     42          NS_FAILED(mps->IsPersistentStorageAllowed(mNodeId, &persistent)))) {
     43    return NS_ERROR_FAILURE;
     44  }
     45  if (persistent) {
     46    mStorage = CreateGMPDiskStorage(mNodeId, mPlugin->GetPluginBaseName());
     47  } else {
     48    mStorage = mps->GetMemoryStorageFor(mNodeId, mPlugin->GetPluginBaseName());
     49  }
     50  if (!mStorage) {
     51    return NS_ERROR_FAILURE;
     52  }
     53 
     54  LOGD(("GMPStorageParent[%p]::Init succeeded, nodeId=%s, persistent=%d", this,
     55        mNodeId.BeginReading(), persistent));
     56  mShutdown = false;
     57  return NS_OK;
     58 }
     59 
     60 mozilla::ipc::IPCResult GMPStorageParent::RecvOpen(
     61    const nsACString& aRecordName) {
     62  LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s')", this,
     63        PromiseFlatCString(aRecordName).get()));
     64 
     65  if (mShutdown) {
     66    // Shutdown is an expected state, so we do not IPC_FAIL.
     67    return IPC_OK();
     68  }
     69 
     70  if (mNodeId.EqualsLiteral("null")) {
     71    // Refuse to open storage if the page is opened from local disk,
     72    // or shared across origin.
     73    LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') failed; null nodeId",
     74          this, PromiseFlatCString(aRecordName).get()));
     75    (void)SendOpenComplete(aRecordName, GMPGenericErr);
     76    return IPC_OK();
     77  }
     78 
     79  if (aRecordName.IsEmpty()) {
     80    LOGD((
     81        "GMPStorageParent[%p]::RecvOpen(record='%s') failed; record name empty",
     82        this, PromiseFlatCString(aRecordName).get()));
     83    (void)SendOpenComplete(aRecordName, GMPGenericErr);
     84    return IPC_OK();
     85  }
     86 
     87  if (mStorage->IsOpen(aRecordName)) {
     88    LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') failed; record in use",
     89          this, PromiseFlatCString(aRecordName).get()));
     90    (void)SendOpenComplete(aRecordName, GMPRecordInUse);
     91    return IPC_OK();
     92  }
     93 
     94  auto err = mStorage->Open(aRecordName);
     95  MOZ_ASSERT(GMP_FAILED(err) || mStorage->IsOpen(aRecordName));
     96  LOGD(("GMPStorageParent[%p]::RecvOpen(record='%s') complete; rv=%d", this,
     97        PromiseFlatCString(aRecordName).get(), err));
     98  (void)SendOpenComplete(aRecordName, err);
     99 
    100  return IPC_OK();
    101 }
    102 
    103 mozilla::ipc::IPCResult GMPStorageParent::RecvRead(
    104    const nsACString& aRecordName) {
    105  LOGD(("GMPStorageParent[%p]::RecvRead(record='%s')", this,
    106        PromiseFlatCString(aRecordName).get()));
    107 
    108  if (mShutdown) {
    109    // Shutdown is an expected state, so we do not IPC_FAIL.
    110    return IPC_OK();
    111  }
    112 
    113  nsTArray<uint8_t> data;
    114  if (!mStorage->IsOpen(aRecordName)) {
    115    LOGD(("GMPStorageParent[%p]::RecvRead(record='%s') failed; record not open",
    116          this, PromiseFlatCString(aRecordName).get()));
    117    (void)SendReadComplete(aRecordName, GMPClosedErr, data);
    118  } else {
    119    GMPErr rv = mStorage->Read(aRecordName, data);
    120    LOGD(
    121        ("GMPStorageParent[%p]::RecvRead(record='%s') read %zu bytes "
    122         "rv=%" PRIu32,
    123         this, PromiseFlatCString(aRecordName).get(), data.Length(),
    124         static_cast<uint32_t>(rv)));
    125    (void)SendReadComplete(aRecordName, rv, data);
    126  }
    127 
    128  return IPC_OK();
    129 }
    130 
    131 mozilla::ipc::IPCResult GMPStorageParent::RecvWrite(
    132    const nsACString& aRecordName, nsTArray<uint8_t>&& aBytes) {
    133  LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') %zu bytes", this,
    134        PromiseFlatCString(aRecordName).get(), aBytes.Length()));
    135 
    136  if (mShutdown) {
    137    // Shutdown is an expected state, so we do not IPC_FAIL.
    138    return IPC_OK();
    139  }
    140 
    141  if (!mStorage->IsOpen(aRecordName)) {
    142    LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') failed record not open",
    143          this, PromiseFlatCString(aRecordName).get()));
    144    (void)SendWriteComplete(aRecordName, GMPClosedErr);
    145    return IPC_OK();
    146  }
    147 
    148  if (aBytes.Length() > GMP_MAX_RECORD_SIZE) {
    149    LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') failed record too big",
    150          this, PromiseFlatCString(aRecordName).get()));
    151    (void)SendWriteComplete(aRecordName, GMPQuotaExceededErr);
    152    return IPC_OK();
    153  }
    154 
    155  GMPErr rv = mStorage->Write(aRecordName, aBytes);
    156  LOGD(("GMPStorageParent[%p]::RecvWrite(record='%s') write complete rv=%d",
    157        this, PromiseFlatCString(aRecordName).get(), rv));
    158 
    159  (void)SendWriteComplete(aRecordName, rv);
    160 
    161  return IPC_OK();
    162 }
    163 
    164 mozilla::ipc::IPCResult GMPStorageParent::RecvClose(
    165    const nsACString& aRecordName) {
    166  LOGD(("GMPStorageParent[%p]::RecvClose(record='%s')", this,
    167        PromiseFlatCString(aRecordName).get()));
    168 
    169  if (mShutdown) {
    170    return IPC_OK();
    171  }
    172 
    173  mStorage->Close(aRecordName);
    174 
    175  return IPC_OK();
    176 }
    177 
    178 void GMPStorageParent::ActorDestroy(ActorDestroyReason aWhy) {
    179  LOGD(("GMPStorageParent[%p]::ActorDestroy(reason=%d)", this, aWhy));
    180  Shutdown();
    181 }
    182 
    183 void GMPStorageParent::Shutdown() {
    184  if (mShutdown) {
    185    return;
    186  }
    187 
    188  LOGD(("GMPStorageParent[%p]::Shutdown()", this));
    189  mShutdown = true;
    190  (void)SendShutdown();
    191 
    192  mStorage = nullptr;
    193 }
    194 
    195 }  // namespace gmp
    196 }  // namespace mozilla