1 // 2 // Copyright (C) 2013 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 #ifndef UPDATE_ENGINE_P2P_MANAGER_H_ 18 #define UPDATE_ENGINE_P2P_MANAGER_H_ 19 20 #include <string> 21 #include <vector> 22 23 #include <base/callback.h> 24 #include <base/files/file_path.h> 25 #include <base/memory/ref_counted.h> 26 #include <base/time/time.h> 27 #include <policy/device_policy.h> 28 #include <policy/libpolicy.h> 29 30 #include "update_engine/common/clock_interface.h" 31 #include "update_engine/common/prefs_interface.h" 32 #include "update_engine/update_manager/update_manager.h" 33 34 namespace chromeos_update_engine { 35 36 // Interface for sharing and discovering files via p2p. 37 class P2PManager { 38 public: 39 // Interface used for P2PManager implementations. The sole reason 40 // for this interface is unit testing. 41 class Configuration { 42 public: ~Configuration()43 virtual ~Configuration() {} 44 45 // Gets the path to the p2p dir being used, e.g. /var/cache/p2p. 46 virtual base::FilePath GetP2PDir() = 0; 47 48 // Gets the argument vector for starting (if |is_start| is True) 49 // resp. stopping (if |is_start| is False) the p2p service 50 // e.g. ["initctl", "start", "p2p"] or ["initctl", "stop", "p2p"]. 51 virtual std::vector<std::string> GetInitctlArgs(bool is_start) = 0; 52 53 // Gets the argument vector for invoking p2p-client, e.g. 54 // "p2p-client --get-url=file_id_we_want --minimum-size=42123". 55 virtual std::vector<std::string> GetP2PClientArgs( 56 const std::string& file_id, size_t minimum_size) = 0; 57 }; 58 ~P2PManager()59 virtual ~P2PManager() {} 60 61 // The type for the callback used in LookupUrlForFile(). 62 // If the lookup failed, |url| is empty. 63 typedef base::Callback<void(const std::string& url)> LookupCallback; 64 65 // Use the device policy specified by |device_policy|. If this is 66 // null, then no device policy is used. 67 virtual void SetDevicePolicy(const policy::DevicePolicy* device_policy) = 0; 68 69 // Returns true iff P2P is currently allowed for use on this device. This 70 // value is determined and maintained by the Update Manager. 71 virtual bool IsP2PEnabled() = 0; 72 73 // Ensures that the p2p subsystem is running (e.g. starts it if it's 74 // not already running) and blocks until this is so. Returns false 75 // if an error occurred. 76 virtual bool EnsureP2PRunning() = 0; 77 78 // Ensures that the p2p subsystem is not running (e.g. stops it if 79 // it's running) and blocks until this is so. Returns false if an 80 // error occurred. 81 virtual bool EnsureP2PNotRunning() = 0; 82 83 // Cleans up files in /var/cache/p2p owned by this application as 84 // per the |file_extension| and |num_files_to_keep| values passed 85 // when the object was constructed. This may be called even if 86 // the p2p subsystem is not running. 87 virtual bool PerformHousekeeping() = 0; 88 89 // Asynchronously finds a peer that serves the file identified by 90 // |file_id|. If |minimum_size| is non-zero, will find a peer that 91 // has at least that many bytes. When the result is ready |callback| 92 // is called from the current message loop. 93 // 94 // This operation may take a very long time to complete because part 95 // of the p2p protocol involves waiting for the LAN-wide sum of all 96 // num-connections to drop below a given threshold. However, if 97 // |max_time_to_wait| is non-zero, the operation is guaranteed to 98 // not exceed this duration. 99 // 100 // If the file is not available on the LAN (or if mDNS/DNS-SD is 101 // filtered), this is guaranteed to not take longer than 5 seconds. 102 virtual void LookupUrlForFile(const std::string& file_id, 103 size_t minimum_size, 104 base::TimeDelta max_time_to_wait, 105 LookupCallback callback) = 0; 106 107 // Shares a file identified by |file_id| in the directory 108 // /var/cache/p2p. Initially the file will not be visible, that is, 109 // it will have a .tmp extension and not be shared via p2p. Use the 110 // FileMakeVisible() method to change this. 111 // 112 // If you know the final size of the file, pass it in the 113 // |expected_size| parameter. Otherwise pass zero. If non-zero, the 114 // amount of free space in /var/cache/p2p is checked and if there is 115 // less than twice the amount of space available, this method 116 // fails. Additionally, disk space will be reserved via fallocate(2) 117 // and |expected_size| is written to the user.cros-p2p-filesize 118 // xattr of the created file. 119 // 120 // If the file already exists, true is returned. Any on-disk xattr 121 // is not updated. 122 virtual bool FileShare(const std::string& file_id, 123 size_t expected_size) = 0; 124 125 // Gets a fully qualified path for the file identified by |file_id|. 126 // If the file has not been shared already using the FileShare() 127 // method, an empty base::FilePath is returned - use FilePath::empty() to 128 // find out. 129 virtual base::FilePath FileGetPath(const std::string& file_id) = 0; 130 131 // Gets the actual size of the file identified by |file_id|. This is 132 // equivalent to reading the value of the st_size field of the 133 // struct stat on the file given by FileGetPath(). Returns -1 if an 134 // error occurs. 135 // 136 // For a file just created with FileShare() this will return 0. 137 virtual ssize_t FileGetSize(const std::string& file_id) = 0; 138 139 // Gets the expected size of the file identified by |file_id|. This 140 // is equivalent to reading the value of the user.cros-p2p-filesize 141 // xattr on the file given by FileGetPath(). Returns -1 if an error 142 // occurs. 143 // 144 // For a file just created with FileShare() this will return the 145 // value of the |expected_size| parameter passed to that method. 146 virtual ssize_t FileGetExpectedSize(const std::string& file_id) = 0; 147 148 // Gets whether the file identified by |file_id| is publicly 149 // visible. If |out_result| is not null, the result is returned 150 // there. Returns false if an error occurs. 151 virtual bool FileGetVisible(const std::string& file_id, 152 bool *out_result) = 0; 153 154 // Makes the file identified by |file_id| publicly visible 155 // (e.g. removes the .tmp extension). If the file is already 156 // visible, this method does nothing. Returns False if 157 // the method fails or there is no file for |file_id|. 158 virtual bool FileMakeVisible(const std::string& file_id) = 0; 159 160 // Counts the number of shared files used by this application 161 // (cf. the |file_extension parameter|. Returns -1 if an error 162 // occurred. 163 virtual int CountSharedFiles() = 0; 164 165 // Creates a suitable P2PManager instance and initializes the object 166 // so it's ready for use. The |file_extension| parameter is used to 167 // identify your application, use e.g. "cros_au". If 168 // |configuration| is non-null, the P2PManager will take ownership 169 // of the Configuration object and use it (hence, it must be 170 // heap-allocated). 171 // 172 // The |num_files_to_keep| parameter specifies how many files to 173 // keep after performing housekeeping (cf. the PerformHousekeeping() 174 // method) - pass zero to allow infinitely many files. The 175 // |max_file_age| parameter specifies the maximum file age after 176 // performing housekeeping (pass zero to allow files of any age). 177 static P2PManager* Construct( 178 Configuration *configuration, 179 ClockInterface *clock, 180 chromeos_update_manager::UpdateManager* update_manager, 181 const std::string& file_extension, 182 const int num_files_to_keep, 183 const base::TimeDelta& max_file_age); 184 }; 185 186 } // namespace chromeos_update_engine 187 188 #endif // UPDATE_ENGINE_P2P_MANAGER_H_ 189