xref: /aosp_15_r20/external/cronet/components/nacl/browser/pnacl_host.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef COMPONENTS_NACL_BROWSER_PNACL_HOST_H_
6*6777b538SAndroid Build Coastguard Worker #define COMPONENTS_NACL_BROWSER_PNACL_HOST_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <map>
11*6777b538SAndroid Build Coastguard Worker #include <memory>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_checker.h"
19*6777b538SAndroid Build Coastguard Worker #include "components/nacl/browser/nacl_file_host.h"
20*6777b538SAndroid Build Coastguard Worker #include "components/nacl/common/pnacl_types.h"
21*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_platform_file.h"
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker namespace net {
24*6777b538SAndroid Build Coastguard Worker class DrainableIOBuffer;
25*6777b538SAndroid Build Coastguard Worker }
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker namespace pnacl {
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker class PnaclHostTest;
30*6777b538SAndroid Build Coastguard Worker class PnaclHostTestDisk;
31*6777b538SAndroid Build Coastguard Worker class PnaclTranslationCache;
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker // Shared state (translation cache) and common utilities (temp file creation)
34*6777b538SAndroid Build Coastguard Worker // for all PNaCl translations. Unless otherwise specified, all methods should be
35*6777b538SAndroid Build Coastguard Worker // called on the IO thread.
36*6777b538SAndroid Build Coastguard Worker class PnaclHost {
37*6777b538SAndroid Build Coastguard Worker  public:
38*6777b538SAndroid Build Coastguard Worker   typedef base::RepeatingCallback<void(base::File)> TempFileCallback;
39*6777b538SAndroid Build Coastguard Worker   typedef base::RepeatingCallback<void(const base::File&, bool is_hit)>
40*6777b538SAndroid Build Coastguard Worker       NexeFdCallback;
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker   // Gets the PnaclHost singleton instance (creating it if necessary).
43*6777b538SAndroid Build Coastguard Worker   // PnaclHost is a singleton because there is only one translation cache, and
44*6777b538SAndroid Build Coastguard Worker   // so that the BrowsingDataRemover can clear it even if no translation has
45*6777b538SAndroid Build Coastguard Worker   // ever been started.
46*6777b538SAndroid Build Coastguard Worker   static PnaclHost* GetInstance();
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   PnaclHost(const PnaclHost&) = delete;
49*6777b538SAndroid Build Coastguard Worker   PnaclHost& operator=(const PnaclHost&) = delete;
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   // The PnaclHost instance is intentionally leaked on shutdown. DeInitIfSafe()
52*6777b538SAndroid Build Coastguard Worker   // attempts to cleanup |disk_cache_| earlier, but if it fails to do so in
53*6777b538SAndroid Build Coastguard Worker   // time, it will be too late when AtExitManager kicks in anway so subscribing
54*6777b538SAndroid Build Coastguard Worker   // to it is useless.
55*6777b538SAndroid Build Coastguard Worker   ~PnaclHost() = delete;
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker   // Initialize cache backend. GetNexeFd will also initialize the backend if
58*6777b538SAndroid Build Coastguard Worker   // necessary, but calling Init ahead of time will minimize the latency.
59*6777b538SAndroid Build Coastguard Worker   void Init();
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   // Creates a temporary file that will be deleted when the last handle
62*6777b538SAndroid Build Coastguard Worker   // is closed, or earlier. Returns a PlatformFile handle.
63*6777b538SAndroid Build Coastguard Worker   void CreateTemporaryFile(TempFileCallback cb);
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   // Create a temporary file, which will be deleted by the time the last
66*6777b538SAndroid Build Coastguard Worker   // handle is closed (or earlier on POSIX systems), to use for the nexe
67*6777b538SAndroid Build Coastguard Worker   // with the cache information given in |cache_info|. The specific instance
68*6777b538SAndroid Build Coastguard Worker   // is identified by the combination of |render_process_id| and |pp_instance|.
69*6777b538SAndroid Build Coastguard Worker   // Returns by calling |cb| with a PlatformFile handle.
70*6777b538SAndroid Build Coastguard Worker   // If the nexe is already present
71*6777b538SAndroid Build Coastguard Worker   // in the cache, |is_hit| is set to true and the contents of the nexe
72*6777b538SAndroid Build Coastguard Worker   // have been copied into the temporary file. Otherwise |is_hit| is set to
73*6777b538SAndroid Build Coastguard Worker   // false and the temporary file will be writeable.
74*6777b538SAndroid Build Coastguard Worker   // Currently the implementation is a stub, which always sets is_hit to false
75*6777b538SAndroid Build Coastguard Worker   // and calls the implementation of CreateTemporaryFile.
76*6777b538SAndroid Build Coastguard Worker   // If the cache request was a miss, the caller is expected to call
77*6777b538SAndroid Build Coastguard Worker   // TranslationFinished after it finishes translation to allow the nexe to be
78*6777b538SAndroid Build Coastguard Worker   // stored in the cache.
79*6777b538SAndroid Build Coastguard Worker   // The returned temp fd may be closed at any time by PnaclHost, so it should
80*6777b538SAndroid Build Coastguard Worker   // be duplicated (e.g. with IPC::GetPlatformFileForTransit) before the
81*6777b538SAndroid Build Coastguard Worker   // callback returns.
82*6777b538SAndroid Build Coastguard Worker   // If |is_incognito| is true, the nexe will not be stored
83*6777b538SAndroid Build Coastguard Worker   // in the cache, but the renderer is still expected to call
84*6777b538SAndroid Build Coastguard Worker   // TranslationFinished.
85*6777b538SAndroid Build Coastguard Worker   void GetNexeFd(int render_process_id,
86*6777b538SAndroid Build Coastguard Worker                  int pp_instance,
87*6777b538SAndroid Build Coastguard Worker                  bool is_incognito,
88*6777b538SAndroid Build Coastguard Worker                  const nacl::PnaclCacheInfo& cache_info,
89*6777b538SAndroid Build Coastguard Worker                  const NexeFdCallback& cb);
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   // Called after the translation of a pexe instance identified by
92*6777b538SAndroid Build Coastguard Worker   // |render_process_id| and |pp_instance| finishes. If |success| is true,
93*6777b538SAndroid Build Coastguard Worker   // store the nexe translated for the instance in the cache.
94*6777b538SAndroid Build Coastguard Worker   void TranslationFinished(int render_process_id,
95*6777b538SAndroid Build Coastguard Worker                            int pp_instance,
96*6777b538SAndroid Build Coastguard Worker                            bool success);
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   // Called when the renderer identified by |render_process_id| is closing.
99*6777b538SAndroid Build Coastguard Worker   // Clean up any outstanding translations for that renderer. If there are no
100*6777b538SAndroid Build Coastguard Worker   // more pending translations, the backend is freed, allowing it to flush.
101*6777b538SAndroid Build Coastguard Worker   void RendererClosing(int render_process_id);
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   // Doom all entries between |initial_time| and |end_time|. Like disk_cache_,
104*6777b538SAndroid Build Coastguard Worker   // PnaclHost supports supports unbounded deletes in either direction by using
105*6777b538SAndroid Build Coastguard Worker   // null Time values for either argument. |callback| will be called on the UI
106*6777b538SAndroid Build Coastguard Worker   // thread when finished.
107*6777b538SAndroid Build Coastguard Worker   void ClearTranslationCacheEntriesBetween(base::Time initial_time,
108*6777b538SAndroid Build Coastguard Worker                                            base::Time end_time,
109*6777b538SAndroid Build Coastguard Worker                                            base::OnceClosure callback);
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   // Return the number of tracked translations or FD requests currently pending.
pending_translations()112*6777b538SAndroid Build Coastguard Worker   size_t pending_translations() {
113*6777b538SAndroid Build Coastguard Worker     DCHECK(thread_checker_.CalledOnValidThread());
114*6777b538SAndroid Build Coastguard Worker     return pending_translations_.size();
115*6777b538SAndroid Build Coastguard Worker   }
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker  private:
118*6777b538SAndroid Build Coastguard Worker   friend class FileProxy;
119*6777b538SAndroid Build Coastguard Worker   friend class PnaclHostTest;
120*6777b538SAndroid Build Coastguard Worker   friend class PnaclHostTestDisk;
121*6777b538SAndroid Build Coastguard Worker   enum CacheState {
122*6777b538SAndroid Build Coastguard Worker     CacheUninitialized,
123*6777b538SAndroid Build Coastguard Worker     CacheInitializing,
124*6777b538SAndroid Build Coastguard Worker     CacheReady
125*6777b538SAndroid Build Coastguard Worker   };
126*6777b538SAndroid Build Coastguard Worker   class PendingTranslation {
127*6777b538SAndroid Build Coastguard Worker    public:
128*6777b538SAndroid Build Coastguard Worker     PendingTranslation();
129*6777b538SAndroid Build Coastguard Worker     PendingTranslation(const PendingTranslation& other);
130*6777b538SAndroid Build Coastguard Worker     ~PendingTranslation();
131*6777b538SAndroid Build Coastguard Worker     base::ProcessHandle process_handle;
132*6777b538SAndroid Build Coastguard Worker     raw_ptr<base::File> nexe_fd;
133*6777b538SAndroid Build Coastguard Worker     bool got_nexe_fd;
134*6777b538SAndroid Build Coastguard Worker     bool got_cache_reply;
135*6777b538SAndroid Build Coastguard Worker     bool got_cache_hit;
136*6777b538SAndroid Build Coastguard Worker     bool is_incognito;
137*6777b538SAndroid Build Coastguard Worker     scoped_refptr<net::DrainableIOBuffer> nexe_read_buffer;
138*6777b538SAndroid Build Coastguard Worker     NexeFdCallback callback;
139*6777b538SAndroid Build Coastguard Worker     std::string cache_key;
140*6777b538SAndroid Build Coastguard Worker     nacl::PnaclCacheInfo cache_info;
141*6777b538SAndroid Build Coastguard Worker   };
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker   typedef std::pair<int, int> TranslationID;
144*6777b538SAndroid Build Coastguard Worker   typedef std::map<TranslationID, PendingTranslation> PendingTranslationMap;
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker   PnaclHost();
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   static bool TranslationMayBeCached(
149*6777b538SAndroid Build Coastguard Worker       const PendingTranslationMap::iterator& entry);
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker   void InitForTest(base::FilePath temp_dir, bool in_memory);
152*6777b538SAndroid Build Coastguard Worker   void OnCacheInitialized(int net_error);
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   static void DoCreateTemporaryFile(base::FilePath temp_dir_,
155*6777b538SAndroid Build Coastguard Worker                                     TempFileCallback cb);
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker   // GetNexeFd common steps
158*6777b538SAndroid Build Coastguard Worker   void SendCacheQueryAndTempFileRequest(const std::string& key,
159*6777b538SAndroid Build Coastguard Worker                                         const TranslationID& id);
160*6777b538SAndroid Build Coastguard Worker   void OnCacheQueryReturn(const TranslationID& id,
161*6777b538SAndroid Build Coastguard Worker                           int net_error,
162*6777b538SAndroid Build Coastguard Worker                           scoped_refptr<net::DrainableIOBuffer> buffer);
163*6777b538SAndroid Build Coastguard Worker   void OnTempFileReturn(const TranslationID& id, base::File file);
164*6777b538SAndroid Build Coastguard Worker   void CheckCacheQueryReady(const PendingTranslationMap::iterator& entry);
165*6777b538SAndroid Build Coastguard Worker 
166*6777b538SAndroid Build Coastguard Worker   // GetNexeFd miss path
167*6777b538SAndroid Build Coastguard Worker   void ReturnMiss(const PendingTranslationMap::iterator& entry);
168*6777b538SAndroid Build Coastguard Worker   static scoped_refptr<net::DrainableIOBuffer> CopyFileToBuffer(
169*6777b538SAndroid Build Coastguard Worker       std::unique_ptr<base::File> file);
170*6777b538SAndroid Build Coastguard Worker   void StoreTranslatedNexe(TranslationID id,
171*6777b538SAndroid Build Coastguard Worker                            scoped_refptr<net::DrainableIOBuffer>);
172*6777b538SAndroid Build Coastguard Worker   void OnTranslatedNexeStored(const TranslationID& id, int net_error);
173*6777b538SAndroid Build Coastguard Worker   void RequeryMatchingTranslations(const std::string& key);
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   // GetNexeFd hit path
176*6777b538SAndroid Build Coastguard Worker   void OnBufferCopiedToTempFile(const TranslationID& id,
177*6777b538SAndroid Build Coastguard Worker                                 std::unique_ptr<base::File> file,
178*6777b538SAndroid Build Coastguard Worker                                 int file_error);
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   void OnEntriesDoomed(base::OnceClosure callback, int net_error);
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   void DeInitIfSafe();
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   scoped_refptr<base::SequencedTaskRunner> file_task_runner_ =
185*6777b538SAndroid Build Coastguard Worker       base::ThreadPool::CreateSequencedTaskRunner(
186*6777b538SAndroid Build Coastguard Worker           {base::MayBlock(), base::TaskPriority::USER_VISIBLE});
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   // Operations which are pending with the cache backend, which we should
189*6777b538SAndroid Build Coastguard Worker   // wait for before destroying it (see comment on DeInitIfSafe).
190*6777b538SAndroid Build Coastguard Worker   int pending_backend_operations_ = 0;
191*6777b538SAndroid Build Coastguard Worker   CacheState cache_state_ = CacheUninitialized;
192*6777b538SAndroid Build Coastguard Worker   base::FilePath temp_dir_;
193*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<PnaclTranslationCache> disk_cache_;
194*6777b538SAndroid Build Coastguard Worker   PendingTranslationMap pending_translations_;
195*6777b538SAndroid Build Coastguard Worker   base::ThreadChecker thread_checker_;
196*6777b538SAndroid Build Coastguard Worker };
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker }  // namespace pnacl
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker #endif  // COMPONENTS_NACL_BROWSER_PNACL_HOST_H_
201