bool ParamTraits<MagicGrallocBufferHandle>::Read(const Message* aMsg, void** aIter, paramType* aResult) { size_t nbytes; size_t nfds; const char* data; if (!aMsg->ReadSize(aIter, &nbytes) || !aMsg->ReadSize(aIter, &nfds) || !aMsg->ReadBytes(aIter, &data, nbytes)) { return false; } int fds[nfds]; for (size_t n = 0; n < nfds; ++n) { FileDescriptor fd; if (!aMsg->ReadFileDescriptor(aIter, &fd)) { return false; } // If the GraphicBuffer was shared cross-process, SCM_RIGHTS does // the right thing and dup's the fd. If it's shared cross-thread, // SCM_RIGHTS doesn't dup the fd. That's surprising, but we just // deal with it here. NB: only the "default" (master) process can // alloc gralloc buffers. bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default); int dupFd = sameProcess ? dup(fd.fd) : fd.fd; fds[n] = dupFd; } sp<GraphicBuffer> buffer(new GraphicBuffer()); #if ANDROID_VERSION >= 19 // Make a copy of "data" and "fds" for unflatten() to avoid casting problem void const *pdata = (void const *)data; int const *pfds = fds; if (NO_ERROR == buffer->unflatten(pdata, nbytes, pfds, nfds)) { #else Flattenable *flattenable = buffer.get(); if (NO_ERROR == flattenable->unflatten(data, nbytes, fds, nfds)) { #endif aResult->mGraphicBuffer = buffer; return true; } return false; } } // namespace IPC
bool ParamTraits<MagicGrallocBufferHandle>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { MOZ_ASSERT(!aResult->mGraphicBuffer.get()); MOZ_ASSERT(aResult->mRef.mOwner == 0); MOZ_ASSERT(aResult->mRef.mKey == -1); size_t nbytes; int owner; int64_t index; if (!aMsg->ReadInt(aIter, &owner) || !aMsg->ReadInt64(aIter, &index) || !aMsg->ReadSize(aIter, &nbytes)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read a message\n"); return false; } auto data = mozilla::MakeUnique<char[]>(nbytes); if (!aMsg->ReadBytesInto(aIter, data.get(), nbytes)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read a message\n"); return false; } size_t nfds = aMsg->num_fds(); int fds[nfds]; for (size_t n = 0; n < nfds; ++n) { FileDescriptor fd; if (!aMsg->ReadFileDescriptor(aIter, &fd)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read file descriptors\n"); return false; } // If the GraphicBuffer was shared cross-process, SCM_RIGHTS does // the right thing and dup's the fd. If it's shared cross-thread, // SCM_RIGHTS doesn't dup the fd. // But in shared cross-thread, dup fd is not necessary because we get // a pointer to the GraphicBuffer directly from SharedBufferManagerParent // and don't create a new GraphicBuffer around the fd. fds[n] = fd.fd; } aResult->mRef.mOwner = owner; aResult->mRef.mKey = index; if (XRE_IsParentProcess()) { // If we are in chrome process, we can just get GraphicBuffer directly from // SharedBufferManagerParent. aResult->mGraphicBuffer = SharedBufferManagerParent::GetGraphicBuffer(aResult->mRef); } else { // Deserialize GraphicBuffer #if ANDROID_VERSION >= 19 sp<GraphicBuffer> buffer(new GraphicBuffer()); const void* datap = (const void*)data.get(); const int* fdsp = &fds[0]; if (NO_ERROR != buffer->unflatten(datap, nbytes, fdsp, nfds)) { buffer = nullptr; } #else sp<GraphicBuffer> buffer(new GraphicBuffer()); Flattenable *flattenable = buffer.get(); if (NO_ERROR != flattenable->unflatten(data.get(), nbytes, fds, nfds)) { buffer = nullptr; } #endif if (buffer.get()) { aResult->mGraphicBuffer = buffer; } } if (!aResult->mGraphicBuffer.get()) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to get gralloc buffer\n"); return false; } return true; }
bool ParamTraits<MagicGrallocBufferHandle>::Read(const Message* aMsg, void** aIter, paramType* aResult) { size_t nbytes; size_t nfds; const char* data; int owner; int64_t index; if (!aMsg->ReadInt(aIter, &owner) || !aMsg->ReadInt64(aIter, &index) || !aMsg->ReadSize(aIter, &nbytes) || !aMsg->ReadSize(aIter, &nfds) || !aMsg->ReadBytes(aIter, &data, nbytes)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read a message\n"); return false; } int fds[nfds]; bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default); for (size_t n = 0; n < nfds; ++n) { FileDescriptor fd; if (!aMsg->ReadFileDescriptor(aIter, &fd)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read file descriptors\n"); return false; } // If the GraphicBuffer was shared cross-process, SCM_RIGHTS does // the right thing and dup's the fd. If it's shared cross-thread, // SCM_RIGHTS doesn't dup the fd. // But in shared cross-thread, dup fd is not necessary because we get // a pointer to the GraphicBuffer directly from SharedBufferManagerParent // and don't create a new GraphicBuffer around the fd. fds[n] = fd.fd; } aResult->mRef.mOwner = owner; aResult->mRef.mKey = index; if (sameProcess) { aResult->mGraphicBuffer = SharedBufferManagerParent::GetGraphicBuffer(aResult->mRef); } else { aResult->mGraphicBuffer = SharedBufferManagerChild::GetSingleton()->GetGraphicBuffer(index); MOZ_ASSERT(!aResult->mGraphicBuffer.get()); // Deserialize GraphicBuffer #if ANDROID_VERSION >= 19 sp<GraphicBuffer> buffer(new GraphicBuffer()); const void* datap = (const void*)data; const int* fdsp = &fds[0]; if (NO_ERROR != buffer->unflatten(datap, nbytes, fdsp, nfds)) { buffer = nullptr; } #else sp<GraphicBuffer> buffer(new GraphicBuffer()); Flattenable *flattenable = buffer.get(); if (NO_ERROR != flattenable->unflatten(data, nbytes, fds, nfds)) { buffer = nullptr; } #endif if(buffer.get() && !aResult->mGraphicBuffer.get()) { aResult->mGraphicBuffer = buffer; } } if (!aResult->mGraphicBuffer.get()) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to get gralloc buffer\n"); return false; } return true; }