1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android-base/file.h>
18 #include <android-base/logging.h>
19 #include <android-base/unique_fd.h>
20 #include <binder/ParcelFileDescriptor.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <utils/Log.h>
24 
25 #include <chrono>
26 #include <future>
27 
28 #include "IncrementalService.h"
29 #include "IncrementalServiceValidation.h"
30 #include "Metadata.pb.h"
31 #include "ServiceWrappers.h"
32 
33 using namespace testing;
34 using namespace android::incremental;
35 using namespace std::literals;
36 using testing::_;
37 using testing::Invoke;
38 using testing::NiceMock;
39 
40 #undef LOG_TAG
41 #define LOG_TAG "IncrementalServiceTest"
42 
43 using namespace android::incfs;
44 using namespace android::content::pm;
45 
46 namespace android::os::incremental {
47 
48 class MockVoldService : public VoldServiceWrapper {
49 public:
50     MOCK_CONST_METHOD4(mountIncFs,
51                        binder::Status(const std::string& backingPath, const std::string& targetDir,
52                                       int32_t flags,
53                                       IncrementalFileSystemControlParcel* _aidl_return));
54     MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
55     MOCK_CONST_METHOD2(bindMount,
56                        binder::Status(const std::string& sourceDir, const std::string& argetDir));
57     MOCK_CONST_METHOD2(setIncFsMountOptions,
58                        binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&, bool));
59 
mountIncFsFails()60     void mountIncFsFails() {
61         ON_CALL(*this, mountIncFs(_, _, _, _))
62                 .WillByDefault(
63                         Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
64     }
mountIncFsInvalidControlParcel()65     void mountIncFsInvalidControlParcel() {
66         ON_CALL(*this, mountIncFs(_, _, _, _))
67                 .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
68     }
mountIncFsSuccess()69     void mountIncFsSuccess() {
70         ON_CALL(*this, mountIncFs(_, _, _, _))
71                 .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
72     }
bindMountFails()73     void bindMountFails() {
74         ON_CALL(*this, bindMount(_, _))
75                 .WillByDefault(Return(
76                         binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
77     }
bindMountSuccess()78     void bindMountSuccess() {
79         ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
80     }
setIncFsMountOptionsFails() const81     void setIncFsMountOptionsFails() const {
82         ON_CALL(*this, setIncFsMountOptions(_, _))
83                 .WillByDefault(
84                         Return(binder::Status::fromExceptionCode(1, String8("failed to set options"))));
85     }
setIncFsMountOptionsSuccess()86     void setIncFsMountOptionsSuccess() {
87         ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
88     }
getInvalidControlParcel(const std::string & imagePath,const std::string & targetDir,int32_t flags,IncrementalFileSystemControlParcel * _aidl_return)89     binder::Status getInvalidControlParcel(const std::string& imagePath,
90                                            const std::string& targetDir, int32_t flags,
91                                            IncrementalFileSystemControlParcel* _aidl_return) {
92         _aidl_return = {};
93         return binder::Status::ok();
94     }
incFsSuccess(const std::string & imagePath,const std::string & targetDir,int32_t flags,IncrementalFileSystemControlParcel * _aidl_return)95     binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
96                                 int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
97         _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
98         _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
99         _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
100         return binder::Status::ok();
101     }
102 
103 private:
104     TemporaryFile cmdFile;
105     TemporaryFile logFile;
106 };
107 
108 class MockDataLoader : public IDataLoader {
109 public:
MockDataLoader()110     MockDataLoader() {
111         ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk));
112         ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk));
113         ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk));
114         ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk));
115         ON_CALL(*this, prepareImage(_, _, _))
116                 .WillByDefault(Invoke(this, &MockDataLoader::prepareImageOk));
117     }
onAsBinder()118     IBinder* onAsBinder() override { return nullptr; }
119     MOCK_METHOD4(create,
120                  binder::Status(int32_t id, const DataLoaderParamsParcel& params,
121                                 const FileSystemControlParcel& control,
122                                 const sp<IDataLoaderStatusListener>& listener));
123     MOCK_METHOD1(start, binder::Status(int32_t id));
124     MOCK_METHOD1(stop, binder::Status(int32_t id));
125     MOCK_METHOD1(destroy, binder::Status(int32_t id));
126     MOCK_METHOD3(prepareImage,
127                  binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles,
128                                 const std::vector<std::string>& removedFiles));
129 
initializeCreateOkNoStatus()130     void initializeCreateOkNoStatus() {
131         ON_CALL(*this, create(_, _, _, _))
132                 .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus));
133     }
134 
createOk(int32_t id,const content::pm::DataLoaderParamsParcel & params,const content::pm::FileSystemControlParcel & control,const sp<content::pm::IDataLoaderStatusListener> & listener)135     binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params,
136                             const content::pm::FileSystemControlParcel& control,
137                             const sp<content::pm::IDataLoaderStatusListener>& listener) {
138         createOkNoStatus(id, params, control, listener);
139         if (mListener) {
140             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_CREATED);
141         }
142         return binder::Status::ok();
143     }
createOkNoStatus(int32_t id,const content::pm::DataLoaderParamsParcel & params,const content::pm::FileSystemControlParcel & control,const sp<content::pm::IDataLoaderStatusListener> & listener)144     binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
145                                     const content::pm::FileSystemControlParcel& control,
146                                     const sp<content::pm::IDataLoaderStatusListener>& listener) {
147         mServiceConnector = control.service;
148         mListener = listener;
149         return binder::Status::ok();
150     }
startOk(int32_t id)151     binder::Status startOk(int32_t id) {
152         if (mListener) {
153             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
154         }
155         return binder::Status::ok();
156     }
stopOk(int32_t id)157     binder::Status stopOk(int32_t id) {
158         if (mListener) {
159             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
160         }
161         return binder::Status::ok();
162     }
destroyOk(int32_t id)163     binder::Status destroyOk(int32_t id) {
164         if (mListener) {
165             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
166         }
167         mListener = nullptr;
168         return binder::Status::ok();
169     }
prepareImageOk(int32_t id,const::std::vector<content::pm::InstallationFileParcel> &,const::std::vector<::std::string> &)170     binder::Status prepareImageOk(int32_t id,
171                                   const ::std::vector<content::pm::InstallationFileParcel>&,
172                                   const ::std::vector<::std::string>&) {
173         if (mListener) {
174             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
175         }
176         return binder::Status::ok();
177     }
setStorageParams(bool enableReadLogs)178     int32_t setStorageParams(bool enableReadLogs) {
179         int32_t result = -1;
180         EXPECT_NE(mServiceConnector.get(), nullptr);
181         EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
182         return result;
183     }
184 
185 private:
186     sp<IIncrementalServiceConnector> mServiceConnector;
187     sp<IDataLoaderStatusListener> mListener;
188 };
189 
190 class MockDataLoaderManager : public DataLoaderManagerWrapper {
191 public:
MockDataLoaderManager(sp<IDataLoader> dataLoader)192     MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
193         EXPECT_TRUE(mDataLoaderHolder != nullptr);
194     }
195 
196     MOCK_CONST_METHOD4(bindToDataLoader,
197                        binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
198                                       const sp<IDataLoaderStatusListener>& listener,
199                                       bool* _aidl_return));
200     MOCK_CONST_METHOD2(getDataLoader,
201                        binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
202     MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));
203 
bindToDataLoaderSuccess()204     void bindToDataLoaderSuccess() {
205         ON_CALL(*this, bindToDataLoader(_, _, _, _))
206                 .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
207     }
bindToDataLoaderFails()208     void bindToDataLoaderFails() {
209         ON_CALL(*this, bindToDataLoader(_, _, _, _))
210                 .WillByDefault(Return(
211                         (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
212     }
getDataLoaderSuccess()213     void getDataLoaderSuccess() {
214         ON_CALL(*this, getDataLoader(_, _))
215                 .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
216     }
unbindFromDataLoaderSuccess()217     void unbindFromDataLoaderSuccess() {
218         ON_CALL(*this, unbindFromDataLoader(_))
219                 .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
220     }
bindToDataLoaderOk(int32_t mountId,const DataLoaderParamsParcel & params,const sp<IDataLoaderStatusListener> & listener,bool * _aidl_return)221     binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
222                                       const sp<IDataLoaderStatusListener>& listener,
223                                       bool* _aidl_return) {
224         mId = mountId;
225         mListener = listener;
226         mDataLoader = mDataLoaderHolder;
227         *_aidl_return = true;
228         if (mListener) {
229             mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
230         }
231         return binder::Status::ok();
232     }
getDataLoaderOk(int32_t mountId,sp<IDataLoader> * _aidl_return)233     binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
234         *_aidl_return = mDataLoader;
235         return binder::Status::ok();
236     }
setDataLoaderStatusCreated()237     void setDataLoaderStatusCreated() {
238         mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
239     }
setDataLoaderStatusStarted()240     void setDataLoaderStatusStarted() {
241         mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
242     }
setDataLoaderStatusDestroyed()243     void setDataLoaderStatusDestroyed() {
244         mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
245     }
setDataLoaderStatusUnavailable()246     void setDataLoaderStatusUnavailable() {
247         mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
248     }
unbindFromDataLoaderOk(int32_t id)249     binder::Status unbindFromDataLoaderOk(int32_t id) {
250         if (mDataLoader) {
251             if (auto status = mDataLoader->destroy(id); !status.isOk()) {
252                 return status;
253             }
254             mDataLoader = nullptr;
255         }
256         if (mListener) {
257             mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
258         }
259         return binder::Status::ok();
260     }
261 
262 private:
263     int mId;
264     sp<IDataLoaderStatusListener> mListener;
265     sp<IDataLoader> mDataLoader;
266     sp<IDataLoader> mDataLoaderHolder;
267 };
268 
269 class MockIncFs : public IncFsWrapper {
270 public:
271     MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
272     MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
273     MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
274     MOCK_CONST_METHOD5(makeFile,
275                        ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
276                                  NewFileParams params));
277     MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
278     MOCK_CONST_METHOD3(makeDirs,
279                        ErrorCode(const Control& control, std::string_view path, int mode));
280     MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
281     MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
282     MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
283     MOCK_CONST_METHOD3(link,
284                        ErrorCode(const Control& control, std::string_view from, std::string_view to));
285     MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
286     MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
287     MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
288     MOCK_CONST_METHOD3(waitForPendingReads,
289                        WaitResult(const Control& control, std::chrono::milliseconds timeout,
290                                   std::vector<incfs::ReadInfo>* pendingReadsBuffer));
291 
MockIncFs()292     MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
293 
makeFileFails()294     void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
makeFileSuccess()295     void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
openMountSuccess()296     void openMountSuccess() {
297         ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
298     }
299 
300     // 1000ms
waitForPendingReadsSuccess(uint64_t ts=0)301     void waitForPendingReadsSuccess(uint64_t ts = 0) {
302         ON_CALL(*this, waitForPendingReads(_, _, _))
303                 .WillByDefault(
304                         Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
305                                     std::vector<incfs::ReadInfo>* pendingReadsBuffer) {
306                             pendingReadsBuffer->push_back({.bootClockTsUs = ts});
307                             return android::incfs::WaitResult::HaveData;
308                         }));
309     }
310 
waitForPendingReadsTimeout()311     void waitForPendingReadsTimeout() {
312         ON_CALL(*this, waitForPendingReads(_, _, _))
313                 .WillByDefault(Return(android::incfs::WaitResult::Timeout));
314     }
315 
316     static constexpr auto kPendingReadsFd = 42;
openMountForHealth(std::string_view)317     Control openMountForHealth(std::string_view) {
318         return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1));
319     }
320 
getMountInfoMetadata(const Control & control,std::string_view path)321     RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
322         metadata::Mount m;
323         m.mutable_storage()->set_id(100);
324         m.mutable_loader()->set_package_name("com.test");
325         m.mutable_loader()->set_arguments("com.uri");
326         const auto metadata = m.SerializeAsString();
327         m.mutable_loader()->release_arguments();
328         m.mutable_loader()->release_package_name();
329         return {metadata.begin(), metadata.end()};
330     }
getStorageMetadata(const Control & control,std::string_view path)331     RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
332         metadata::Storage st;
333         st.set_id(100);
334         auto metadata = st.SerializeAsString();
335         return {metadata.begin(), metadata.end()};
336     }
getBindPointMetadata(const Control & control,std::string_view path)337     RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
338         metadata::BindPoint bp;
339         std::string destPath = "dest";
340         std::string srcPath = "src";
341         bp.set_storage_id(100);
342         bp.set_allocated_dest_path(&destPath);
343         bp.set_allocated_source_subdir(&srcPath);
344         const auto metadata = bp.SerializeAsString();
345         bp.release_source_subdir();
346         bp.release_dest_path();
347         return std::vector<char>(metadata.begin(), metadata.end());
348     }
349 };
350 
351 class MockAppOpsManager : public AppOpsManagerWrapper {
352 public:
353     MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
354     MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
355     MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));
356 
checkPermissionSuccess()357     void checkPermissionSuccess() {
358         ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
359     }
checkPermissionFails()360     void checkPermissionFails() {
361         ON_CALL(*this, checkPermission(_, _, _))
362                 .WillByDefault(
363                         Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
364     }
initializeStartWatchingMode()365     void initializeStartWatchingMode() {
366         ON_CALL(*this, startWatchingMode(_, _, _))
367                 .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
368     }
storeCallback(int32_t,const String16 &,const sp<IAppOpsCallback> & cb)369     void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
370         mStoredCallback = cb;
371     }
372 
373     sp<IAppOpsCallback> mStoredCallback;
374 };
375 
376 class MockJniWrapper : public JniWrapper {
377 public:
378     MOCK_CONST_METHOD0(initializeForCurrentThread, void());
379 
MockJniWrapper()380     MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
381 };
382 
383 class MockLooperWrapper : public LooperWrapper {
384 public:
385     MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
386     MOCK_METHOD1(removeFd, int(int));
387     MOCK_METHOD0(wake, void());
388     MOCK_METHOD1(pollAll, int(int));
389 
MockLooperWrapper()390     MockLooperWrapper() {
391         ON_CALL(*this, addFd(_, _, _, _, _))
392                 .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
393         ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
394         ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
395     }
396 
storeCallback(int,int,int,android::Looper_callbackFunc callback,void * data)397     int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
398         mCallback = callback;
399         mCallbackData = data;
400         return 0;
401     }
402 
clearCallback(int)403     int clearCallback(int) {
404         mCallback = nullptr;
405         mCallbackData = nullptr;
406         return 0;
407     }
408 
wait10Ms(int)409     int wait10Ms(int) {
410         // This is called from a loop in runCmdLooper.
411         // Sleeping for 10ms only to avoid busy looping.
412         std::this_thread::sleep_for(10ms);
413         return 0;
414     }
415 
416     android::Looper_callbackFunc mCallback = nullptr;
417     void* mCallbackData = nullptr;
418 };
419 
420 class MockTimedQueueWrapper : public TimedQueueWrapper {
421 public:
422     MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
423     MOCK_METHOD1(removeJobs, void(MountId));
424     MOCK_METHOD0(stop, void());
425 
MockTimedQueueWrapper()426     MockTimedQueueWrapper() {
427         ON_CALL(*this, addJob(_, _, _))
428                 .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
429         ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
430     }
431 
storeJob(MountId id,Milliseconds after,Job what)432     void storeJob(MountId id, Milliseconds after, Job what) {
433         mId = id;
434         mAfter = after;
435         mWhat = std::move(what);
436     }
437 
clearJob(MountId id)438     void clearJob(MountId id) {
439         if (mId == id) {
440             mAfter = {};
441             mWhat = {};
442         }
443     }
444 
445     MountId mId = -1;
446     Milliseconds mAfter;
447     Job mWhat;
448 };
449 
450 class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
451 public:
452     MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
453 
MockStorageHealthListener()454     MockStorageHealthListener() {
455         ON_CALL(*this, onHealthStatus(_, _))
456                 .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
457     }
458 
storeStorageIdAndStatus(int32_t storageId,int32_t status)459     binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
460         mStorageId = storageId;
461         mStatus = status;
462         return binder::Status::ok();
463     }
464 
465     int32_t mStorageId = -1;
466     int32_t mStatus = -1;
467 };
468 
469 class MockServiceManager : public ServiceManagerWrapper {
470 public:
MockServiceManager(std::unique_ptr<MockVoldService> vold,std::unique_ptr<MockDataLoaderManager> dataLoaderManager,std::unique_ptr<MockIncFs> incfs,std::unique_ptr<MockAppOpsManager> appOpsManager,std::unique_ptr<MockJniWrapper> jni,std::unique_ptr<MockLooperWrapper> looper,std::unique_ptr<MockTimedQueueWrapper> timedQueue)471     MockServiceManager(std::unique_ptr<MockVoldService> vold,
472                        std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
473                        std::unique_ptr<MockIncFs> incfs,
474                        std::unique_ptr<MockAppOpsManager> appOpsManager,
475                        std::unique_ptr<MockJniWrapper> jni,
476                        std::unique_ptr<MockLooperWrapper> looper,
477                        std::unique_ptr<MockTimedQueueWrapper> timedQueue)
478           : mVold(std::move(vold)),
479             mDataLoaderManager(std::move(dataLoaderManager)),
480             mIncFs(std::move(incfs)),
481             mAppOpsManager(std::move(appOpsManager)),
482             mJni(std::move(jni)),
483             mLooper(std::move(looper)),
484             mTimedQueue(std::move(timedQueue)) {}
getVoldService()485     std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
getDataLoaderManager()486     std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
487         return std::move(mDataLoaderManager);
488     }
getIncFs()489     std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
getAppOpsManager()490     std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final { return std::move(mAppOpsManager); }
getJni()491     std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
getLooper()492     std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
getTimedQueue()493     std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
494 
495 private:
496     std::unique_ptr<MockVoldService> mVold;
497     std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
498     std::unique_ptr<MockIncFs> mIncFs;
499     std::unique_ptr<MockAppOpsManager> mAppOpsManager;
500     std::unique_ptr<MockJniWrapper> mJni;
501     std::unique_ptr<MockLooperWrapper> mLooper;
502     std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
503 };
504 
505 // --- IncrementalServiceTest ---
506 
507 class IncrementalServiceTest : public testing::Test {
508 public:
SetUp()509     void SetUp() override {
510         auto vold = std::make_unique<NiceMock<MockVoldService>>();
511         mVold = vold.get();
512         sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
513         mDataLoader = dataLoader.get();
514         auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
515         mDataLoaderManager = dataloaderManager.get();
516         auto incFs = std::make_unique<NiceMock<MockIncFs>>();
517         mIncFs = incFs.get();
518         auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
519         mAppOpsManager = appOps.get();
520         auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
521         mJni = jni.get();
522         auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
523         mLooper = looper.get();
524         auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
525         mTimedQueue = timedQueue.get();
526         mIncrementalService =
527                 std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
528                                                                         std::move(
529                                                                                 dataloaderManager),
530                                                                         std::move(incFs),
531                                                                         std::move(appOps),
532                                                                         std::move(jni),
533                                                                         std::move(looper),
534                                                                         std::move(timedQueue)),
535                                                      mRootDir.path);
536         mDataLoaderParcel.packageName = "com.test";
537         mDataLoaderParcel.arguments = "uri";
538         mDataLoaderManager->unbindFromDataLoaderSuccess();
539         mIncrementalService->onSystemReady();
540     }
541 
setUpExistingMountDir(const std::string & rootDir)542     void setUpExistingMountDir(const std::string& rootDir) {
543         const auto dir = rootDir + "/dir1";
544         const auto mountDir = dir + "/mount";
545         const auto backingDir = dir + "/backing_store";
546         const auto storageDir = mountDir + "/st0";
547         ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
548         ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
549         ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
550         ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
551         const auto mountInfoFile = rootDir + "/dir1/mount/.info";
552         const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
553         ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
554         ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
555         ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
556                 .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
557         ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
558                 .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
559         ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
560                 .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
561     }
562 
563 protected:
564     NiceMock<MockVoldService>* mVold = nullptr;
565     NiceMock<MockIncFs>* mIncFs = nullptr;
566     NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
567     NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
568     NiceMock<MockJniWrapper>* mJni = nullptr;
569     NiceMock<MockLooperWrapper>* mLooper = nullptr;
570     NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
571     NiceMock<MockDataLoader>* mDataLoader = nullptr;
572     std::unique_ptr<IncrementalService> mIncrementalService;
573     TemporaryDir mRootDir;
574     DataLoaderParamsParcel mDataLoaderParcel;
575 };
576 
TEST_F(IncrementalServiceTest,testCreateStorageMountIncFsFails)577 TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
578     mVold->mountIncFsFails();
579     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
580     TemporaryDir tempDir;
581     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
582                                                        IncrementalService::CreateOptions::CreateNew,
583                                                        {}, {}, {});
584     ASSERT_LT(storageId, 0);
585 }
586 
TEST_F(IncrementalServiceTest,testCreateStorageMountIncFsInvalidControlParcel)587 TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
588     mVold->mountIncFsInvalidControlParcel();
589     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
590     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
591     TemporaryDir tempDir;
592     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
593                                                        IncrementalService::CreateOptions::CreateNew,
594                                                        {}, {}, {});
595     ASSERT_LT(storageId, 0);
596 }
597 
TEST_F(IncrementalServiceTest,testCreateStorageMakeFileFails)598 TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
599     mVold->mountIncFsSuccess();
600     mIncFs->makeFileFails();
601     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
602     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
603     EXPECT_CALL(*mVold, unmountIncFs(_));
604     TemporaryDir tempDir;
605     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
606                                                        IncrementalService::CreateOptions::CreateNew,
607                                                        {}, {}, {});
608     ASSERT_LT(storageId, 0);
609 }
610 
TEST_F(IncrementalServiceTest,testCreateStorageBindMountFails)611 TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
612     mVold->mountIncFsSuccess();
613     mIncFs->makeFileSuccess();
614     mVold->bindMountFails();
615     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0);
616     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
617     EXPECT_CALL(*mVold, unmountIncFs(_));
618     TemporaryDir tempDir;
619     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
620                                                        IncrementalService::CreateOptions::CreateNew,
621                                                        {}, {}, {});
622     ASSERT_LT(storageId, 0);
623 }
624 
TEST_F(IncrementalServiceTest,testCreateStoragePrepareDataLoaderFails)625 TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
626     mVold->mountIncFsSuccess();
627     mIncFs->makeFileSuccess();
628     mVold->bindMountSuccess();
629     mDataLoaderManager->bindToDataLoaderFails();
630     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
631     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
632     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
633     EXPECT_CALL(*mDataLoader, start(_)).Times(0);
634     EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
635     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
636     TemporaryDir tempDir;
637     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
638                                                        IncrementalService::CreateOptions::CreateNew,
639                                                        {}, {}, {});
640     ASSERT_LT(storageId, 0);
641 }
642 
TEST_F(IncrementalServiceTest,testDeleteStorageSuccess)643 TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
644     mVold->mountIncFsSuccess();
645     mIncFs->makeFileSuccess();
646     mVold->bindMountSuccess();
647     mDataLoaderManager->bindToDataLoaderSuccess();
648     mDataLoaderManager->getDataLoaderSuccess();
649     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
650     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
651     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
652     EXPECT_CALL(*mDataLoader, start(_)).Times(0);
653     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
654     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
655     TemporaryDir tempDir;
656     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
657                                                        IncrementalService::CreateOptions::CreateNew,
658                                                        {}, {}, {});
659     ASSERT_GE(storageId, 0);
660     mIncrementalService->deleteStorage(storageId);
661 }
662 
TEST_F(IncrementalServiceTest,testDataLoaderDestroyed)663 TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
664     mVold->mountIncFsSuccess();
665     mIncFs->makeFileSuccess();
666     mVold->bindMountSuccess();
667     mDataLoaderManager->bindToDataLoaderSuccess();
668     mDataLoaderManager->getDataLoaderSuccess();
669     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
670     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
671     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
672     EXPECT_CALL(*mDataLoader, start(_)).Times(0);
673     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
674     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
675     TemporaryDir tempDir;
676     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
677                                                        IncrementalService::CreateOptions::CreateNew,
678                                                        {}, {}, {});
679     ASSERT_GE(storageId, 0);
680     // Simulated crash/other connection breakage.
681     mDataLoaderManager->setDataLoaderStatusDestroyed();
682 }
683 
TEST_F(IncrementalServiceTest,testStartDataLoaderCreate)684 TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
685     mVold->mountIncFsSuccess();
686     mIncFs->makeFileSuccess();
687     mVold->bindMountSuccess();
688     mDataLoader->initializeCreateOkNoStatus();
689     mDataLoaderManager->bindToDataLoaderSuccess();
690     mDataLoaderManager->getDataLoaderSuccess();
691     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
692     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
693     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
694     EXPECT_CALL(*mDataLoader, start(_)).Times(1);
695     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
696     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
697     TemporaryDir tempDir;
698     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
699                                                        IncrementalService::CreateOptions::CreateNew,
700                                                        {}, {}, {});
701     ASSERT_GE(storageId, 0);
702     mDataLoaderManager->setDataLoaderStatusCreated();
703     ASSERT_TRUE(mIncrementalService->startLoading(storageId));
704     mDataLoaderManager->setDataLoaderStatusStarted();
705 }
706 
TEST_F(IncrementalServiceTest,testStartDataLoaderPendingStart)707 TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
708     mVold->mountIncFsSuccess();
709     mIncFs->makeFileSuccess();
710     mVold->bindMountSuccess();
711     mDataLoader->initializeCreateOkNoStatus();
712     mDataLoaderManager->bindToDataLoaderSuccess();
713     mDataLoaderManager->getDataLoaderSuccess();
714     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
715     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
716     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
717     EXPECT_CALL(*mDataLoader, start(_)).Times(1);
718     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
719     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
720     TemporaryDir tempDir;
721     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
722                                                        IncrementalService::CreateOptions::CreateNew,
723                                                        {}, {}, {});
724     ASSERT_GE(storageId, 0);
725     ASSERT_TRUE(mIncrementalService->startLoading(storageId));
726     mDataLoaderManager->setDataLoaderStatusCreated();
727 }
728 
TEST_F(IncrementalServiceTest,testStartDataLoaderCreateUnavailable)729 TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
730     mVold->mountIncFsSuccess();
731     mIncFs->makeFileSuccess();
732     mVold->bindMountSuccess();
733     mDataLoader->initializeCreateOkNoStatus();
734     mDataLoaderManager->bindToDataLoaderSuccess();
735     mDataLoaderManager->getDataLoaderSuccess();
736     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
737     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
738     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
739     EXPECT_CALL(*mDataLoader, start(_)).Times(0);
740     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
741     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
742     TemporaryDir tempDir;
743     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
744                                                        IncrementalService::CreateOptions::CreateNew,
745                                                        {}, {}, {});
746     ASSERT_GE(storageId, 0);
747     mDataLoaderManager->setDataLoaderStatusUnavailable();
748 }
749 
TEST_F(IncrementalServiceTest,testStartDataLoaderRecreateOnPendingReads)750 TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
751     mVold->mountIncFsSuccess();
752     mIncFs->makeFileSuccess();
753     mIncFs->openMountSuccess();
754     mIncFs->waitForPendingReadsSuccess();
755     mVold->bindMountSuccess();
756     mDataLoader->initializeCreateOkNoStatus();
757     mDataLoaderManager->bindToDataLoaderSuccess();
758     mDataLoaderManager->getDataLoaderSuccess();
759     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
760     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
761     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
762     EXPECT_CALL(*mDataLoader, start(_)).Times(0);
763     EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
764     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
765     EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
766     EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
767     TemporaryDir tempDir;
768     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
769                                                        IncrementalService::CreateOptions::CreateNew,
770                                                        {}, {}, {});
771     ASSERT_GE(storageId, 0);
772     mDataLoaderManager->setDataLoaderStatusUnavailable();
773     ASSERT_NE(nullptr, mLooper->mCallback);
774     ASSERT_NE(nullptr, mLooper->mCallbackData);
775     mLooper->mCallback(-1, -1, mLooper->mCallbackData);
776 }
777 
TEST_F(IncrementalServiceTest,testStartDataLoaderUnhealthyStorage)778 TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
779     mVold->mountIncFsSuccess();
780     mIncFs->makeFileSuccess();
781     mIncFs->openMountSuccess();
782     mVold->bindMountSuccess();
783     mDataLoaderManager->bindToDataLoaderSuccess();
784     mDataLoaderManager->getDataLoaderSuccess();
785     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
786     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
787     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
788     EXPECT_CALL(*mDataLoader, start(_)).Times(1);
789     EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
790     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
791     EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
792     EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
793     EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
794 
795     sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
796     NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
797     EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
798             .Times(2);
799     EXPECT_CALL(*listenerMock,
800                 onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
801             .Times(1);
802     EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
803             .Times(1);
804     EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
805             .Times(2);
806 
807     StorageHealthCheckParams params;
808     params.blockedTimeoutMs = 10000;
809     params.unhealthyTimeoutMs = 20000;
810     params.unhealthyMonitoringMs = 30000;
811 
812     using MS = std::chrono::milliseconds;
813     using MCS = std::chrono::microseconds;
814 
815     const auto blockedTimeout = MS(params.blockedTimeoutMs);
816     const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
817     const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);
818 
819     const uint64_t kFirstTimestampUs = 1000000000ll;
820     const uint64_t kBlockedTimestampUs =
821             kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
822     const uint64_t kUnhealthyTimestampUs =
823             kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();
824 
825     TemporaryDir tempDir;
826     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
827                                                        IncrementalService::CreateOptions::CreateNew,
828                                                        {}, std::move(params), listener);
829     ASSERT_GE(storageId, 0);
830 
831     // Healthy state, registered for pending reads.
832     ASSERT_NE(nullptr, mLooper->mCallback);
833     ASSERT_NE(nullptr, mLooper->mCallbackData);
834     ASSERT_EQ(storageId, listener->mStorageId);
835     ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
836 
837     // Looper/epoll callback.
838     mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
839     mLooper->mCallback(-1, -1, mLooper->mCallbackData);
840 
841     // Unregister from pending reads and wait.
842     ASSERT_EQ(nullptr, mLooper->mCallback);
843     ASSERT_EQ(nullptr, mLooper->mCallbackData);
844     ASSERT_EQ(storageId, listener->mStorageId);
845     ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
846     // Timed callback present.
847     ASSERT_EQ(storageId, mTimedQueue->mId);
848     ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
849     auto timedCallback = mTimedQueue->mWhat;
850     mTimedQueue->clearJob(storageId);
851 
852     // Timed job callback for blocked.
853     mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
854     timedCallback();
855 
856     // Still not registered, and blocked.
857     ASSERT_EQ(nullptr, mLooper->mCallback);
858     ASSERT_EQ(nullptr, mLooper->mCallbackData);
859     ASSERT_EQ(storageId, listener->mStorageId);
860     ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
861     // Timed callback present.
862     ASSERT_EQ(storageId, mTimedQueue->mId);
863     ASSERT_GE(mTimedQueue->mAfter, 1000ms);
864     timedCallback = mTimedQueue->mWhat;
865     mTimedQueue->clearJob(storageId);
866 
867     // Timed job callback for unhealthy.
868     mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
869     timedCallback();
870 
871     // Still not registered, and blocked.
872     ASSERT_EQ(nullptr, mLooper->mCallback);
873     ASSERT_EQ(nullptr, mLooper->mCallbackData);
874     ASSERT_EQ(storageId, listener->mStorageId);
875     ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
876     // Timed callback present.
877     ASSERT_EQ(storageId, mTimedQueue->mId);
878     ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
879     timedCallback = mTimedQueue->mWhat;
880     mTimedQueue->clearJob(storageId);
881 
882     // One more unhealthy.
883     mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
884     timedCallback();
885 
886     // Still not registered, and blocked.
887     ASSERT_EQ(nullptr, mLooper->mCallback);
888     ASSERT_EQ(nullptr, mLooper->mCallbackData);
889     ASSERT_EQ(storageId, listener->mStorageId);
890     ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
891     // Timed callback present.
892     ASSERT_EQ(storageId, mTimedQueue->mId);
893     ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
894     timedCallback = mTimedQueue->mWhat;
895     mTimedQueue->clearJob(storageId);
896 
897     // And now healthy.
898     mIncFs->waitForPendingReadsTimeout();
899     timedCallback();
900 
901     // Healthy state, registered for pending reads.
902     ASSERT_NE(nullptr, mLooper->mCallback);
903     ASSERT_NE(nullptr, mLooper->mCallbackData);
904     ASSERT_EQ(storageId, listener->mStorageId);
905     ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
906 }
907 
TEST_F(IncrementalServiceTest,testSetIncFsMountOptionsSuccess)908 TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
909     mVold->mountIncFsSuccess();
910     mIncFs->makeFileSuccess();
911     mVold->bindMountSuccess();
912     mVold->setIncFsMountOptionsSuccess();
913     mDataLoaderManager->bindToDataLoaderSuccess();
914     mDataLoaderManager->getDataLoaderSuccess();
915     mAppOpsManager->checkPermissionSuccess();
916     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
917     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
918     // We are calling setIncFsMountOptions(true).
919     EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
920     // After setIncFsMountOptions succeeded expecting to start watching.
921     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
922     // Not expecting callback removal.
923     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
924     TemporaryDir tempDir;
925     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
926                                                        IncrementalService::CreateOptions::CreateNew,
927                                                        {}, {}, {});
928     ASSERT_GE(storageId, 0);
929     ASSERT_GE(mDataLoader->setStorageParams(true), 0);
930 }
931 
TEST_F(IncrementalServiceTest,testSetIncFsMountOptionsSuccessAndDisabled)932 TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
933     mVold->mountIncFsSuccess();
934     mIncFs->makeFileSuccess();
935     mVold->bindMountSuccess();
936     mVold->setIncFsMountOptionsSuccess();
937     mDataLoaderManager->bindToDataLoaderSuccess();
938     mDataLoaderManager->getDataLoaderSuccess();
939     mAppOpsManager->checkPermissionSuccess();
940     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
941     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
942     // Enabling and then disabling readlogs.
943     EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
944     EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
945     // After setIncFsMountOptions succeeded expecting to start watching.
946     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
947     // Not expecting callback removal.
948     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
949     TemporaryDir tempDir;
950     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
951                                                        IncrementalService::CreateOptions::CreateNew,
952                                                        {}, {}, {});
953     ASSERT_GE(storageId, 0);
954     ASSERT_GE(mDataLoader->setStorageParams(true), 0);
955     // Now disable.
956     mIncrementalService->disableReadLogs(storageId);
957     ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
958 }
959 
TEST_F(IncrementalServiceTest,testSetIncFsMountOptionsSuccessAndPermissionChanged)960 TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
961     mVold->mountIncFsSuccess();
962     mIncFs->makeFileSuccess();
963     mVold->bindMountSuccess();
964     mVold->setIncFsMountOptionsSuccess();
965     mDataLoaderManager->bindToDataLoaderSuccess();
966     mDataLoaderManager->getDataLoaderSuccess();
967     mAppOpsManager->checkPermissionSuccess();
968     mAppOpsManager->initializeStartWatchingMode();
969     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
970     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
971     // We are calling setIncFsMountOptions(true).
972     EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
973     // setIncFsMountOptions(false) is called on the callback.
974     EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
975     // After setIncFsMountOptions succeeded expecting to start watching.
976     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
977     // After callback is called, disable read logs and remove callback.
978     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
979     TemporaryDir tempDir;
980     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
981                                                        IncrementalService::CreateOptions::CreateNew,
982                                                        {}, {}, {});
983     ASSERT_GE(storageId, 0);
984     ASSERT_GE(mDataLoader->setStorageParams(true), 0);
985     ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
986     mAppOpsManager->mStoredCallback->opChanged(0, {});
987 }
988 
TEST_F(IncrementalServiceTest,testSetIncFsMountOptionsCheckPermissionFails)989 TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
990     mVold->mountIncFsSuccess();
991     mIncFs->makeFileSuccess();
992     mVold->bindMountSuccess();
993     mDataLoaderManager->bindToDataLoaderSuccess();
994     mDataLoaderManager->getDataLoaderSuccess();
995     mAppOpsManager->checkPermissionFails();
996     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
997     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
998     // checkPermission fails, no calls to set opitions,  start or stop WatchingMode.
999     EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(0);
1000     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1001     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1002     TemporaryDir tempDir;
1003     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1004                                                        IncrementalService::CreateOptions::CreateNew,
1005                                                        {}, {}, {});
1006     ASSERT_GE(storageId, 0);
1007     ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1008 }
1009 
TEST_F(IncrementalServiceTest,testSetIncFsMountOptionsFails)1010 TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
1011     mVold->mountIncFsSuccess();
1012     mIncFs->makeFileSuccess();
1013     mVold->bindMountSuccess();
1014     mVold->setIncFsMountOptionsFails();
1015     mDataLoaderManager->bindToDataLoaderSuccess();
1016     mDataLoaderManager->getDataLoaderSuccess();
1017     mAppOpsManager->checkPermissionSuccess();
1018     EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
1019     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
1020     // We are calling setIncFsMountOptions.
1021     EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(1);
1022     // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
1023     EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
1024     EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
1025     TemporaryDir tempDir;
1026     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1027                                                        IncrementalService::CreateOptions::CreateNew,
1028                                                        {}, {}, {});
1029     ASSERT_GE(storageId, 0);
1030     ASSERT_LT(mDataLoader->setStorageParams(true), 0);
1031 }
1032 
TEST_F(IncrementalServiceTest,testMakeDirectory)1033 TEST_F(IncrementalServiceTest, testMakeDirectory) {
1034     mVold->mountIncFsSuccess();
1035     mIncFs->makeFileSuccess();
1036     mVold->bindMountSuccess();
1037     mDataLoaderManager->bindToDataLoaderSuccess();
1038     mDataLoaderManager->getDataLoaderSuccess();
1039     TemporaryDir tempDir;
1040     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1041                                                        IncrementalService::CreateOptions::CreateNew,
1042                                                        {}, {}, {});
1043     std::string dir_path("test");
1044 
1045     // Expecting incfs to call makeDir on a path like:
1046     // <root>/*/mount/<storage>/test
1047     EXPECT_CALL(*mIncFs,
1048                 makeDir(_, Truly([&](std::string_view arg) {
1049                             return arg.starts_with(mRootDir.path) &&
1050                                     arg.ends_with("/mount/st_1_0/" + dir_path);
1051                         }),
1052                         _));
1053     auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
1054     ASSERT_EQ(res, 0);
1055 }
1056 
TEST_F(IncrementalServiceTest,testMakeDirectories)1057 TEST_F(IncrementalServiceTest, testMakeDirectories) {
1058     mVold->mountIncFsSuccess();
1059     mIncFs->makeFileSuccess();
1060     mVold->bindMountSuccess();
1061     mDataLoaderManager->bindToDataLoaderSuccess();
1062     mDataLoaderManager->getDataLoaderSuccess();
1063     TemporaryDir tempDir;
1064     int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
1065                                                        IncrementalService::CreateOptions::CreateNew,
1066                                                        {}, {}, {});
1067     auto first = "first"sv;
1068     auto second = "second"sv;
1069     auto third = "third"sv;
1070     auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
1071 
1072     EXPECT_CALL(*mIncFs,
1073                 makeDirs(_, Truly([&](std::string_view arg) {
1074                              return arg.starts_with(mRootDir.path) &&
1075                                      arg.ends_with("/mount/st_1_0/" + dir_path);
1076                          }),
1077                          _));
1078     auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
1079     ASSERT_EQ(res, 0);
1080 }
1081 } // namespace android::os::incremental
1082