1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_FILEAPI_RECENT_ARC_MEDIA_SOURCE_H_
#define CHROME_BROWSER_ASH_FILEAPI_RECENT_ARC_MEDIA_SOURCE_H_
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <vector>
#include "base/containers/id_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h"
#include "chrome/browser/ash/fileapi/recent_source.h"
#include "chrome/browser/profiles/profile.h"
#include "chromeos/ash/experiences/arc/mojom/file_system.mojom.h"
class Profile;
namespace ash {
class RecentFile;
// RecentSource implementation for ARC media view. This class is not designed to
// be used by itself. Instead, it is instantiated and used by the RecentModel to
// retrieve recent files from ARC media view.
//
// All member functions must be called on the UI thread.
class RecentArcMediaSource : public RecentSource {
public:
// Creates a recent file sources that scans Arc media. The `profile` is used
// to arc::ArcFileSystemOperationRunner and arc::ArcDocumentsProviderRootMap
// for retrieving recent files and scanning ARC directories, respectively. The
// `root_id` must be one of the know ARC root IDs, denoting Documents, Videos,
// Images or Audio roots.
RecentArcMediaSource(Profile* profile, const std::string& root_id);
RecentArcMediaSource(const RecentArcMediaSource&) = delete;
RecentArcMediaSource& operator=(const RecentArcMediaSource&) = delete;
~RecentArcMediaSource() override;
// Overrides the base class method to launch searches for recent file in the
// root identified by the `root_id` parameter given at the construction time.
void GetRecentFiles(const Params& params,
GetRecentFilesCallback callback) override;
// Overrides the base class Stop method to return partial results collected
// before the timeout call. This method must be called on the UI thread.
std::vector<RecentFile> Stop(const int32_t call_id) override;
// Causes laggy performance for this source. This is to be only used in tests.
void SetLagForTesting(const base::TimeDelta& lag);
// The name of the metric under which recent file access statistics for ARC
// are recorded.
static const char kLoadHistogramName[];
private:
// Call context stores information specific to a single GetRecentFiles call.
// If multiple calls are issued each will have its own context.
struct CallContext {
CallContext(const Params& params, GetRecentFilesCallback callback);
// Move constructor needed as callback cannot be copied.
CallContext(CallContext&& context);
~CallContext();
// The parameters of the GetRecentFiles call.
const Params params;
// The callback to be called once all files are gathered. We do not know
// ahead of time when this may be the case, due to nested directories.
// Thus this class behaves similarly to a Barrier class, except that the
// number of times the barrier has to be called varies.
GetRecentFilesCallback callback;
// Time when this call started.
base::TimeTicks build_start_time;
// Number of in-flight ReadDirectory() calls by ScanDirectory().
int num_inflight_readdirs = 0;
// Maps a document ID to a RecentFile. In OnGotRecentDocuments(), this map
// is initialized with document IDs returned by GetRecentDocuments(), and
// its values are filled as we scan the tree in ScanDirectory().
// In case of multiple files with the same document ID found, the file with
// lexicographically smallest URL is kept. A nullopt value means the
// corresponding file is not (yet) found.
std::map<std::string, std::optional<RecentFile>> document_id_to_file;
};
// Returns whether or not this scanner supports files with the given type.
bool MatchesFileType(FileType file_type) const;
// Extra method that allows us to insert an optional lag between the runner
// being done and the OnGotRecentDocuments being called.
void OnRunnerDone(
const int32_t call_id,
std::optional<std::vector<arc::mojom::DocumentPtr>> maybe_documents);
// The method called once recent document pointers have been retrieved. This
// may take place immediately after the runner was done, or with a small lag
// that helps testing the interaction with the Stop method.
void OnGotRecentDocuments(
const int32_t call_id,
std::optional<std::vector<arc::mojom::DocumentPtr>> maybe_documents);
// Starts scanning of the directory with the given path.
void ScanDirectory(const int32_t call_id, const base::FilePath& path);
// The method called once a scan of directory is completed.
void OnDirectoryRead(
const int32_t call_id,
const base::FilePath& path,
base::File::Error result,
std::vector<arc::ArcDocumentsProviderRoot::ThinFileInfo> files);
// Invoked once traversing of the directory hirerachy is finished.
void OnComplete(const int32_t call_id);
// Creates a complete FileSystemURL for the given `path`, with the
// help of `relative_mount_path_`.
storage::FileSystemURL BuildDocumentsProviderUrl(
const Params& params,
const base::FilePath& path) const;
bool WillArcFileSystemOperationsRunImmediately();
// A map from the call ID to the call context.
base::IDMap<std::unique_ptr<CallContext>> context_map_;
// The profile for which this recent source was created.
const raw_ptr<Profile> profile_;
// The ARC root, such as Documents, Images, Media or Audio.
const std::string root_id_;
// The path at which the given ARC system is mounted.
const base::FilePath relative_mount_path_;
// The artificial lag introduced to this root for test purposes.
base::TimeDelta lag_;
// Timer; only allocated if the lag is positive.
std::unique_ptr<base::OneShotTimer> timer_;
base::WeakPtrFactory<RecentArcMediaSource> weak_ptr_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_FILEAPI_RECENT_ARC_MEDIA_SOURCE_H_
|