Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/filesystem/GetFilesTask.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "GetFilesTask.h"
8
9
#include "HTMLSplitOnSpacesTokenizer.h"
10
#include "js/Value.h"
11
#include "mozilla/dom/File.h"
12
#include "mozilla/dom/FileSystemBase.h"
13
#include "mozilla/dom/FileSystemUtils.h"
14
#include "mozilla/dom/IPCBlobUtils.h"
15
#include "mozilla/dom/PFileSystemParams.h"
16
#include "mozilla/dom/Promise.h"
17
#include "nsIFile.h"
18
#include "nsString.h"
19
20
namespace mozilla {
21
namespace dom {
22
23
/**
24
 * GetFilesTaskChild
25
 */
26
27
/* static */ already_AddRefed<GetFilesTaskChild>
28
GetFilesTaskChild::Create(FileSystemBase* aFileSystem,
29
                          Directory* aDirectory,
30
                          nsIFile* aTargetPath,
31
                          bool aRecursiveFlag,
32
                          ErrorResult& aRv)
33
0
{
34
0
  MOZ_ASSERT(aFileSystem);
35
0
  MOZ_ASSERT(aDirectory);
36
0
  aFileSystem->AssertIsOnOwningThread();
37
0
38
0
  nsCOMPtr<nsIGlobalObject> globalObject =
39
0
    do_QueryInterface(aFileSystem->GetParentObject());
40
0
  if (NS_WARN_IF(!globalObject)) {
41
0
    aRv.Throw(NS_ERROR_FAILURE);
42
0
    return nullptr;
43
0
  }
44
0
45
0
  RefPtr<GetFilesTaskChild> task =
46
0
    new GetFilesTaskChild(globalObject, aFileSystem, aDirectory, aTargetPath,
47
0
                          aRecursiveFlag);
48
0
49
0
  // aTargetPath can be null. In this case SetError will be called.
50
0
51
0
  task->mPromise = Promise::Create(globalObject, aRv);
52
0
  if (NS_WARN_IF(aRv.Failed())) {
53
0
    return nullptr;
54
0
  }
55
0
56
0
  return task.forget();
57
0
}
58
59
GetFilesTaskChild::GetFilesTaskChild(nsIGlobalObject *aGlobalObject,
60
                                     FileSystemBase* aFileSystem,
61
                                     Directory* aDirectory,
62
                                     nsIFile* aTargetPath,
63
                                     bool aRecursiveFlag)
64
  : FileSystemTaskChildBase(aGlobalObject, aFileSystem)
65
  , mDirectory(aDirectory)
66
  , mTargetPath(aTargetPath)
67
  , mRecursiveFlag(aRecursiveFlag)
68
0
{
69
0
  MOZ_ASSERT(aFileSystem);
70
0
  MOZ_ASSERT(aDirectory);
71
0
  aFileSystem->AssertIsOnOwningThread();
72
0
}
73
74
GetFilesTaskChild::~GetFilesTaskChild()
75
0
{
76
0
  mFileSystem->AssertIsOnOwningThread();
77
0
}
78
79
already_AddRefed<Promise>
80
GetFilesTaskChild::GetPromise()
81
0
{
82
0
  mFileSystem->AssertIsOnOwningThread();
83
0
  return RefPtr<Promise>(mPromise).forget();
84
0
}
85
86
FileSystemParams
87
GetFilesTaskChild::GetRequestParams(const nsString& aSerializedDOMPath,
88
                                    ErrorResult& aRv) const
89
0
{
90
0
  mFileSystem->AssertIsOnOwningThread();
91
0
92
0
  nsAutoString path;
93
0
  aRv = mTargetPath->GetPath(path);
94
0
  if (NS_WARN_IF(aRv.Failed())) {
95
0
    return FileSystemGetFilesParams();
96
0
  }
97
0
98
0
  nsAutoString domPath;
99
0
  mDirectory->GetPath(domPath, aRv);
100
0
  if (NS_WARN_IF(aRv.Failed())) {
101
0
    return FileSystemGetFilesParams();
102
0
  }
103
0
104
0
  return FileSystemGetFilesParams(aSerializedDOMPath, path, domPath,
105
0
                                  mRecursiveFlag);
106
0
}
107
108
void
109
GetFilesTaskChild::SetSuccessRequestResult(const FileSystemResponseValue& aValue,
110
                                           ErrorResult& aRv)
111
0
{
112
0
  mFileSystem->AssertIsOnOwningThread();
113
0
  MOZ_ASSERT(aValue.type() ==
114
0
               FileSystemResponseValue::TFileSystemFilesResponse);
115
0
116
0
  FileSystemFilesResponse r = aValue;
117
0
118
0
  if (!mTargetData.SetLength(r.data().Length(), mozilla::fallible_t())) {
119
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
120
0
    return;
121
0
  }
122
0
123
0
  for (uint32_t i = 0; i < r.data().Length(); ++i) {
124
0
    const FileSystemFileResponse& data = r.data()[i];
125
0
    RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(data.blob());
126
0
    MOZ_ASSERT(blobImpl);
127
0
128
0
    mTargetData[i] = File::Create(mFileSystem->GetParentObject(), blobImpl);
129
0
  }
130
0
}
131
132
void
133
GetFilesTaskChild::HandlerCallback()
134
0
{
135
0
  mFileSystem->AssertIsOnOwningThread();
136
0
  if (mFileSystem->IsShutdown()) {
137
0
    mPromise = nullptr;
138
0
    return;
139
0
  }
140
0
141
0
  if (HasError()) {
142
0
    mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
143
0
    mPromise = nullptr;
144
0
    return;
145
0
  }
146
0
147
0
  mPromise->MaybeResolve(mTargetData);
148
0
  mPromise = nullptr;
149
0
}
150
151
/**
152
 * GetFilesTaskParent
153
 */
154
155
/* static */ already_AddRefed<GetFilesTaskParent>
156
GetFilesTaskParent::Create(FileSystemBase* aFileSystem,
157
                           const FileSystemGetFilesParams& aParam,
158
                           FileSystemRequestParent* aParent,
159
                           ErrorResult& aRv)
160
0
{
161
0
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
162
0
  AssertIsOnBackgroundThread();
163
0
  MOZ_ASSERT(aFileSystem);
164
0
165
0
  RefPtr<GetFilesTaskParent> task =
166
0
    new GetFilesTaskParent(aFileSystem, aParam, aParent);
167
0
168
0
  aRv = NS_NewLocalFile(aParam.realPath(), true,
169
0
                        getter_AddRefs(task->mTargetPath));
170
0
  if (NS_WARN_IF(aRv.Failed())) {
171
0
    return nullptr;
172
0
  }
173
0
174
0
  return task.forget();
175
0
}
176
177
GetFilesTaskParent::GetFilesTaskParent(FileSystemBase* aFileSystem,
178
                                       const FileSystemGetFilesParams& aParam,
179
                                       FileSystemRequestParent* aParent)
180
  : FileSystemTaskParentBase(aFileSystem, aParam, aParent)
181
  , GetFilesHelperBase(aParam.recursiveFlag())
182
  , mDirectoryDOMPath(aParam.domPath())
183
0
{
184
0
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
185
0
  AssertIsOnBackgroundThread();
186
0
  MOZ_ASSERT(aFileSystem);
187
0
}
188
189
FileSystemResponseValue
190
GetFilesTaskParent::GetSuccessRequestResult(ErrorResult& aRv) const
191
0
{
192
0
  AssertIsOnBackgroundThread();
193
0
194
0
  FallibleTArray<FileSystemFileResponse> inputs;
195
0
  if (!inputs.SetLength(mTargetBlobImplArray.Length(), mozilla::fallible_t())) {
196
0
    FileSystemFilesResponse response;
197
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
198
0
    return response;
199
0
  }
200
0
201
0
  for (unsigned i = 0; i < mTargetBlobImplArray.Length(); i++) {
202
0
    IPCBlob ipcBlob;
203
0
    aRv = IPCBlobUtils::Serialize(mTargetBlobImplArray[i],
204
0
                                  mRequestParent->Manager(), ipcBlob);
205
0
    if (NS_WARN_IF(aRv.Failed())) {
206
0
      FileSystemFilesResponse response;
207
0
      return response;
208
0
    }
209
0
210
0
    inputs[i] = FileSystemFileResponse(ipcBlob);
211
0
  }
212
0
213
0
  FileSystemFilesResponse response;
214
0
  response.data().SwapElements(inputs);
215
0
  return response;
216
0
}
217
218
nsresult
219
GetFilesTaskParent::IOWork()
220
0
{
221
0
  MOZ_ASSERT(XRE_IsParentProcess(),
222
0
             "Only call from parent process!");
223
0
  MOZ_ASSERT(!NS_IsMainThread(), "Only call on I/O thread!");
224
0
225
0
  if (mFileSystem->IsShutdown()) {
226
0
    return NS_ERROR_FAILURE;
227
0
  }
228
0
229
0
  bool exists;
230
0
  nsresult rv = mTargetPath->Exists(&exists);
231
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
232
0
    return rv;
233
0
  }
234
0
235
0
  if (!exists) {
236
0
    return NS_OK;
237
0
  }
238
0
239
0
  bool isDir;
240
0
  rv = mTargetPath->IsDirectory(&isDir);
241
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
242
0
    return rv;
243
0
  }
244
0
245
0
  if (!isDir) {
246
0
    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
247
0
  }
248
0
249
0
  // Get isDirectory.
250
0
  rv = ExploreDirectory(mDirectoryDOMPath, mTargetPath);
251
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
252
0
    return rv;
253
0
  }
254
0
255
0
  return NS_OK;
256
0
}
257
258
nsresult
259
GetFilesTaskParent::GetTargetPath(nsAString& aPath) const
260
0
{
261
0
  return mTargetPath->GetPath(aPath);
262
0
}
263
264
} // namespace dom
265
} // namespace mozilla