Skip to content

Commit 29e73e5

Browse files
authored
Updating docs and enabling javadocs (#2405)
1 parent 6b44629 commit 29e73e5

File tree

8 files changed

+61
-34
lines changed

8 files changed

+61
-34
lines changed

firebase-ml-modeldownloader/api.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ package com.google.firebase.ml.modeldownloader {
4242
field public static final int MODEL_HASH_MISMATCH = 102; // 0x66
4343
field public static final int NOT_ENOUGH_SPACE = 101; // 0x65
4444
field public static final int NOT_FOUND = 5; // 0x5
45+
field public static final int NO_NETWORK_CONNECTION = 17; // 0x11
4546
field public static final int OUT_OF_RANGE = 11; // 0xb
4647
field public static final int PERMISSION_DENIED = 7; // 0x7
4748
field public static final int RESOURCE_EXHAUSTED = 8; // 0x8
@@ -51,7 +52,7 @@ package com.google.firebase.ml.modeldownloader {
5152
field public static final int UNKNOWN = 2; // 0x2
5253
}
5354

54-
@IntDef({com.google.firebase.ml.modeldownloader.FirebaseMlException.CANCELLED, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNKNOWN, com.google.firebase.ml.modeldownloader.FirebaseMlException.INVALID_ARGUMENT, com.google.firebase.ml.modeldownloader.FirebaseMlException.DEADLINE_EXCEEDED, com.google.firebase.ml.modeldownloader.FirebaseMlException.NOT_FOUND, com.google.firebase.ml.modeldownloader.FirebaseMlException.ALREADY_EXISTS, com.google.firebase.ml.modeldownloader.FirebaseMlException.PERMISSION_DENIED, com.google.firebase.ml.modeldownloader.FirebaseMlException.RESOURCE_EXHAUSTED, com.google.firebase.ml.modeldownloader.FirebaseMlException.FAILED_PRECONDITION, com.google.firebase.ml.modeldownloader.FirebaseMlException.ABORTED, com.google.firebase.ml.modeldownloader.FirebaseMlException.OUT_OF_RANGE, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNIMPLEMENTED, com.google.firebase.ml.modeldownloader.FirebaseMlException.INTERNAL, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNAVAILABLE, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNAUTHENTICATED, com.google.firebase.ml.modeldownloader.FirebaseMlException.NOT_ENOUGH_SPACE, com.google.firebase.ml.modeldownloader.FirebaseMlException.MODEL_HASH_MISMATCH, com.google.firebase.ml.modeldownloader.FirebaseMlException.DOWNLOAD_URL_EXPIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface FirebaseMlException.Code {
55+
@IntDef({com.google.firebase.ml.modeldownloader.FirebaseMlException.CANCELLED, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNKNOWN, com.google.firebase.ml.modeldownloader.FirebaseMlException.INVALID_ARGUMENT, com.google.firebase.ml.modeldownloader.FirebaseMlException.DEADLINE_EXCEEDED, com.google.firebase.ml.modeldownloader.FirebaseMlException.NOT_FOUND, com.google.firebase.ml.modeldownloader.FirebaseMlException.ALREADY_EXISTS, com.google.firebase.ml.modeldownloader.FirebaseMlException.PERMISSION_DENIED, com.google.firebase.ml.modeldownloader.FirebaseMlException.RESOURCE_EXHAUSTED, com.google.firebase.ml.modeldownloader.FirebaseMlException.FAILED_PRECONDITION, com.google.firebase.ml.modeldownloader.FirebaseMlException.ABORTED, com.google.firebase.ml.modeldownloader.FirebaseMlException.OUT_OF_RANGE, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNIMPLEMENTED, com.google.firebase.ml.modeldownloader.FirebaseMlException.INTERNAL, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNAVAILABLE, com.google.firebase.ml.modeldownloader.FirebaseMlException.UNAUTHENTICATED, com.google.firebase.ml.modeldownloader.FirebaseMlException.NO_NETWORK_CONNECTION, com.google.firebase.ml.modeldownloader.FirebaseMlException.NOT_ENOUGH_SPACE, com.google.firebase.ml.modeldownloader.FirebaseMlException.MODEL_HASH_MISMATCH, com.google.firebase.ml.modeldownloader.FirebaseMlException.DOWNLOAD_URL_EXPIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface FirebaseMlException.Code {
5556
}
5657

5758
public class FirebaseModelDownloader {

firebase-ml-modeldownloader/firebase-ml-modeldownloader.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ plugins {
1919

2020
firebaseLibrary {
2121
testLab.enabled = true
22-
publishJavadoc = false
22+
publishJavadoc = true
2323
}
2424

2525
protobuf {

firebase-ml-modeldownloader/src/main/java/com/google/firebase/ml/modeldownloader/FirebaseMlException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ public class FirebaseMlException extends FirebaseException {
9696
/** The request does not have valid authentication credentials for the operation. */
9797
public static final int UNAUTHENTICATED = 16;
9898

99+
/** There is no network connection. */
100+
public static final int NO_NETWORK_CONNECTION = 17;
101+
99102
// ===============================================================================================
100103
// Error codes: 100 to 149 reserved for errors during model downloading/loading.
101104
/** There is not enough space left on the device. */
@@ -131,6 +134,7 @@ public class FirebaseMlException extends FirebaseException {
131134
INTERNAL,
132135
UNAVAILABLE,
133136
UNAUTHENTICATED,
137+
NO_NETWORK_CONNECTION,
134138
NOT_ENOUGH_SPACE,
135139
MODEL_HASH_MISMATCH,
136140
DOWNLOAD_URL_EXPIRED

firebase-ml-modeldownloader/src/main/java/com/google/firebase/ml/modeldownloader/FirebaseModelDownloader.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ public static FirebaseModelDownloader getInstance(@NonNull FirebaseApp app) {
120120
* trigger new download, task only completes when download finishes
121121
* </ul>
122122
*
123+
* Most common exceptions include:
124+
*
125+
* <ul>
126+
* <li>{@link FirebaseMlException#NO_NETWORK_CONNECTION}: Error connecting to the network.
127+
* <li>{@link FirebaseMlException#NOT_FOUND}: No model found with the given name.
128+
* <li>{@link FirebaseMlException#NOT_ENOUGH_SPACE}: Not enough space on device to download
129+
* model.
130+
* <li>{@link FirebaseMlException#DOWNLOAD_URL_EXPIRED}: Url used to fetch model expired before
131+
* model download completed. (Rare: these calls are retried internally before being raised.)
132+
* </ul>
133+
*
123134
* @param modelName - model name
124135
* @param downloadType - download type
125136
* @param conditions - download conditions
@@ -422,11 +433,9 @@ private Task<CustomModel> finishModelDownload(@NonNull String modelName) {
422433
}
423434

424435
/**
425-
* Triggers the move to permanent storage of successful model downloads and lists all models
426-
* downloaded to device.
436+
* Lists all models downloaded to device.
427437
*
428-
* @return The set of all models that are downloaded to this device, triggers completion of file
429-
* moves for completed model downloads.
438+
* @return The set of all models that are downloaded to this device.
430439
*/
431440
@NonNull
432441
public Task<Set<CustomModel>> listDownloadedModels() {
@@ -440,7 +449,7 @@ public Task<Set<CustomModel>> listDownloadedModels() {
440449
}
441450

442451
/**
443-
* Delete old local models, when no longer in use.
452+
* Delete local model. Removes any information and files associated with the model name.
444453
*
445454
* @param modelName - name of the model
446455
*/
@@ -463,7 +472,15 @@ private void deleteModelDetails(@NonNull String modelName) {
463472
}
464473

465474
/**
466-
* Update the settings which allow logging to firelog.
475+
* Enables stats collection in Firebase Ml ModelDownloader via Firelog. The stats include API
476+
* calls counts, errors, API call durations, options, etc. No personally identifiable information
477+
* is logged.
478+
*
479+
* <p>The setting is per FirebaseApp, and it is persistent together with app's private data. It
480+
* means if the user uninstalls the app or clears all app data, the setting will be erased. The
481+
* best practice is to set the flag in each initialization.
482+
*
483+
* <p>By default the logging matches the Firebase wide data collection switch.
467484
*
468485
* @param enabled - is statistics logging enabled
469486
*/
@@ -475,17 +492,15 @@ public void setStatsCollectionEnabled(boolean enabled) {
475492
* Get the current models' download id (returns background download id when applicable). This id
476493
* can be used to create a progress bar to track file download progress.
477494
*
478-
* <p>If no model exists or there is no download in progress, return 0.
479-
*
480-
* <p>If 0 is returned immediately after starting a download via getModel, then
495+
* <p>[Preferred] If getModelTask is not null, then this task returns when the download id is not
496+
* 0 (download has been enqueued) or when the getModelTask completes (returning 0).
481497
*
482-
* <ul>
483-
* <li>the enqueuing wasn't needed: the getModel task already completed and/or no background
484-
* update.
485-
* <li>the enqueuing hasn't completed: the download id hasn't generated yet - try again.
486-
* </ul>
498+
* <p>If getModelTask is null, then immediately returns the download id of the model. This will be
499+
* 0 if the model doesn't exist, the model has completed downloading, or the download hasn't been
500+
* enqueued.
487501
*
488502
* @param modelName - model name
503+
* @param getModelTask - use the most recent getModel task associated with the model name
489504
* @return id associated with Android Download Manager.
490505
*/
491506
@NonNull

firebase-ml-modeldownloader/src/main/java/com/google/firebase/ml/modeldownloader/internal/CustomModelDownloadService.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,23 +147,23 @@ public Task<CustomModel> getCustomModelDetails(
147147
if (!installationAuthTokenTask.isSuccessful()) {
148148
ErrorCode errorCode = ErrorCode.MODEL_INFO_DOWNLOAD_CONNECTION_FAILED;
149149
String errorMessage = "Failed to get model due to authentication error";
150+
int exceptionCode = FirebaseMlException.UNAUTHENTICATED;
150151
if (installationAuthTokenTask.getException() != null
151152
&& (installationAuthTokenTask.getException() instanceof UnknownHostException
152153
|| installationAuthTokenTask.getException().getCause()
153154
instanceof UnknownHostException)) {
154155
errorCode = ErrorCode.NO_NETWORK_CONNECTION;
155156
errorMessage = "Failed to retrieve model info due to no internet connection.";
157+
exceptionCode = FirebaseMlException.NO_NETWORK_CONNECTION;
156158
}
157159
eventLogger.logDownloadFailureWithReason(
158160
new CustomModel(modelName, modelHash, 0, 0L), false, errorCode.getValue());
159-
return Tasks.forException(
160-
new FirebaseMlException(errorMessage, FirebaseMlException.INTERNAL));
161+
return Tasks.forException(new FirebaseMlException(errorMessage, exceptionCode));
161162
}
162163

163164
connection.setRequestProperty(
164165
INSTALLATIONS_AUTH_TOKEN_HEADER, installationAuthTokenTask.getResult().getToken());
165166
connection.setRequestProperty(API_KEY_HEADER, apiKey);
166-
167167
return fetchDownloadDetails(modelName, connection);
168168
});
169169

@@ -201,13 +201,12 @@ static long parseTokenExpirationTimestamp(String expiresIn) {
201201
private Task<CustomModel> fetchDownloadDetails(String modelName, HttpURLConnection connection) {
202202
try {
203203
connection.connect();
204-
205204
int httpResponseCode = connection.getResponseCode();
206205
String errorMessage = getErrorStream(connection);
207206

208207
switch (httpResponseCode) {
209208
case HttpURLConnection.HTTP_OK:
210-
return Tasks.forResult(readCustomModelResponse(modelName, connection));
209+
return readCustomModelResponse(modelName, connection);
211210
case HttpURLConnection.HTTP_NOT_MODIFIED:
212211
return Tasks.forResult(null);
213212
case HttpURLConnection.HTTP_NOT_FOUND:
@@ -256,13 +255,14 @@ private Task<CustomModel> fetchDownloadDetails(String modelName, HttpURLConnecti
256255
} catch (IOException e) {
257256
ErrorCode errorCode = ErrorCode.MODEL_INFO_DOWNLOAD_CONNECTION_FAILED;
258257
String errorMessage = "Failed to get model URL";
258+
int exceptionCode = FirebaseMlException.INTERNAL;
259259
if (e instanceof UnknownHostException) {
260260
errorCode = ErrorCode.NO_NETWORK_CONNECTION;
261261
errorMessage = "Failed to retrieve model info due to no internet connection.";
262+
exceptionCode = FirebaseMlException.NO_NETWORK_CONNECTION;
262263
}
263264
eventLogger.logModelInfoRetrieverFailure(new CustomModel(modelName, "", 0, 0), errorCode);
264-
return Tasks.forException(
265-
new FirebaseMlException(errorMessage, FirebaseMlException.INTERNAL));
265+
return Tasks.forException(new FirebaseMlException(errorMessage, exceptionCode));
266266
}
267267
}
268268

@@ -275,9 +275,8 @@ private Task<CustomModel> setAndLogException(
275275
return Tasks.forException(new FirebaseMlException(errorMessage, invalidArgument));
276276
}
277277

278-
private CustomModel readCustomModelResponse(
278+
private Task<CustomModel> readCustomModelResponse(
279279
@NonNull String modelName, HttpURLConnection connection) throws IOException {
280-
281280
String encodingKey = connection.getHeaderField(CONTENT_ENCODING_HEADER_KEY);
282281
InputStream inputStream = maybeUnGzip(connection.getInputStream(), encodingKey);
283282
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, UTF_8));
@@ -288,8 +287,13 @@ private CustomModel readCustomModelResponse(
288287
String modelHash = maybeUnGzipHeader(connection.getHeaderField(ETAG_HEADER), encodingKey);
289288

290289
if (modelHash == null || modelHash.isEmpty()) {
291-
// todo(annz) replace this...
292-
modelHash = connection.getResponseMessage();
290+
eventLogger.logDownloadFailureWithReason(
291+
new CustomModel(modelName, modelHash, 0, 0L),
292+
false,
293+
ErrorCode.MODEL_INFO_DOWNLOAD_CONNECTION_FAILED.getValue());
294+
return Tasks.forException(
295+
new FirebaseMlException(
296+
"Model hash not set in download response.", FirebaseMlException.INTERNAL));
293297
}
294298

295299
// JsonReader.peek will sometimes throw AssertionErrors in Android 8.0 and above. See
@@ -318,9 +322,10 @@ private CustomModel readCustomModelResponse(
318322
inputStream.close();
319323

320324
if (!downloadUrl.isEmpty() && expireTime > 0L) {
321-
return new CustomModel(modelName, modelHash, fileSize, downloadUrl, expireTime);
325+
return Tasks.forResult(
326+
new CustomModel(modelName, modelHash, fileSize, downloadUrl, expireTime));
322327
}
323-
return null;
328+
return Tasks.forResult(null);
324329
}
325330

326331
private static InputStream maybeUnGzip(InputStream input, String contentEncoding)

firebase-ml-modeldownloader/src/main/java/com/google/firebase/ml/modeldownloader/internal/ModelFileDownloadService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,8 @@ public void onReceive(Context context, Intent intent) {
592592
if (downloadingModel == null) {
593593
taskCompletionSource.setException(
594594
new FirebaseMlException(
595-
"No model associated with name: " + modelName,
596-
FirebaseMlException.INVALID_ARGUMENT));
595+
"Possible caching issues: No model associated with name: " + modelName,
596+
FirebaseMlException.INTERNAL));
597597
return;
598598
}
599599
}

firebase-ml-modeldownloader/src/test/java/com/google/firebase/ml/modeldownloader/internal/CustomModelDownloadServiceTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,8 @@ public void downloadService_unauthenticatedToken() {
428428

429429
Assert.assertTrue(modelTask.getException() instanceof FirebaseMlException);
430430
Assert.assertEquals(
431-
((FirebaseMlException) modelTask.getException()).getCode(), FirebaseMlException.INTERNAL);
431+
((FirebaseMlException) modelTask.getException()).getCode(),
432+
FirebaseMlException.UNAUTHENTICATED);
432433
Assert.assertTrue(modelTask.getException().getMessage().contains("authentication error"));
433434

434435
verify(mockEventLogger, times(1))
@@ -472,7 +473,8 @@ public void downloadService_unauthenticatedToken_noNetworkConnection() {
472473

473474
Assert.assertTrue(modelTask.getException() instanceof FirebaseMlException);
474475
Assert.assertEquals(
475-
((FirebaseMlException) modelTask.getException()).getCode(), FirebaseMlException.INTERNAL);
476+
((FirebaseMlException) modelTask.getException()).getCode(),
477+
FirebaseMlException.NO_NETWORK_CONNECTION);
476478
Assert.assertTrue(modelTask.getException().getMessage().contains("no internet connection"));
477479

478480
verify(mockEventLogger, times(1))

firebase-ml-modeldownloader/src/test/java/com/google/firebase/ml/modeldownloader/internal/ModelFileDownloadServiceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ public void ensureModelDownloaded_downloadCompletes_missingModel() throws Except
339339
task.addOnCompleteListener(executor, onCompleteListener);
340340
onCompleteListener.await();
341341
} catch (FirebaseMlException ex) {
342-
assertEquals(ex.getCode(), FirebaseMlException.INVALID_ARGUMENT);
342+
assertEquals(ex.getCode(), FirebaseMlException.INTERNAL);
343343
}
344344
assertTrue(task.isComplete());
345345
assertFalse(task.isSuccessful());

0 commit comments

Comments
 (0)