/* * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.libraries.mobiledatadownload; import com.google.android.libraries.mobiledatadownload.TaskScheduler.ConstraintOverrides; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CheckReturnValue; import com.google.mobiledatadownload.ClientConfigProto.ClientFileGroup; import com.google.mobiledatadownload.DownloadConfigProto.DataFileGroup; import java.util.Map; /** The root object and entry point for the MobileDataDownload library. */ public interface MobileDataDownload { /** * Adds for download the data file group in {@link AddFileGroupRequest}, after running validation * on the group. This group will replace any previous version of this group once it is downloaded. * *
This api takes {@link AddFileGroupRequest} that contains data file group, and it can be used * to set extra params such as account. * *
This doesn't start the download right away. The download starts later when the tasks * scheduled via {@link #schedulePeriodicTasks} are run. * *
Calling this api with the exact same parameters multiple times is a no-op.
*
* @param addFileGroupRequest The request to add file group in MDD.
* @return ListenableFuture of true if the group was successfully added, or the group was already
* present; ListenableFuture of false if the group is invalid or an I/O error occurs.
*/
ListenableFuture This api takes {@link RemoveFileGroupRequest} that contains data file group, and it can be
* used to set extra params such as account.
*
* @param removeFileGroupRequest The request to remove file group from MDD.
* @return Listenable of true if the group was successfully removed, or no group matches;
* Listenable of false if the matching group fails to be removed.
*/
ListenableFuture This api takes a {@link RemoveFileGroupsByFilterRequest} that contains optional filters for
* the group name, group source, associated account, etc.
*
* A resolved future will only be returned if the removal completes successfully for all
* matching file groups. If any failures occur during this method, it will return a failed future
* with an {@link AggregateException} containing the failures that occurred.
*
* NOTE: This only removes the metadata from MDD, not file content. Downloaded files that are
* no longer needed are deleted during MDD's daily maintenance task.
*
* @param removeFileGroupsByFilterRequest The request to remove file group from MDD.
* @return ListenableFuture that resolves with {@link RemoveFileGroupsByFilterResponse}, or fails
* with {@link AggregateException}
*/
ListenableFuture Only present fields in {@link ReadDataFileGroupsByFilterRequest} will be used to perform the
* filtering. For example, if no account is specified in the filter, file groups won't be filtered
* based on account.
*
* @param readDataFileGroupsByFilterRequest The request to get multiple data file groups after
* filtering.
* @return The ListenableFuture that will resolve to a list of the requested data file groups.
* This ListenableFuture will resolve to all data file groups when {@code
* readDataFileGroupsByFilterRequest.includeAllGroups} is true.
*/
default ListenableFuture This api takes an instance of {@link GetFileGroupRequest} that contains group name, and it
* can be used to set extra params such as account.
*
* This listenable future will return null if no group exists or has been downloaded for the
* given group name.
*
* Note: getFileGroup returns a snapshot of the latest state, but it's possible for the state
* to change between a getFileGroup call and accessing the files if the ClientFileGroup gets
* cached. Caching the returned ClientFileGroup is therefore discouraged.
*
* @param getFileGroupRequest The request to get a single file group.
* @return The ListenableFuture of requested client file group for the given request.
*/
ListenableFuture This listenable future will return a list of file groups with their current download status.
*
* Only present fields in {@link GetFileGroupsByFilterRequest} will be used to perform the
* filtering, i.e. when no account is specified in the filter, file groups won't be filtered based
* on account.
*
* Note: getFileGroupsByFilter returns a snapshot of the latest state, but it's possible for
* the state to change between a getFileGroupsByFilter call and accessing the files if the
* ClientFileGroup gets cached. Caching the returned ClientFileGroup is therefore discouraged.
*
* @param getFileGroupsByFilterRequest The request to get multiple file groups after filtering.
* @return The ListenableFuture that will resolve to a list of the requested client file groups,
* including pending and downloaded versions; this ListenableFuture will resolve to all client
* file groups when {@code getFileGroupsByFilterRequest.includeAllGroups} is true.
*/
ListenableFuture This api takes a {@link ImportFilesRequest} containing identifying information about an
* existing File Group, an optional list of {@link DataFile}s to import into the existing File
* Group, and a Map of file content to import into MDD.
*
* The identifying information is used to identify a file group and its specific version. This
* prevents the caller from accidentally importing files into the wrong file group or the wrong
* version of the file group. An optional {@link Account} parameter can also be specified if the
* existing file group was associated with an account.
*
* The given {@link DataFile} list allows updated files (still compatible with a given file
* group version) to be imported into MDD. This API wll merge the given DataFiles into the
* existing file group in the following manner:
*
* {@link ImportFilesRequest} also requires a Map of file sources that should be imported by
* MDD. The Map is keyed by the fileIds of DataFiles and contains the contents of the file to
* import within a {@link ByteString}. This Map must contains an entry for all {@link DataFile}s
* which require an inline file source. Only "Inline" {@link DataFile}s should be included in this
* map (see details below).
*
* An inline {@link DataFile} is the same as a standard {@link DataFile}, but instead of an
* "https" url, the url should match the following format:
*
* Where {@code key} is a unique identifier of the file. In most cases, the checksum should be
* used as this key. If the checksum is not used, another unique identifier should be used to
* allow proper deduping of the file import within MDD.
*
* Example inline file url:
*
* NOTE: Inline files can be specified by the given DataFile list in {@link
* ImportFilesRequest}, but can also be specified by a {@link DataFileGroup} added via {@link
* #addFileGroup}. A File Group that contains inline files will not be considered DOWNLOADED until
* all inline files are imported via this API.
*
* Because this method performs an update to the stored File Group metadata, the given {@link
* ImportFilesRequest} must satisfy the following conditions:
*
* If either of these conditions is not met, this operation will return a failed
* ListenableFuture.
*
* Finally, this API is a atomic operation. That is, either all inline files will be
* imported successfully or none will be imported. If there is a failure with importing a
* file, MDD will not update the file group (i.e. future calls to {@link #getFileGroup} will
* return the same {@link ClientFileGroup} as before this call).
*
* @param importFilesRequest Request containing required parameters to perform import files
* operation.
* @return ListenableFuture that resolves when all inline files are successfully imported.
*/
ListenableFuture This api takes {@link SingleFileDownloadRequest}, which contains a download url of the file
* to download. the destination location on device must also be specified. See
* SingleFileDownloadRequest for full list of required/optional parameters.
*
* The returned ListenableFuture will fail if there is an error during the download. The caller
* is responsible for calling downloadFile again to restart the download.
*
* The caller can be notified of progress by providing a {@link SingleFileDownloadListener}.
* This listener will also provide callbacks for a completed download, failed download, or paused
* download due to connectivity loss.
*
* The caller can specify constraints that should be used for the download by providing a
* {@link com.google.android.libraries.mobiledatadownload.downloader.DownloadConstraints}. This
* allows downloads to only start when on Wifi, for example. By default, no constraints are
* specified.
*
* @param singleFileDownloadRequest The request to download a file.
* @return ListenableFuture that resolves when file is downloaded.
*/
@CheckReturnValue
ListenableFuture This api takes {@link DownloadFileGroupRequest} that contains group name, and it can be used
* to set extra params such as account, download conditions, and download listener.
*
* The group name must be added using {@link #addFileGroup} before downloading the file group.
*
* The returned ListenableFuture will be resolved when the file group is downloaded. It can
* also be used to cancel the download.
*
* The returned ListenableFuture would fail if there is any error during the download. Client
* is responsible to call the downloadFileGroup to resume the download.
*
* Download progress is supported through the DownloadListener.
*
* To download under any conditions, clients should use {@link
* Constants.NO_RESTRICTIONS_DOWNLOAD_CONDITIONS}
*
* @param downloadFileGroupRequest The request to download file group.
*/
ListenableFuture This is similar to {@link #downloadFile}, but allows the download to continue running when
* the app enters the background.
*
* The notification created for the download includes a cancel action. This will allow the
* download to be cancelled even when the app is in the background.
*
* The cancel action in the notification menu requires the ForegroundService to be registered
* with the application (via the AndroidManifest.xml). This allows the cancellation intents to be
* properly picked up. To register the service, the following lines must be included in the app's
* {@code AndroidManifest.xml}:
*
* NOTE: The above excerpt is for Framework and Sting apps. Dagger apps should use the same
* excerpt, but change the {@code android:name} property to:
*
* The cancel action in the notification menu requires the ForegroundService to be registered
* with the application (via the AndroidManifest.xml). This allows the cancellation intents to be
* properly picked up. To register the service, the following lines must be included in the app's
* {@code AndroidManifest.xml}:
*
* NOTE: The above excerpt is for Framework and Sting apps. Dagger apps should use the same
* excerpt, but change the {@code android:name} property to:
*
* Attempts to cancel an on-going foreground download using best effort. If download is unknown
* to MDD, this operation is a noop.
*
* The key passed here must be created using {@link ForegroundDownloadKey}, and must match the
* properties used from the request. Depending on which API was used to start the download, this
* would be {@link DownloadFileGroupRequest} for {@link SingleFileDownloadRequest}.
*
* NOTE: In most cases, clients will not need to call this -- it is meant to allow the
* ForegroundDownloadService to cancel a download via the Cancel action registered to a
* notification.
*
* Clients should prefer to cancel the future returned to them from the download call.
*
* @param downloadKey the key associated with the download
*/
void cancelForegroundDownload(String downloadKey);
/**
* Triggers the execution of MDD maintenance.
*
* MDD needs to run maintenance task once a day. If you call {@link
* #schedulePeriodicBackgroundTasks} api, the maintenance will be called automatically. In case
* you don't want to schedule MDD tasks, you can call this maintenance method directly.
*
* If you do need to call this api, make sure that this api is called exactly once every day.
*
* The returned ListenableFuture would fail if the maintenance execution doesn't succeed.
*/
ListenableFuture By default, this is run as part of {@link #maintenance} so doesn't need to be invoked
* directly by client code. If you disabled that behavior via {@link
* Flags#mddEnableGarbageCollection} then this method should be periodically called to clean up
* unused files.
*/
ListenableFuture If the host app doesn't provide a TaskScheduler, calling this API will be a no-op.
*
* @deprecated Use the {@link schedulePeriodicBackgroundTasks} instead.
*/
@Deprecated
void schedulePeriodicTasks();
/**
* Schedule periodic background tasks that will download and verify all file groups when the
* required conditions are met, using the given {@link TaskScheduler}.
*
* If the host app doesn't provide a TaskScheduler, calling this API will be a no-op.
*/
ListenableFuture If the host app doesn't provide a TaskScheduler, calling this API will be a no-op.
*
* @param constraintOverridesMap to allow clients to override constraints requirements.
*
*
*
* {@code "inlinefile:
*
* {@code inlinefile:sha1:9a4ea3ca81d3f1d631531cbc216a62d9b10509ee}
*
*
*
*
* {@code
*
*
*
* {@code
* android:name="com.google.android.libraries.mobiledatadownload.foreground.dagger.ForegroundDownloadService"
* }
*/
@CheckReturnValue
ListenableFuture{@code
*
*
*
* {@code
* android:name="com.google.android.libraries.mobiledatadownload.foreground.dagger.ForegroundDownloadService"
* }
*/
ListenableFuture{@code
* ConstraintOverrides wifiOverrides =
* ConstraintOverrides.newBuilder()
* .setRequiresCharging(false)
* .setRequiresDeviceIdle(true)
* .build();
* ConstraintOverrides cellularOverrides =
* ConstraintOverrides.newBuilder()
* .setRequiresCharging(true)
* .setRequiresDeviceIdle(false)
* .build();
*
* Map
*/
ListenableFuture