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 CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_
6#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_
7
8#include <queue>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/memory/weak_ptr.h"
15#include "content/browser/renderer_host/pepper/quota_reservation.h"
16#include "content/common/content_export.h"
17#include "ppapi/c/pp_file_info.h"
18#include "ppapi/c/private/ppb_isolated_file_system_private.h"
19#include "ppapi/host/host_message_context.h"
20#include "ppapi/host/resource_host.h"
21#include "ppapi/shared_impl/file_growth.h"
22#include "storage/browser/fileapi/file_system_context.h"
23#include "url/gurl.h"
24
25namespace content {
26
27class BrowserPpapiHost;
28class PepperFileIOHost;
29
30class CONTENT_EXPORT PepperFileSystemBrowserHost
31    : public ppapi::host::ResourceHost,
32      public base::SupportsWeakPtr<PepperFileSystemBrowserHost> {
33 public:
34  // Creates a new PepperFileSystemBrowserHost for a file system of a given
35  // |type|. The host must be opened before use.
36  PepperFileSystemBrowserHost(BrowserPpapiHost* host,
37                              PP_Instance instance,
38                              PP_Resource resource,
39                              PP_FileSystemType type);
40  virtual ~PepperFileSystemBrowserHost();
41
42  // Opens the PepperFileSystemBrowserHost to use an existing file system at the
43  // given |root_url|. The file system at |root_url| must already be opened and
44  // have the type given by GetType().
45  // Calls |callback| when complete.
46  void OpenExisting(const GURL& root_url, const base::Closure& callback);
47
48  // ppapi::host::ResourceHost overrides.
49  virtual int32_t OnResourceMessageReceived(
50      const IPC::Message& msg,
51      ppapi::host::HostMessageContext* context) OVERRIDE;
52  virtual bool IsFileSystemHost() OVERRIDE;
53
54  // Supports FileRefs direct access on the host side.
55  PP_FileSystemType GetType() const { return type_; }
56  bool IsOpened() const { return opened_; }
57  GURL GetRootUrl() const { return root_url_; }
58  scoped_refptr<storage::FileSystemContext> GetFileSystemContext() const {
59    return file_system_context_;
60  }
61
62  // Supports FileIOs direct access on the host side.
63  // Non-NULL only for PP_FILESYSTEMTYPE_LOCAL{PERSISTENT,TEMPORARY}.
64  storage::FileSystemOperationRunner* GetFileSystemOperationRunner() const {
65    return file_system_operation_runner_.get();
66  }
67  bool ChecksQuota() const { return quota_reservation_.get() != NULL; }
68  // Opens a file for writing with quota checks. Returns the file size in the
69  // callback.
70  typedef base::Callback<void(int64_t)> OpenQuotaFileCallback;
71  void OpenQuotaFile(PepperFileIOHost* file_io_host,
72                     const storage::FileSystemURL& url,
73                     const OpenQuotaFileCallback& callback);
74  // Closes the file. This must be called after OpenQuotaFile and before the
75  // PepperFileIOHost is destroyed.
76  void CloseQuotaFile(PepperFileIOHost* file_io_host,
77                      const ppapi::FileGrowth& file_growth);
78
79 private:
80  friend class PepperFileSystemBrowserHostTest;
81
82  void OpenExistingFileSystem(
83      const base::Closure& callback,
84      scoped_refptr<storage::FileSystemContext> file_system_context);
85  void OpenFileSystem(
86      ppapi::host::ReplyMessageContext reply_context,
87      storage::FileSystemType file_system_type,
88      scoped_refptr<storage::FileSystemContext> file_system_context);
89  void OpenFileSystemComplete(ppapi::host::ReplyMessageContext reply_context,
90                              const GURL& root,
91                              const std::string& name,
92                              base::File::Error error);
93  void OpenIsolatedFileSystem(
94      ppapi::host::ReplyMessageContext reply_context,
95      const std::string& fsid,
96      PP_IsolatedFileSystemType_Private type,
97      scoped_refptr<storage::FileSystemContext> file_system_context);
98  void OpenPluginPrivateFileSystem(
99      ppapi::host::ReplyMessageContext reply_context,
100      const std::string& fsid,
101      scoped_refptr<storage::FileSystemContext> file_system_context);
102  void OpenPluginPrivateFileSystemComplete(
103      ppapi::host::ReplyMessageContext reply_context,
104      const std::string& fsid,
105      base::File::Error error);
106
107  int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
108                        int64_t expected_size);
109  int32_t OnHostMsgInitIsolatedFileSystem(
110      ppapi::host::HostMessageContext* context,
111      const std::string& fsid,
112      PP_IsolatedFileSystemType_Private type);
113  int32_t OnHostMsgReserveQuota(ppapi::host::HostMessageContext* context,
114                                int64_t amount,
115                                const ppapi::FileGrowthMap& file_growths);
116
117  void SendReplyForFileSystem(ppapi::host::ReplyMessageContext reply_context,
118                              int32_t pp_error);
119  void SendReplyForIsolatedFileSystem(
120      ppapi::host::ReplyMessageContext reply_context,
121      const std::string& fsid,
122      int32_t error);
123
124  void SetFileSystemContext(
125      scoped_refptr<storage::FileSystemContext> file_system_context);
126
127  bool ShouldCreateQuotaReservation() const;
128  void CreateQuotaReservation(const base::Closure& callback);
129  void GotQuotaReservation(const base::Closure& callback,
130                           scoped_refptr<QuotaReservation> quota_reservation);
131
132  void GotReservedQuota(ppapi::host::ReplyMessageContext reply_context,
133                        int64_t amount,
134                        const ppapi::FileSizeMap& file_sizes);
135  void DidOpenQuotaFile(PP_Resource file_io_resource,
136                        const OpenQuotaFileCallback& callback,
137                        int64_t max_written_offset);
138
139  std::string GetPluginMimeType() const;
140
141  // Returns plugin ID generated from plugin's MIME type.
142  std::string GeneratePluginId(const std::string& mime_type) const;
143
144  BrowserPpapiHost* browser_ppapi_host_;
145
146  PP_FileSystemType type_;
147  bool called_open_;  // whether open has been called.
148  bool opened_;       // whether open succeeded.
149  GURL root_url_;
150  scoped_refptr<storage::FileSystemContext> file_system_context_;
151
152  scoped_ptr<storage::FileSystemOperationRunner> file_system_operation_runner_;
153
154  // Used only for file systems with quota.
155  // When a PepperFileIOHost calls OpenQuotaFile, we add the id and a non-owning
156  // pointer to this map. CloseQuotaFile must be called when before the host is
157  // destroyed.
158  typedef std::map<int32_t, PepperFileIOHost*> FileMap;
159  FileMap files_;
160  int64_t reserved_quota_;
161  bool reserving_quota_;
162  // Access only on the FileSystemContext's default_file_task_runner().
163  scoped_refptr<QuotaReservation> quota_reservation_;
164
165  std::string fsid_;  // used only for isolated filesystems.
166
167  base::WeakPtrFactory<PepperFileSystemBrowserHost> weak_factory_;
168
169  DISALLOW_COPY_AND_ASSIGN(PepperFileSystemBrowserHost);
170};
171
172}  // namespace content
173
174#endif  // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_FILE_SYSTEM_BROWSER_HOST_H_
175