Skip to content

Commit 5287fb4

Browse files
authored
Merge b8af493 into b695dd2
2 parents b695dd2 + b8af493 commit 5287fb4

File tree

25 files changed

+605
-432
lines changed

25 files changed

+605
-432
lines changed

firebase-ml-modeldownloader/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Unreleased
2+
- [changed] Internal infrastructure improvements.
23

34
# 24.1.1
45
* [fixed] Fixed an issue where `FirebaseModelDownloader.getModel` was throwing

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
plugins {
1616
id 'firebase-library'
17+
id 'firebase-vendor'
1718
id 'com.google.protobuf'
1819
}
1920

@@ -76,6 +77,12 @@ dependencies {
7677
implementation 'com.google.auto.service:auto-service-annotations:1.0-rc6'
7778
implementation 'javax.inject:javax.inject:1'
7879

80+
implementation 'javax.inject:javax.inject:1'
81+
vendor ('com.google.dagger:dagger:2.43.2') {
82+
exclude group: "javax.inject", module: "javax.inject"
83+
}
84+
annotationProcessor 'com.google.dagger:dagger-compiler:2.43.2'
85+
7986
compileOnly "com.google.auto.value:auto-value-annotations:1.6.6"
8087
annotationProcessor "com.google.auto.value:auto-value:1.6.5"
8188
annotationProcessor project(":encoders:firebase-encoders-processor")

firebase-ml-modeldownloader/ktx/ktx.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ dependencies {
4949
implementation project(':firebase-ml-modeldownloader')
5050

5151
testImplementation "org.robolectric:robolectric:$robolectricVersion"
52-
testImplementation 'junit:junit:4.12'
52+
testImplementation 'junit:junit:4.13.2'
5353
testImplementation "com.google.truth:truth:$googleTruthVersion"
54+
testImplementation 'org.mockito:mockito-core:3.6.0'
55+
testImplementation 'androidx.test:runner:1.5.1'
56+
testImplementation 'androidx.test.ext:junit:1.1.4'
5457
}

firebase-ml-modeldownloader/ktx/src/test/kotlin/com/google/firebase/ml/modeldownloader/ktx/ModelDownloaderTests.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@
1414

1515
package com.google.firebase.ml.modeldownloader.ktx
1616

17+
import androidx.test.core.app.ApplicationProvider
18+
import androidx.test.ext.junit.runners.AndroidJUnit4
1719
import com.google.common.truth.Truth.assertThat
1820
import com.google.firebase.FirebaseApp
1921
import com.google.firebase.FirebaseOptions
2022
import com.google.firebase.ktx.Firebase
2123
import com.google.firebase.ktx.app
2224
import com.google.firebase.ktx.initialize
23-
import com.google.firebase.ml.modeldownloader.CustomModel
2425
import com.google.firebase.ml.modeldownloader.FirebaseModelDownloader
2526
import com.google.firebase.platforminfo.UserAgentPublisher
2627
import org.junit.After
2728
import org.junit.Before
2829
import org.junit.Test
2930
import org.junit.runner.RunWith
3031
import org.robolectric.RobolectricTestRunner
31-
import org.robolectric.RuntimeEnvironment
3232

3333
const val APP_ID = "1:1234567890:android:321abc456def7890"
3434
const val API_KEY = "AIzaSyDOCAbC123dEf456GhI789jKl012-MnO"
@@ -39,15 +39,15 @@ abstract class BaseTestCase {
3939
@Before
4040
fun setUp() {
4141
Firebase.initialize(
42-
RuntimeEnvironment.application,
42+
ApplicationProvider.getApplicationContext(),
4343
FirebaseOptions.Builder()
4444
.setApplicationId(APP_ID)
4545
.setApiKey(API_KEY)
4646
.setProjectId("123")
4747
.build()
4848
)
4949
Firebase.initialize(
50-
RuntimeEnvironment.application,
50+
ApplicationProvider.getApplicationContext(),
5151
FirebaseOptions.Builder()
5252
.setApplicationId(APP_ID)
5353
.setApiKey(API_KEY)
@@ -63,7 +63,7 @@ abstract class BaseTestCase {
6363
}
6464
}
6565

66-
@RunWith(RobolectricTestRunner::class)
66+
@RunWith(AndroidJUnit4::class)
6767
class ModelDownloaderTests : BaseTestCase() {
6868

6969
@Test
@@ -92,14 +92,17 @@ class ModelDownloaderTests : BaseTestCase() {
9292

9393
@Test
9494
fun `CustomModel destructuring declarations work`() {
95+
val app = Firebase.app(EXISTING_APP)
96+
9597
val modelName = "myModel"
9698
val modelHash = "someHash"
9799
val fileSize = 200L
98100
val downloadId = 258L
99101

100-
val customModel = CustomModel(modelName, modelHash, fileSize, downloadId)
102+
val customModel =
103+
Firebase.modelDownloader(app).modelFactory.create(modelName, modelHash, fileSize, downloadId)
101104

102-
val (file, size, id, hash, name) = customModel
105+
val (_, size, id, hash, name) = customModel
103106

104107
assertThat(name).isEqualTo(customModel.name)
105108
assertThat(hash).isEqualTo(customModel.modelHash)

firebase-ml-modeldownloader/ml-data-collection-tests/src/test/java/com/google/firebase/ml_data_collection_tests/MlDataCollectionTestUtil.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414

1515
package com.google.firebase.ml_data_collection_tests;
1616

17-
import android.content.Context;
18-
import android.content.SharedPreferences;
1917
import androidx.test.core.app.ApplicationProvider;
2018
import com.google.firebase.FirebaseApp;
2119
import com.google.firebase.FirebaseOptions;
20+
import com.google.firebase.ml.modeldownloader.FirebaseModelDownloader;
2221
import com.google.firebase.ml.modeldownloader.internal.SharedPreferencesUtil;
2322
import java.util.function.Consumer;
2423

@@ -47,12 +46,8 @@ static void withApp(String name, Consumer<FirebaseApp> callable) {
4746
}
4847

4948
static SharedPreferencesUtil getSharedPreferencesUtil(FirebaseApp app) {
50-
return new SharedPreferencesUtil(app);
51-
}
52-
53-
static SharedPreferences getSharedPreferences(FirebaseApp app) {
54-
return app.getApplicationContext()
55-
.getSharedPreferences(SharedPreferencesUtil.PREFERENCES_PACKAGE_NAME, Context.MODE_PRIVATE);
49+
return new SharedPreferencesUtil(
50+
app, FirebaseModelDownloader.getInstance(app).getModelFactory());
5651
}
5752

5853
static void setSharedPreferencesTo(FirebaseApp app, Boolean enabled) {

firebase-ml-modeldownloader/src/androidTest/java/com/google/firebase/ml/modeldownloader/TestGetModelLocal.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,25 @@ public class TestGetModelLocal {
4545
private static final String MODEL_NAME_LOCAL = "getLocalModel";
4646
private static final String MODEL_NAME_LOCAL_2 = "getLocalModel2";
4747
private static final String MODEL_HASH = "origHash324";
48-
private final CustomModel SETUP_LOADED_LOCAL_MODEL =
49-
new CustomModel(MODEL_NAME_LOCAL, MODEL_HASH, 100, 0);
5048

5149
private FirebaseApp app;
5250
private File firstDeviceModelFile;
5351
private File firstLoadTempModelFile;
5452

53+
private CustomModel.Factory modelFactory;
54+
private CustomModel setupLoadedLocalModel;
55+
5556
@Before
5657
public void before() {
5758
app = FirebaseApp.initializeApp(ApplicationProvider.getApplicationContext());
5859
app.setDataCollectionDefaultEnabled(Boolean.FALSE);
5960
FirebaseModelDownloader firebaseModelDownloader = FirebaseModelDownloader.getInstance(app);
6061

61-
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(app);
62+
modelFactory = firebaseModelDownloader.getModelFactory();
63+
64+
setupLoadedLocalModel = modelFactory.create(MODEL_NAME_LOCAL, MODEL_HASH, 100, 0);
65+
66+
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(app, modelFactory);
6267
// reset shared preferences and downloads for models used by this test.
6368
firebaseModelDownloader.deleteDownloadedModel(MODEL_NAME_LOCAL);
6469
firebaseModelDownloader.deleteDownloadedModel(MODEL_NAME_LOCAL_2);
@@ -79,7 +84,11 @@ public void teardown() {
7984
}
8085

8186
private void setUpLoadedLocalModelWithFile() throws Exception {
82-
ModelFileManager fileManager = ModelFileManager.getInstance();
87+
ModelFileManager fileManager =
88+
new ModelFileManager(
89+
app.getApplicationContext(),
90+
app.getPersistenceKey(),
91+
new SharedPreferencesUtil(app, modelFactory));
8392
final File testDir = new File(app.getApplicationContext().getNoBackupFilesDir(), "tmpModels");
8493
testDir.mkdirs();
8594
// make sure the directory is empty. Doesn't recurse into subdirs, but that's OK since
@@ -105,14 +114,14 @@ private void setUpLoadedLocalModelWithFile() throws Exception {
105114
ParcelFileDescriptor fd =
106115
ParcelFileDescriptor.open(firstLoadTempModelFile, ParcelFileDescriptor.MODE_READ_ONLY);
107116

108-
firstDeviceModelFile = fileManager.moveModelToDestinationFolder(SETUP_LOADED_LOCAL_MODEL, fd);
117+
firstDeviceModelFile = fileManager.moveModelToDestinationFolder(setupLoadedLocalModel, fd);
109118
assertEquals(firstDeviceModelFile, new File(expectedDestinationFolder + "/0"));
110119
assertTrue(firstDeviceModelFile.exists());
111120
fd.close();
112121

113122
fakePreloadedCustomModel(
114123
MODEL_NAME_LOCAL,
115-
SETUP_LOADED_LOCAL_MODEL.getModelHash(),
124+
setupLoadedLocalModel.getModelHash(),
116125
99,
117126
expectedDestinationFolder + "/0");
118127
}
@@ -228,9 +237,9 @@ public void localModel_preloadedDoNotFetchUpdate() throws Exception {
228237
}
229238

230239
private void fakePreloadedCustomModel(String modelName, String hash, long size, String filePath) {
231-
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(app);
240+
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(app, modelFactory);
232241
sharedPreferencesUtil.setLoadedCustomModelDetails(
233-
new CustomModel(modelName, hash, size, 0L, filePath));
242+
modelFactory.create(modelName, hash, size, 0L, filePath));
234243
}
235244

236245
private Set<CustomModel> getDownloadedModelList()

firebase-ml-modeldownloader/src/androidTest/java/com/google/firebase/ml/modeldownloader/TestPublicApi.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public void before() {
4545
app.setDataCollectionDefaultEnabled(Boolean.FALSE);
4646
FirebaseModelDownloader firebaseModelDownloader = FirebaseModelDownloader.getInstance(app);
4747

48-
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(app);
48+
SharedPreferencesUtil sharedPreferencesUtil =
49+
new SharedPreferencesUtil(app, firebaseModelDownloader.getModelFactory());
4950
// reset shared preferences and downloads for models used by this test.
5051
firebaseModelDownloader.deleteDownloadedModel(MODEL_NAME_LOCAL);
5152
firebaseModelDownloader.deleteDownloadedModel(MODEL_NAME_LOCAL_2);

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

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
import androidx.annotation.NonNull;
1818
import androidx.annotation.Nullable;
19+
import androidx.annotation.RestrictTo;
1920
import androidx.annotation.VisibleForTesting;
2021
import com.google.android.gms.common.internal.Objects;
2122
import com.google.firebase.ml.modeldownloader.internal.ModelFileDownloadService;
23+
import dagger.assisted.Assisted;
24+
import dagger.assisted.AssistedFactory;
25+
import dagger.assisted.AssistedInject;
2226
import java.io.File;
2327

2428
/**
@@ -27,6 +31,7 @@
2731
* downloaded, the original model file will be removed once it is safe to do so.
2832
*/
2933
public class CustomModel {
34+
private final ModelFileDownloadService fileDownloadService;
3035
private final String name;
3136
private final long downloadId;
3237
private final long fileSize;
@@ -35,57 +40,31 @@ public class CustomModel {
3540
private final String downloadUrl;
3641
private final long downloadUrlExpiry;
3742

38-
/**
39-
* Use when creating a custom model while the initial download is still in progress.
40-
*
41-
* @param name Model name.
42-
* @param modelHash Model hash.
43-
* @param fileSize Model file size.
44-
* @param downloadId Android Download Manger - download ID.
45-
* @hide
46-
*/
47-
public CustomModel(
48-
@NonNull String name, @NonNull String modelHash, long fileSize, long downloadId) {
49-
this(name, modelHash, fileSize, downloadId, "", "", 0);
50-
}
43+
/** @hide */
44+
@AssistedFactory
45+
public interface Factory {
46+
CustomModel create(
47+
@Assisted("name") String name,
48+
@Assisted("modelHash") String modelHash,
49+
@Assisted("fileSize") long fileSize,
50+
@Assisted("downloadId") long downloadId,
51+
@Assisted("localFilePath") String localFilePath,
52+
@Assisted("downloadUrl") String downloadUrl,
53+
@Assisted("downloadUrlExpiry") long downloadUrlExpiry);
5154

52-
/**
53-
* Use when creating a custom model from a stored model with a new download in the background.
54-
*
55-
* @param name Model name.
56-
* @param modelHash Model hash.
57-
* @param fileSize Model file size.
58-
* @param downloadId Android Download Manger - download ID.
59-
* @hide
60-
*/
61-
public CustomModel(
62-
@NonNull String name,
63-
@NonNull String modelHash,
64-
long fileSize,
65-
long downloadId,
66-
String localFilePath) {
67-
this(name, modelHash, fileSize, downloadId, localFilePath, "", 0);
68-
}
55+
default CustomModel create(String name, String modelHash, long fileSize, long downloadId) {
56+
return create(name, modelHash, fileSize, downloadId, "", "", 0);
57+
}
6958

70-
/**
71-
* Use when creating a custom model from a download service response. Download URL and download
72-
* URL expiry should go together. These will not be stored in user preferences as this is a
73-
* temporary step towards setting the actual download ID.
74-
*
75-
* @param name Model name.
76-
* @param modelHash Model hash.
77-
* @param fileSize Model file size.
78-
* @param downloadUrl Download URL path
79-
* @param downloadUrlExpiry Time download URL path expires.
80-
* @hide
81-
*/
82-
public CustomModel(
83-
@NonNull String name,
84-
@NonNull String modelHash,
85-
long fileSize,
86-
String downloadUrl,
87-
long downloadUrlExpiry) {
88-
this(name, modelHash, fileSize, 0, "", downloadUrl, downloadUrlExpiry);
59+
default CustomModel create(
60+
String name, String modelHash, long fileSize, long downloadId, String localFilePath) {
61+
return create(name, modelHash, fileSize, downloadId, localFilePath, "", 0);
62+
}
63+
64+
default CustomModel create(
65+
String name, String modelHash, long fileSize, String downloadUrl, long downloadUrlExpiry) {
66+
return create(name, modelHash, fileSize, 0, "", downloadUrl, downloadUrlExpiry);
67+
}
8968
}
9069

9170
/**
@@ -100,14 +79,19 @@ public CustomModel(
10079
* @param downloadUrlExpiry Expiry time of download URL link.
10180
* @hide
10281
*/
103-
private CustomModel(
104-
@NonNull String name,
105-
@NonNull String modelHash,
106-
long fileSize,
107-
long downloadId,
108-
@Nullable String localFilePath,
109-
@Nullable String downloadUrl,
110-
long downloadUrlExpiry) {
82+
@AssistedInject
83+
@VisibleForTesting
84+
@RestrictTo(RestrictTo.Scope.LIBRARY)
85+
public CustomModel(
86+
ModelFileDownloadService fileDownloadService,
87+
@Assisted("name") String name,
88+
@Assisted("modelHash") String modelHash,
89+
@Assisted("fileSize") long fileSize,
90+
@Assisted("downloadId") long downloadId,
91+
@Assisted("localFilePath") String localFilePath,
92+
@Assisted("downloadUrl") String downloadUrl,
93+
@Assisted("downloadUrlExpiry") long downloadUrlExpiry) {
94+
this.fileDownloadService = fileDownloadService;
11195
this.modelHash = modelHash;
11296
this.name = name;
11397
this.fileSize = fileSize;
@@ -137,7 +121,7 @@ public String getName() {
137121
*/
138122
@Nullable
139123
public File getFile() {
140-
return getFile(ModelFileDownloadService.getInstance());
124+
return getFile(fileDownloadService);
141125
}
142126

143127
/**

0 commit comments

Comments
 (0)