author Ryan VanderMeulen <>
Wed, 29 Jul 2015 10:04:25 -0400
changeset 222182 d1ed7de67f5a16325716cbfa3ca79dbe6284049f
parent 215070 11664677d35ec9c4606dec917f8f0425a3907319
permissions -rw-r--r--
Added tag B2G_2_1_END for changeset 41e10c6740be on a CLOSED TREE

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* 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 */

#ifndef _RemoteOpenFileChild_h
#define _RemoteOpenFileChild_h

#include "mozilla/Attributes.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/net/PRemoteOpenFileChild.h"
#include "nsICachedFileDescriptorListener.h"
#include "nsILocalFile.h"
#include "nsIRemoteOpenFileListener.h"

class nsILoadContext;

namespace mozilla {

namespace ipc {
class FileDescriptor;

namespace net {

 * RemoteOpenFileChild: a thin wrapper around regular nsIFile classes that does
 * IPC to open a file handle on parent instead of child.  Used when we can't
 * open file handle on child (don't have permission), but we don't want the
 * overhead of shipping all I/O traffic across IPDL.  Example: JAR files.
 * To open a file handle with this class, AsyncRemoteFileOpen() must be called
 * first.  After the listener's OnRemoteFileOpenComplete() is called, if the
 * result is NS_OK, nsIFile.OpenNSPRFileDesc() may be called to get a
 * duplicated file descriptor.
 * Note that the file descriptor returned by NSPRFileDesc() is duplicated from
 * the original, which shares its file offset with the original.  If the file
 * offset is modified (ex: by lseek/read/write) on one of the shared
 * descriptors, the offset is also changed for the other.   It can be safely
 * used only with operations that take absolute offsets, such as
 * mmap/pread/pwrite.
 * This class should only be instantiated in a child process.
class RemoteOpenFileChild MOZ_FINAL
  : public PRemoteOpenFileChild
  , public nsIFile
  , public nsIHashable
  , public nsICachedFileDescriptorListener
  typedef mozilla::dom::TabChild TabChild;
  typedef mozilla::ipc::FileDescriptor FileDescriptor;

  virtual ~RemoteOpenFileChild();

    : mNSPRFileDesc(nullptr)
    , mAsyncOpenCalled(false)
    , mNSPROpenCalled(false)


  // aRemoteOpenUri must be scheme 'remoteopenfile://': otherwise looks like
  // a file:// uri.
  nsresult Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri);

  // Send message to parent to tell it to open file handle for file.
  // TabChild is required, for IPC security.
  // Note: currently only PR_RDONLY is supported for 'flags'
  nsresult AsyncRemoteFileOpen(int32_t aFlags,
                               nsIRemoteOpenFileListener* aListener,
                               nsITabChild* aTabChild,
                               nsILoadContext *aLoadContext);

  nsresult SetNSPRFileDesc(PRFileDesc* aNSPRFileDesc);

  void ReleaseIPDLReference()

  RemoteOpenFileChild(const RemoteOpenFileChild& other);

  void AddIPDLReference()

  virtual bool Recv__delete__(const FileDescriptor&) MOZ_OVERRIDE;

  virtual void OnCachedFileDescriptor(const nsAString& aPath,
                                      const FileDescriptor& aFD) MOZ_OVERRIDE;

  void HandleFileDescriptorAndNotifyListener(const FileDescriptor&,
                                             bool aFromRecvDelete);

  void NotifyListener(nsresult aResult);

  // regular nsIFile object, that we forward most calls to.
  nsCOMPtr<nsIFile> mFile;
  nsCOMPtr<nsIURI> mURI;
  nsCOMPtr<nsIURI> mAppURI;
  nsCOMPtr<nsIRemoteOpenFileListener> mListener;
  nsRefPtr<TabChild> mTabChild;
  PRFileDesc* mNSPRFileDesc;
  bool mAsyncOpenCalled;
  bool mNSPROpenCalled;

} // namespace net
} // namespace mozilla

#endif // _RemoteOpenFileChild_h