Home | History | Annotate | Download | only in nacl_host
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_
      6 #define CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_
      7 
      8 #include <map>
      9 
     10 #include "base/callback_forward.h"
     11 #include "base/memory/singleton.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "base/threading/thread_checker.h"
     14 #include "chrome/browser/nacl_host/nacl_file_host.h"
     15 #include "components/nacl/common/pnacl_types.h"
     16 #include "ipc/ipc_platform_file.h"
     17 
     18 namespace net {
     19 class DrainableIOBuffer;
     20 }
     21 
     22 namespace pnacl {
     23 class PnaclHostTest;
     24 class PnaclTranslationCache;
     25 }
     26 
     27 // Shared state (translation cache) and common utilities (temp file creation)
     28 // for all PNaCl translations. Unless otherwise specified, all methods should be
     29 // called on the IO thread.
     30 class PnaclHost {
     31  public:
     32   typedef base::Callback<void(base::PlatformFile)> TempFileCallback;
     33   typedef base::Callback<void(base::PlatformFile, bool is_hit)> NexeFdCallback;
     34 
     35   static PnaclHost* GetInstance();
     36 
     37   PnaclHost();
     38   ~PnaclHost();
     39 
     40   // Initialize cache backend. GetNexeFd will also initialize the backend if
     41   // necessary, but calling Init ahead of time will minimize the latency.
     42   void Init();
     43 
     44   // Creates a temporary file that will be deleted when the last handle
     45   // is closed, or earlier. Returns a PlatformFile handle.
     46   void CreateTemporaryFile(TempFileCallback cb);
     47 
     48   // Create a temporary file, which will be deleted by the time the last
     49   // handle is closed (or earlier on POSIX systems), to use for the nexe
     50   // with the cache information given in |cache_info|. The specific instance
     51   // is identified by the combination of |render_process_id| and |pp_instance|.
     52   // Returns by calling |cb| with a PlatformFile handle.
     53   // If the nexe is already present
     54   // in the cache, |is_hit| is set to true and the contents of the nexe
     55   // have been copied into the temporary file. Otherwise |is_hit| is set to
     56   // false and the temporary file will be writeable.
     57   // Currently the implementation is a stub, which always sets is_hit to false
     58   // and calls the implementation of CreateTemporaryFile.
     59   // If the cache request was a miss, the caller is expected to call
     60   // TranslationFinished after it finishes translation to allow the nexe to be
     61   // stored in the cache.
     62   // The returned temp fd may be closed at any time by PnaclHost, so it should
     63   // be duplicated (e.g. with IPC::GetFileHandleForProcess) before the callback
     64   // returns.
     65   // If |is_incognito| is true, the nexe will not be stored
     66   // in the cache, but the renderer is still expected to call
     67   // TranslationFinished.
     68   void GetNexeFd(int render_process_id,
     69                  int render_view_id,
     70                  int pp_instance,
     71                  bool is_incognito,
     72                  const nacl::PnaclCacheInfo& cache_info,
     73                  const NexeFdCallback& cb);
     74 
     75   // Called after the translation of a pexe instance identified by
     76   // |render_process_id| and |pp_instance| finishes. If |success| is true,
     77   // store the nexe translated for the instance in the cache.
     78   void TranslationFinished(int render_process_id,
     79                            int pp_instance,
     80                            bool success);
     81 
     82   // Called when the renderer identified by |render_process_id| is closing.
     83   // Clean up any outstanding translations for that renderer. If there are no
     84   // more pending translations, the backend is freed, allowing it to flush.
     85   void RendererClosing(int render_process_id);
     86 
     87   // Doom all entries between |initial_time| and |end_time|. Like disk_cache_,
     88   // PnaclHost supports supports unbounded deletes in either direction by using
     89   // null Time values for either argument. |callback| will be called on the UI
     90   // thread when finished.
     91   void ClearTranslationCacheEntriesBetween(base::Time initial_time,
     92                                            base::Time end_time,
     93                                            const base::Closure& callback);
     94 
     95   // Return the number of tracked translations or FD requests currently pending.
     96   size_t pending_translations() { return pending_translations_.size(); }
     97 
     98  private:
     99   // PnaclHost is a singleton because there is only one translation cache, and
    100   // so that the BrowsingDataRemover can clear it even if no translation has
    101   // ever been started.
    102   friend struct DefaultSingletonTraits<PnaclHost>;
    103   friend class pnacl::PnaclHostTest;
    104   enum CacheState {
    105     CacheUninitialized,
    106     CacheInitializing,
    107     CacheReady
    108   };
    109   class PendingTranslation {
    110    public:
    111     PendingTranslation();
    112     ~PendingTranslation();
    113     base::ProcessHandle process_handle;
    114     int render_view_id;
    115     base::PlatformFile nexe_fd;
    116     bool got_nexe_fd;
    117     bool got_cache_reply;
    118     bool got_cache_hit;
    119     bool is_incognito;
    120     scoped_refptr<net::DrainableIOBuffer> nexe_read_buffer;
    121     NexeFdCallback callback;
    122     std::string cache_key;
    123     nacl::PnaclCacheInfo cache_info;
    124   };
    125 
    126   typedef std::pair<int, int> TranslationID;
    127   typedef std::map<TranslationID, PendingTranslation> PendingTranslationMap;
    128 
    129   void InitForTest(base::FilePath temp_dir);
    130   void OnCacheInitialized(int net_error);
    131 
    132   static base::PlatformFile DoCreateTemporaryFile(base::FilePath temp_dir_);
    133 
    134   // GetNexeFd common steps
    135   void SendCacheQueryAndTempFileRequest(const std::string& key,
    136                                         const TranslationID& id);
    137   void OnCacheQueryReturn(const TranslationID& id,
    138                           int net_error,
    139                           scoped_refptr<net::DrainableIOBuffer> buffer);
    140   void OnTempFileReturn(const TranslationID& id, base::PlatformFile fd);
    141   void CheckCacheQueryReady(const PendingTranslationMap::iterator& entry);
    142 
    143   // GetNexeFd miss path
    144   void ReturnMiss(const PendingTranslationMap::iterator& entry);
    145   static scoped_refptr<net::DrainableIOBuffer> CopyFileToBuffer(
    146       base::PlatformFile fd);
    147   void StoreTranslatedNexe(TranslationID id,
    148                            scoped_refptr<net::DrainableIOBuffer>);
    149   void OnTranslatedNexeStored(const TranslationID& id, int net_error);
    150   void RequeryMatchingTranslations(const std::string& key);
    151 
    152   // GetNexeFd hit path
    153   static int CopyBufferToFile(base::PlatformFile fd,
    154                               scoped_refptr<net::DrainableIOBuffer> buffer);
    155   void OnBufferCopiedToTempFile(const TranslationID& id, int file_error);
    156 
    157   static void OnEntriesDoomed(const base::Closure& callback, int net_error);
    158 
    159   CacheState cache_state_;
    160   base::FilePath temp_dir_;
    161   scoped_ptr<pnacl::PnaclTranslationCache> disk_cache_;
    162   PendingTranslationMap pending_translations_;
    163   base::ThreadChecker thread_checker_;
    164   base::WeakPtrFactory<PnaclHost> weak_factory_;
    165   DISALLOW_COPY_AND_ASSIGN(PnaclHost);
    166 };
    167 
    168 #endif  // CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_
    169