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