LCOV - code coverage report
Current view: top level - dom/media/gmp - GMPStorageChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 117 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "GMPStorageChild.h"
       7             : #include "GMPChild.h"
       8             : #include "gmp-storage.h"
       9             : #include "base/task.h"
      10             : 
      11             : #define ON_GMP_THREAD() (mPlugin->GMPMessageLoop() == MessageLoop::current())
      12             : 
      13             : #define CALL_ON_GMP_THREAD(_func, ...) \
      14             :   do { \
      15             :     if (ON_GMP_THREAD()) { \
      16             :       _func(__VA_ARGS__); \
      17             :     } else { \
      18             :       mPlugin->GMPMessageLoop()->PostTask( \
      19             :         dont_add_new_uses_of_this::NewRunnableMethod(this, &GMPStorageChild::_func, ##__VA_ARGS__) \
      20             :       ); \
      21             :     } \
      22             :   } while(false)
      23             : 
      24             : static nsTArray<uint8_t>
      25           0 : ToArray(const uint8_t* aData, uint32_t aDataSize)
      26             : {
      27           0 :   nsTArray<uint8_t> data;
      28           0 :   data.AppendElements(aData, aDataSize);
      29           0 :   return mozilla::Move(data);
      30             : }
      31             : 
      32             : namespace mozilla {
      33             : namespace gmp {
      34             : 
      35           0 : GMPRecordImpl::GMPRecordImpl(GMPStorageChild* aOwner,
      36             :                              const nsCString& aName,
      37           0 :                              GMPRecordClient* aClient)
      38             :   : mName(aName)
      39             :   , mClient(aClient)
      40           0 :   , mOwner(aOwner)
      41             : {
      42           0 : }
      43             : 
      44             : GMPErr
      45           0 : GMPRecordImpl::Open()
      46             : {
      47           0 :   return mOwner->Open(this);
      48             : }
      49             : 
      50             : void
      51           0 : GMPRecordImpl::OpenComplete(GMPErr aStatus)
      52             : {
      53           0 :   mClient->OpenComplete(aStatus);
      54           0 : }
      55             : 
      56             : GMPErr
      57           0 : GMPRecordImpl::Read()
      58             : {
      59           0 :   return mOwner->Read(this);
      60             : }
      61             : 
      62             : void
      63           0 : GMPRecordImpl::ReadComplete(GMPErr aStatus,
      64             :                             const uint8_t* aBytes,
      65             :                             uint32_t aLength)
      66             : {
      67           0 :   mClient->ReadComplete(aStatus, aBytes, aLength);
      68           0 : }
      69             : 
      70             : GMPErr
      71           0 : GMPRecordImpl::Write(const uint8_t* aData, uint32_t aDataSize)
      72             : {
      73           0 :   return mOwner->Write(this, aData, aDataSize);
      74             : }
      75             : 
      76             : void
      77           0 : GMPRecordImpl::WriteComplete(GMPErr aStatus)
      78             : {
      79           0 :   mClient->WriteComplete(aStatus);
      80           0 : }
      81             : 
      82             : GMPErr
      83           0 : GMPRecordImpl::Close()
      84             : {
      85           0 :   RefPtr<GMPRecordImpl> kungfuDeathGrip(this);
      86             :   // Delete our self reference.
      87           0 :   Release();
      88           0 :   mOwner->Close(this->Name());
      89           0 :   return GMPNoErr;
      90             : }
      91             : 
      92           0 : GMPStorageChild::GMPStorageChild(GMPChild* aPlugin)
      93             :   : mMonitor("GMPStorageChild")
      94             :   , mPlugin(aPlugin)
      95           0 :   , mShutdown(false)
      96             : {
      97           0 :   MOZ_ASSERT(ON_GMP_THREAD());
      98           0 : }
      99             : 
     100             : GMPErr
     101           0 : GMPStorageChild::CreateRecord(const nsCString& aRecordName,
     102             :                               GMPRecord** aOutRecord,
     103             :                               GMPRecordClient* aClient)
     104             : {
     105           0 :   MonitorAutoLock lock(mMonitor);
     106             : 
     107           0 :   if (mShutdown) {
     108           0 :     NS_WARNING("GMPStorage used after it's been shutdown!");
     109           0 :     return GMPClosedErr;
     110             :   }
     111             : 
     112           0 :   MOZ_ASSERT(aRecordName.Length() && aOutRecord);
     113             : 
     114           0 :   if (HasRecord(aRecordName)) {
     115           0 :     return GMPRecordInUse;
     116             :   }
     117             : 
     118           0 :   RefPtr<GMPRecordImpl> record(new GMPRecordImpl(this, aRecordName, aClient));
     119           0 :   mRecords.Put(aRecordName, record); // Addrefs
     120             : 
     121             :   // The GMPRecord holds a self reference until the GMP calls Close() on
     122             :   // it. This means the object is always valid (even if neutered) while
     123             :   // the GMP expects it to be.
     124           0 :   record.forget(aOutRecord);
     125             : 
     126           0 :   return GMPNoErr;
     127             : }
     128             : 
     129             : bool
     130           0 : GMPStorageChild::HasRecord(const nsCString& aRecordName)
     131             : {
     132           0 :   mMonitor.AssertCurrentThreadOwns();
     133           0 :   return mRecords.Contains(aRecordName);
     134             : }
     135             : 
     136             : already_AddRefed<GMPRecordImpl>
     137           0 : GMPStorageChild::GetRecord(const nsCString& aRecordName)
     138             : {
     139           0 :   MonitorAutoLock lock(mMonitor);
     140           0 :   RefPtr<GMPRecordImpl> record;
     141           0 :   mRecords.Get(aRecordName, getter_AddRefs(record));
     142           0 :   return record.forget();
     143             : }
     144             : 
     145             : GMPErr
     146           0 : GMPStorageChild::Open(GMPRecordImpl* aRecord)
     147             : {
     148           0 :   MonitorAutoLock lock(mMonitor);
     149             : 
     150           0 :   if (mShutdown) {
     151           0 :     NS_WARNING("GMPStorage used after it's been shutdown!");
     152           0 :     return GMPClosedErr;
     153             :   }
     154             : 
     155           0 :   if (!HasRecord(aRecord->Name())) {
     156             :     // Trying to re-open a record that has already been closed.
     157           0 :     return GMPClosedErr;
     158             :   }
     159             : 
     160           0 :   CALL_ON_GMP_THREAD(SendOpen, aRecord->Name());
     161             : 
     162           0 :   return GMPNoErr;
     163             : }
     164             : 
     165             : GMPErr
     166           0 : GMPStorageChild::Read(GMPRecordImpl* aRecord)
     167             : {
     168           0 :   MonitorAutoLock lock(mMonitor);
     169             : 
     170           0 :   if (mShutdown) {
     171           0 :     NS_WARNING("GMPStorage used after it's been shutdown!");
     172           0 :     return GMPClosedErr;
     173             :   }
     174             : 
     175           0 :   if (!HasRecord(aRecord->Name())) {
     176             :     // Record not opened.
     177           0 :     return GMPClosedErr;
     178             :   }
     179             : 
     180           0 :   CALL_ON_GMP_THREAD(SendRead, aRecord->Name());
     181             : 
     182           0 :   return GMPNoErr;
     183             : }
     184             : 
     185             : GMPErr
     186           0 : GMPStorageChild::Write(GMPRecordImpl* aRecord,
     187             :                        const uint8_t* aData,
     188             :                        uint32_t aDataSize)
     189             : {
     190           0 :   if (aDataSize > GMP_MAX_RECORD_SIZE) {
     191           0 :     return GMPQuotaExceededErr;
     192             :   }
     193             : 
     194           0 :   MonitorAutoLock lock(mMonitor);
     195             : 
     196           0 :   if (mShutdown) {
     197           0 :     NS_WARNING("GMPStorage used after it's been shutdown!");
     198           0 :     return GMPClosedErr;
     199             :   }
     200             : 
     201           0 :   if (!HasRecord(aRecord->Name())) {
     202             :     // Record not opened.
     203           0 :     return GMPClosedErr;
     204             :   }
     205             : 
     206           0 :   CALL_ON_GMP_THREAD(SendWrite, aRecord->Name(), ToArray(aData, aDataSize));
     207             : 
     208           0 :   return GMPNoErr;
     209             : }
     210             : 
     211             : GMPErr
     212           0 : GMPStorageChild::Close(const nsCString& aRecordName)
     213             : {
     214           0 :   MonitorAutoLock lock(mMonitor);
     215             : 
     216           0 :   if (!HasRecord(aRecordName)) {
     217             :     // Already closed.
     218           0 :     return GMPClosedErr;
     219             :   }
     220             : 
     221           0 :   mRecords.Remove(aRecordName);
     222             : 
     223           0 :   if (!mShutdown) {
     224           0 :     CALL_ON_GMP_THREAD(SendClose, aRecordName);
     225             :   }
     226             : 
     227           0 :   return GMPNoErr;
     228             : }
     229             : 
     230             : mozilla::ipc::IPCResult
     231           0 : GMPStorageChild::RecvOpenComplete(const nsCString& aRecordName,
     232             :                                   const GMPErr& aStatus)
     233             : {
     234             :   // We don't need a lock to read |mShutdown| since it is only changed in
     235             :   // the GMP thread.
     236           0 :   if (mShutdown) {
     237           0 :     return IPC_OK();
     238             :   }
     239           0 :   RefPtr<GMPRecordImpl> record = GetRecord(aRecordName);
     240           0 :   if (!record) {
     241             :     // Not fatal.
     242           0 :     return IPC_OK();
     243             :   }
     244           0 :   record->OpenComplete(aStatus);
     245           0 :   return IPC_OK();
     246             : }
     247             : 
     248             : mozilla::ipc::IPCResult
     249           0 : GMPStorageChild::RecvReadComplete(const nsCString& aRecordName,
     250             :                                   const GMPErr& aStatus,
     251             :                                   InfallibleTArray<uint8_t>&& aBytes)
     252             : {
     253           0 :   if (mShutdown) {
     254           0 :     return IPC_OK();
     255             :   }
     256           0 :   RefPtr<GMPRecordImpl> record = GetRecord(aRecordName);
     257           0 :   if (!record) {
     258             :     // Not fatal.
     259           0 :     return IPC_OK();
     260             :   }
     261           0 :   record->ReadComplete(aStatus, aBytes.Elements(), aBytes.Length());
     262           0 :   return IPC_OK();
     263             : }
     264             : 
     265             : mozilla::ipc::IPCResult
     266           0 : GMPStorageChild::RecvWriteComplete(const nsCString& aRecordName,
     267             :                                    const GMPErr& aStatus)
     268             : {
     269           0 :   if (mShutdown) {
     270           0 :     return IPC_OK();
     271             :   }
     272           0 :   RefPtr<GMPRecordImpl> record = GetRecord(aRecordName);
     273           0 :   if (!record) {
     274             :     // Not fatal.
     275           0 :     return IPC_OK();
     276             :   }
     277           0 :   record->WriteComplete(aStatus);
     278           0 :   return IPC_OK();
     279             : }
     280             : 
     281             : mozilla::ipc::IPCResult
     282           0 : GMPStorageChild::RecvShutdown()
     283             : {
     284             :   // Block any new storage requests, and thus any messages back to the
     285             :   // parent. We don't delete any objects here, as that may invalidate
     286             :   // GMPRecord pointers held by the GMP.
     287           0 :   MonitorAutoLock lock(mMonitor);
     288           0 :   mShutdown = true;
     289           0 :   return IPC_OK();
     290             : }
     291             : 
     292             : } // namespace gmp
     293             : } // namespace mozilla
     294             : 
     295             : // avoid redefined macro in unified build
     296             : #undef ON_GMP_THREAD
     297             : #undef CALL_ON_GMP_THREAD

Generated by: LCOV version 1.13