| OLD | NEW |
| (Empty) |
| 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 static bool TranslationMayBeCached( | |
| 129 const PendingTranslationMap::iterator& entry); | |
| 130 | |
| 131 void InitForTest(base::FilePath temp_dir); | |
| 132 void OnCacheInitialized(int net_error); | |
| 133 | |
| 134 static void DoCreateTemporaryFile(base::FilePath temp_dir_, | |
| 135 TempFileCallback cb); | |
| 136 | |
| 137 // GetNexeFd common steps | |
| 138 void SendCacheQueryAndTempFileRequest(const std::string& key, | |
| 139 const TranslationID& id); | |
| 140 void OnCacheQueryReturn(const TranslationID& id, | |
| 141 int net_error, | |
| 142 scoped_refptr<net::DrainableIOBuffer> buffer); | |
| 143 void OnTempFileReturn(const TranslationID& id, base::PlatformFile fd); | |
| 144 void CheckCacheQueryReady(const PendingTranslationMap::iterator& entry); | |
| 145 | |
| 146 // GetNexeFd miss path | |
| 147 void ReturnMiss(const PendingTranslationMap::iterator& entry); | |
| 148 static scoped_refptr<net::DrainableIOBuffer> CopyFileToBuffer( | |
| 149 base::PlatformFile fd); | |
| 150 void StoreTranslatedNexe(TranslationID id, | |
| 151 scoped_refptr<net::DrainableIOBuffer>); | |
| 152 void OnTranslatedNexeStored(const TranslationID& id, int net_error); | |
| 153 void RequeryMatchingTranslations(const std::string& key); | |
| 154 | |
| 155 // GetNexeFd hit path | |
| 156 static int CopyBufferToFile(base::PlatformFile fd, | |
| 157 scoped_refptr<net::DrainableIOBuffer> buffer); | |
| 158 void OnBufferCopiedToTempFile(const TranslationID& id, int file_error); | |
| 159 | |
| 160 void OnEntriesDoomed(const base::Closure& callback, int net_error); | |
| 161 | |
| 162 void DeInitIfSafe(); | |
| 163 | |
| 164 // Operations which are pending with the cache backend, which we should | |
| 165 // wait for before destroying it (see comment on DeInitIfSafe). | |
| 166 int pending_backend_operations_; | |
| 167 CacheState cache_state_; | |
| 168 base::FilePath temp_dir_; | |
| 169 scoped_ptr<pnacl::PnaclTranslationCache> disk_cache_; | |
| 170 PendingTranslationMap pending_translations_; | |
| 171 base::ThreadChecker thread_checker_; | |
| 172 base::WeakPtrFactory<PnaclHost> weak_factory_; | |
| 173 DISALLOW_COPY_AND_ASSIGN(PnaclHost); | |
| 174 }; | |
| 175 | |
| 176 #endif // CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_ | |
| OLD | NEW |