1 /* 2 * Copyright (C) 2023 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 package com.android.providers.media.photopicker.sync; 18 19 import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_CLOUD_ONLY; 20 import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_LOCAL_AND_CLOUD; 21 import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_LOCAL_ONLY; 22 import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_MEDIA_GRANTS; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.VisibleForTesting; 26 27 import java.util.UUID; 28 29 /** 30 * This class stores all sync trackers. 31 */ 32 public class SyncTrackerRegistry { 33 private static SyncTracker sLocalSyncTracker = new SyncTracker(); 34 private static SyncTracker sLocalAlbumSyncTracker = new SyncTracker(); 35 private static SyncTracker sCloudSyncTracker = new SyncTracker(); 36 private static SyncTracker sCloudAlbumSyncTracker = new SyncTracker(); 37 private static SyncTracker sGrantsSyncTracker = new SyncTracker(); 38 private static SyncTracker sLocalSearchTracker = new SyncTracker(); 39 private static SyncTracker sCloudSearchTracker = new SyncTracker(); 40 private static SyncTracker sCloudMediaSetsSyncTracker = new SyncTracker(); 41 private static SyncTracker sLocalMediaSetsSyncTracker = new SyncTracker(); 42 private static SyncTracker sCloudMediaInMediaSetTracker = new SyncTracker(); 43 private static SyncTracker sLocalMediaInMediaSetTracker = new SyncTracker(); 44 getLocalSyncTracker()45 public static SyncTracker getLocalSyncTracker() { 46 return sLocalSyncTracker; 47 } 48 49 /** 50 * This setter is required to inject mock data for tests. Do not use this anywhere else. 51 */ 52 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setLocalSyncTracker(SyncTracker syncTracker)53 public static void setLocalSyncTracker(SyncTracker syncTracker) { 54 sLocalSyncTracker = syncTracker; 55 } 56 getLocalAlbumSyncTracker()57 public static SyncTracker getLocalAlbumSyncTracker() { 58 return sLocalAlbumSyncTracker; 59 } 60 61 /** 62 * This setter is required to inject mock data for tests. Do not use this anywhere else. 63 */ 64 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setLocalAlbumSyncTracker( SyncTracker localAlbumSyncTracker)65 public static void setLocalAlbumSyncTracker( 66 SyncTracker localAlbumSyncTracker) { 67 sLocalAlbumSyncTracker = localAlbumSyncTracker; 68 } 69 70 /** 71 * This setter is required to inject mock data for tests. Do not use this anywhere else. 72 */ 73 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setGrantsSyncTracker( SyncTracker grantsSyncTracker)74 public static void setGrantsSyncTracker( 75 SyncTracker grantsSyncTracker) { 76 sGrantsSyncTracker = grantsSyncTracker; 77 } 78 getCloudSyncTracker()79 public static SyncTracker getCloudSyncTracker() { 80 return sCloudSyncTracker; 81 } 82 83 /** 84 * This setter is required to inject mock data for tests. Do not use this anywhere else. 85 */ 86 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setCloudSyncTracker( SyncTracker cloudSyncTracker)87 public static void setCloudSyncTracker( 88 SyncTracker cloudSyncTracker) { 89 sCloudSyncTracker = cloudSyncTracker; 90 } 91 getCloudAlbumSyncTracker()92 public static SyncTracker getCloudAlbumSyncTracker() { 93 return sCloudAlbumSyncTracker; 94 } 95 96 /** 97 * This setter is required to inject mock data for tests. Do not use this anywhere else. 98 */ 99 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setCloudAlbumSyncTracker( SyncTracker cloudAlbumSyncTracker)100 public static void setCloudAlbumSyncTracker( 101 SyncTracker cloudAlbumSyncTracker) { 102 sCloudAlbumSyncTracker = cloudAlbumSyncTracker; 103 } 104 getGrantsSyncTracker()105 public static SyncTracker getGrantsSyncTracker() { 106 return sGrantsSyncTracker; 107 } 108 getLocalSearchSyncTracker()109 public static SyncTracker getLocalSearchSyncTracker() { 110 return sLocalSearchTracker; 111 } 112 113 /** 114 * This setter is required to inject mock data for tests. Do not use this anywhere else. 115 */ 116 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setLocalSearchSyncTracker( SyncTracker localSearchSyncTracker)117 public static void setLocalSearchSyncTracker( 118 SyncTracker localSearchSyncTracker) { 119 sLocalSearchTracker = localSearchSyncTracker; 120 } 121 getCloudSearchSyncTracker()122 public static SyncTracker getCloudSearchSyncTracker() { 123 return sCloudSearchTracker; 124 } 125 126 /** 127 * This setter is required to inject mock data for tests. Do not use this anywhere else. 128 */ 129 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setCloudSearchSyncTracker( SyncTracker cloudSearchSyncTracker)130 public static void setCloudSearchSyncTracker( 131 SyncTracker cloudSearchSyncTracker) { 132 sCloudSearchTracker = cloudSearchSyncTracker; 133 } 134 135 getCloudMediaSetsSyncTracker()136 public static SyncTracker getCloudMediaSetsSyncTracker() { 137 return sCloudMediaSetsSyncTracker; 138 } 139 getLocalMediaSetsSyncTracker()140 public static SyncTracker getLocalMediaSetsSyncTracker() { 141 return sLocalMediaSetsSyncTracker; 142 } 143 144 145 /* 146 Required for testing. Not to be used anywhere else 147 */ 148 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setCloudMediaSetsSyncTracker(SyncTracker cloudMediaSetsSyncTracker)149 public static void setCloudMediaSetsSyncTracker(SyncTracker cloudMediaSetsSyncTracker) { 150 sCloudMediaSetsSyncTracker = cloudMediaSetsSyncTracker; 151 } 152 153 /* 154 Required for testing. Not to be used anywhere else 155 */ 156 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setLocalMediaSetsSyncTracker(SyncTracker localMediaSetsSyncTracker)157 public static void setLocalMediaSetsSyncTracker(SyncTracker localMediaSetsSyncTracker) { 158 sLocalMediaSetsSyncTracker = localMediaSetsSyncTracker; 159 } 160 getCloudMediaInMediaSetTracker()161 public static SyncTracker getCloudMediaInMediaSetTracker() { 162 return sCloudMediaInMediaSetTracker; 163 } 164 getLocalMediaInMediaSetTracker()165 public static SyncTracker getLocalMediaInMediaSetTracker() { 166 return sLocalMediaInMediaSetTracker; 167 } 168 169 /* 170 Only to be used for tests and nowhere else 171 */ 172 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setCloudMediaInMediaSetTracker( SyncTracker cloudMediaInMediaSetTracker)173 public static void setCloudMediaInMediaSetTracker( 174 SyncTracker cloudMediaInMediaSetTracker) { 175 sCloudMediaInMediaSetTracker = cloudMediaInMediaSetTracker; 176 } 177 178 /* 179 Only to be used for tests and nowhere else 180 */ 181 @VisibleForTesting(otherwise = VisibleForTesting.NONE) setLocalMediaInMediaSetTracker( SyncTracker localMediaInMediaSetTracker)182 public static void setLocalMediaInMediaSetTracker( 183 SyncTracker localMediaInMediaSetTracker) { 184 sLocalMediaInMediaSetTracker = localMediaInMediaSetTracker; 185 } 186 187 /** 188 * Return the appropriate sync tracker. 189 * @param isLocal is true when sync with local provider needs to be tracked. It is false for 190 * sync with cloud provider. 191 * @return the appropriate {@link SyncTracker} object. 192 */ getSyncTracker(boolean isLocal)193 public static SyncTracker getSyncTracker(boolean isLocal) { 194 if (isLocal) { 195 return sLocalSyncTracker; 196 } else { 197 return sCloudSyncTracker; 198 } 199 } 200 201 /** 202 * Return the appropriate album sync tracker. 203 * @param isLocal is true when sync with local provider needs to be tracked. It is false for 204 * sync with cloud provider. 205 * @return the appropriate {@link SyncTracker} object. 206 */ getAlbumSyncTracker(boolean isLocal)207 public static SyncTracker getAlbumSyncTracker(boolean isLocal) { 208 if (isLocal) { 209 return sLocalAlbumSyncTracker; 210 } else { 211 return sCloudAlbumSyncTracker; 212 } 213 } 214 215 /** 216 * Create the required completable futures for new media sync requests that need to be tracked. 217 */ trackNewSyncRequests( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)218 public static void trackNewSyncRequests( 219 @PickerSyncManager.SyncSource int syncSource, 220 @NonNull UUID syncRequestId) { 221 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 222 getLocalSyncTracker().createSyncFuture(syncRequestId); 223 } 224 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 225 getCloudSyncTracker().createSyncFuture(syncRequestId); 226 } 227 if (syncSource == SYNC_MEDIA_GRANTS) { 228 getGrantsSyncTracker().createSyncFuture(syncRequestId); 229 } 230 } 231 232 /** 233 * Create the required completable futures for new album media sync requests that need to be 234 * tracked. 235 */ trackNewAlbumMediaSyncRequests( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)236 public static void trackNewAlbumMediaSyncRequests( 237 @PickerSyncManager.SyncSource int syncSource, 238 @NonNull UUID syncRequestId) { 239 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 240 getLocalAlbumSyncTracker().createSyncFuture(syncRequestId); 241 } 242 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 243 getCloudAlbumSyncTracker().createSyncFuture(syncRequestId); 244 } 245 } 246 247 /** 248 * Create the required completable futures for new search result sync requests that need to be 249 * tracked. 250 */ trackNewSearchResultsSyncRequests( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)251 public static void trackNewSearchResultsSyncRequests( 252 @PickerSyncManager.SyncSource int syncSource, 253 @NonNull UUID syncRequestId) { 254 switch (syncSource) { 255 case SYNC_LOCAL_ONLY: 256 getLocalSearchSyncTracker().createSyncFuture(syncRequestId); 257 break; 258 case SYNC_CLOUD_ONLY: 259 getCloudSearchSyncTracker().createSyncFuture(syncRequestId); 260 break; 261 default: 262 getLocalSearchSyncTracker().createSyncFuture(syncRequestId); 263 getCloudSearchSyncTracker().createSyncFuture(syncRequestId); 264 break; 265 } 266 } 267 268 /** 269 * Create the required completable futures to track a new media sets sync request 270 */ trackNewMediaSetsSyncRequest( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)271 public static void trackNewMediaSetsSyncRequest( 272 @PickerSyncManager.SyncSource int syncSource, 273 @NonNull UUID syncRequestId) { 274 switch (syncSource) { 275 case SYNC_LOCAL_ONLY: 276 getLocalMediaSetsSyncTracker().createSyncFuture(syncRequestId); 277 break; 278 case SYNC_CLOUD_ONLY: 279 getCloudMediaSetsSyncTracker().createSyncFuture(syncRequestId); 280 break; 281 default: 282 getLocalMediaSetsSyncTracker().createSyncFuture(syncRequestId); 283 getCloudMediaSetsSyncTracker().createSyncFuture(syncRequestId); 284 break; 285 } 286 } 287 288 /** 289 * Create the required completable futures to track a new media in media set sync request 290 */ trackNewMediaInMediaSetSyncRequest( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)291 public static void trackNewMediaInMediaSetSyncRequest( 292 @PickerSyncManager.SyncSource int syncSource, 293 @NonNull UUID syncRequestId) { 294 switch (syncSource) { 295 case SYNC_LOCAL_ONLY: 296 getLocalMediaInMediaSetTracker().createSyncFuture(syncRequestId); 297 break; 298 case SYNC_CLOUD_ONLY: 299 getCloudMediaInMediaSetTracker().createSyncFuture(syncRequestId); 300 break; 301 default: 302 getLocalMediaInMediaSetTracker().createSyncFuture(syncRequestId); 303 getCloudMediaInMediaSetTracker().createSyncFuture(syncRequestId); 304 break; 305 } 306 } 307 308 /** 309 * Mark the required futures as complete for existing media sync requests. 310 */ markSyncAsComplete( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)311 public static void markSyncAsComplete( 312 @PickerSyncManager.SyncSource int syncSource, 313 @NonNull UUID syncRequestId) { 314 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 315 getLocalSyncTracker().markSyncCompleted(syncRequestId); 316 } 317 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 318 getCloudSyncTracker().markSyncCompleted(syncRequestId); 319 } 320 if (syncSource == SYNC_MEDIA_GRANTS) { 321 getGrantsSyncTracker().markSyncCompleted(syncRequestId); 322 } 323 } 324 325 /** 326 * Mark the required futures as complete for existing album media sync requests. 327 */ markAlbumMediaSyncAsComplete( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)328 public static void markAlbumMediaSyncAsComplete( 329 @PickerSyncManager.SyncSource int syncSource, 330 @NonNull UUID syncRequestId) { 331 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 332 getLocalAlbumSyncTracker().markSyncCompleted(syncRequestId); 333 } 334 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 335 getCloudAlbumSyncTracker().markSyncCompleted(syncRequestId); 336 } 337 } 338 339 /** 340 * Mark the required futures as complete for existing search result sync requests. 341 */ markSearchResultsSyncAsComplete( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)342 public static void markSearchResultsSyncAsComplete( 343 @PickerSyncManager.SyncSource int syncSource, 344 @NonNull UUID syncRequestId) { 345 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 346 getLocalSearchSyncTracker().markSyncCompleted(syncRequestId); 347 } 348 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 349 getCloudSearchSyncTracker().markSyncCompleted(syncRequestId); 350 } 351 } 352 353 /** 354 * Mark all the pending futures as complete. 355 */ markAllSearchResultsSyncAsComplete( @ickerSyncManager.SyncSource int syncSource)356 public static void markAllSearchResultsSyncAsComplete( 357 @PickerSyncManager.SyncSource int syncSource) { 358 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 359 getLocalSearchSyncTracker().markAllSyncsCompleted(); 360 } 361 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 362 getCloudSearchSyncTracker().markAllSyncsCompleted(); 363 } 364 } 365 366 /** 367 * Mark the required futures as complete for existing media set sync requests. 368 */ markMediaSetsSyncAsComplete( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)369 public static void markMediaSetsSyncAsComplete( 370 @PickerSyncManager.SyncSource int syncSource, 371 @NonNull UUID syncRequestId) { 372 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 373 getLocalMediaSetsSyncTracker().markSyncCompleted(syncRequestId); 374 } 375 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 376 getCloudMediaSetsSyncTracker().markSyncCompleted(syncRequestId); 377 } 378 } 379 380 /** 381 * Mark the required futures as complete for existing media in media set sync requests. 382 */ markMediaInMediaSetSyncAsComplete( @ickerSyncManager.SyncSource int syncSource, @NonNull UUID syncRequestId)383 public static void markMediaInMediaSetSyncAsComplete( 384 @PickerSyncManager.SyncSource int syncSource, 385 @NonNull UUID syncRequestId) { 386 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 387 getLocalMediaInMediaSetTracker().markSyncCompleted(syncRequestId); 388 } 389 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 390 getCloudMediaInMediaSetTracker().markSyncCompleted(syncRequestId); 391 } 392 } 393 394 /** 395 * Mark all media in media sets sync pending futures as complete 396 */ markAllMediaInMediaSetsSyncAsComplete( @ickerSyncManager.SyncSource int syncSource)397 public static void markAllMediaInMediaSetsSyncAsComplete( 398 @PickerSyncManager.SyncSource int syncSource) { 399 if (syncSource == SYNC_LOCAL_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 400 getLocalMediaInMediaSetTracker().markAllSyncsCompleted(); 401 } 402 if (syncSource == SYNC_CLOUD_ONLY || syncSource == SYNC_LOCAL_AND_CLOUD) { 403 getCloudMediaInMediaSetTracker().markAllSyncsCompleted(); 404 } 405 } 406 } 407