Skip to content

Commit 05de05d

Browse files
committed
Some cleanup in App Distro's Dagger usage
1 parent 20d6467 commit 05de05d

File tree

11 files changed

+120
-72
lines changed

11 files changed

+120
-72
lines changed

firebase-appdistribution/firebase-appdistribution.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ dependencies {
5555
testImplementation project(':integ-testing')
5656
runtimeOnly project(':firebase-installations')
5757

58-
implementation 'javax.inject:javax.inject:1'
59-
vendor ('com.google.dagger:dagger:2.43.2') {
58+
implementation libs.javax.inject
59+
vendor (libs.dagger.dagger) {
6060
exclude group: "javax.inject", module: "javax.inject"
6161
}
62-
annotationProcessor 'com.google.dagger:dagger-compiler:2.43.2'
62+
annotationProcessor libs.dagger.compiler
6363

6464
testImplementation 'junit:junit:4.13.2'
6565
testImplementation "org.robolectric:robolectric:$robolectricVersion"

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/AabUpdater.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
import java.io.IOException;
3333
import java.util.concurrent.Executor;
3434
import javax.inject.Inject;
35+
import javax.inject.Singleton;
3536
import javax.net.ssl.HttpsURLConnection;
3637

3738
/** Class that handles updateApp functionality for AABs in {@link FirebaseAppDistribution}. */
39+
@Singleton // Only one update should happen at a time, even across FirebaseAppDistribution instances
3840
class AabUpdater {
3941
private static final String TAG = "AabUpdater";
4042

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/ApkInstaller.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
2525
import java.util.concurrent.Executor;
2626
import javax.inject.Inject;
27+
import javax.inject.Singleton;
2728

2829
/** Class that handles installing APKs in {@link FirebaseAppDistribution}. */
30+
@Singleton // Only one update should happen at a time, even across FirebaseAppDistribution instances
2931
class ApkInstaller {
3032
private static final String TAG = "ApkInstaller";
3133

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/ApkUpdater.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
import java.util.concurrent.Executor;
3838
import java.util.jar.JarFile;
3939
import javax.inject.Inject;
40+
import javax.inject.Singleton;
4041
import javax.net.ssl.HttpsURLConnection;
4142

4243
/** Class that handles updateApp functionality for APKs in {@link FirebaseAppDistribution}. */
44+
@Singleton // Only one update should happen at a time, even across FirebaseAppDistribution instances
4345
class ApkUpdater {
4446
private static final String TAG = "ApkUpdater";
4547
private static final int UPDATE_INTERVAL_MS = 250;

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@
4848
import java.util.concurrent.Executor;
4949
import java.util.concurrent.atomic.AtomicBoolean;
5050
import javax.inject.Inject;
51+
import javax.inject.Singleton;
5152

5253
/**
5354
* This class is the "real" implementation of the Firebase App Distribution API which should only be
5455
* included in pre-release builds.
5556
*/
57+
// TODO(b/266704696): This currently only supports one FirebaseAppDistribution instance app-wide
58+
@Singleton
5659
class FirebaseAppDistributionImpl implements FirebaseAppDistribution {
5760

5861
private static final String TAG = "Impl";

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionLifecycleNotifier.java

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818

1919
import android.app.Activity;
2020
import android.app.Application;
21+
import android.app.Application.ActivityLifecycleCallbacks;
2122
import android.os.Bundle;
2223
import android.os.Looper;
2324
import androidx.annotation.GuardedBy;
2425
import androidx.annotation.NonNull;
2526
import androidx.annotation.Nullable;
27+
import androidx.annotation.VisibleForTesting;
2628
import com.google.android.gms.tasks.SuccessContinuation;
2729
import com.google.android.gms.tasks.Task;
2830
import com.google.android.gms.tasks.TaskCompletionSource;
@@ -35,8 +37,8 @@
3537
import javax.inject.Inject;
3638
import javax.inject.Singleton;
3739

38-
@Singleton
39-
class FirebaseAppDistributionLifecycleNotifier implements Application.ActivityLifecycleCallbacks {
40+
@Singleton // Only one lifecycle notifier is required across the entire app
41+
class FirebaseAppDistributionLifecycleNotifier {
4042

4143
/** An {@link Executor} that runs tasks on the current thread. */
4244
private static final Executor DIRECT_EXECUTOR = Runnable::run;
@@ -59,8 +61,12 @@ interface NullableActivityFunction<T> {
5961
}
6062

6163
@UiThread private final Executor uiThreadExecutor;
64+
@VisibleForTesting final LifecycleCallbacks lifecycleCallbacks = new LifecycleCallbacks();
6265
private final Object lock = new Object();
6366

67+
@GuardedBy("lock")
68+
private boolean lifecycleCallbacksRegistered = false;
69+
6470
@GuardedBy("lock")
6571
private Activity currentActivity;
6672

@@ -112,6 +118,21 @@ interface OnActivityDestroyedListener {
112118
void onDestroyed(Activity activity);
113119
}
114120

121+
/**
122+
* Register for activity lifecycle callbacks for the application.
123+
*
124+
* <p>This must be called for this class to provide information about activity state.
125+
*/
126+
void registerActivityLifecycleCallbacks(Application application) {
127+
synchronized (lock) {
128+
// Make sure we register for callbacks only once, so callbacks are not called twice
129+
if (!lifecycleCallbacksRegistered) {
130+
application.registerActivityLifecycleCallbacks(lifecycleCallbacks);
131+
lifecycleCallbacksRegistered = true;
132+
}
133+
}
134+
}
135+
115136
/**
116137
* Apply a function to a foreground activity, when one is available, returning a {@link Task} that
117138
* will complete immediately after the function is applied.
@@ -311,67 +332,71 @@ void addOnActivityPausedListener(@NonNull OnActivityPausedListener listener) {
311332
}
312333
}
313334

314-
@Override
315-
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
316-
synchronized (lock) {
317-
updateCurrentActivity(activity);
318-
for (OnActivityCreatedListener listener : onActivityCreatedListeners) {
319-
listener.onCreated(activity);
335+
@VisibleForTesting
336+
class LifecycleCallbacks implements ActivityLifecycleCallbacks {
337+
338+
@Override
339+
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
340+
synchronized (lock) {
341+
updateCurrentActivity(activity);
342+
for (OnActivityCreatedListener listener : onActivityCreatedListeners) {
343+
listener.onCreated(activity);
344+
}
320345
}
321346
}
322-
}
323347

324-
@Override
325-
public void onActivityStarted(@NonNull Activity activity) {
326-
synchronized (lock) {
327-
updateCurrentActivity(activity);
328-
for (OnActivityStartedListener listener : onActivityStartedListeners) {
329-
listener.onStarted(activity);
348+
@Override
349+
public void onActivityStarted(@NonNull Activity activity) {
350+
synchronized (lock) {
351+
updateCurrentActivity(activity);
352+
for (OnActivityStartedListener listener : onActivityStartedListeners) {
353+
listener.onStarted(activity);
354+
}
330355
}
331356
}
332-
}
333357

334-
@Override
335-
public void onActivityResumed(@NonNull Activity activity) {
336-
synchronized (lock) {
337-
updateCurrentActivity(activity);
338-
for (OnActivityResumedListener listener : onActivityResumedListeners) {
339-
listener.onResumed(activity);
358+
@Override
359+
public void onActivityResumed(@NonNull Activity activity) {
360+
synchronized (lock) {
361+
updateCurrentActivity(activity);
362+
for (OnActivityResumedListener listener : onActivityResumedListeners) {
363+
listener.onResumed(activity);
364+
}
340365
}
341366
}
342-
}
343367

344-
@Override
345-
public void onActivityPaused(@NonNull Activity activity) {
346-
synchronized (lock) {
347-
if (currentActivity == activity) {
348-
updateCurrentActivity(null);
349-
}
350-
for (OnActivityPausedListener listener : onActivityPausedListeners) {
351-
listener.onPaused(activity);
368+
@Override
369+
public void onActivityPaused(@NonNull Activity activity) {
370+
synchronized (lock) {
371+
if (currentActivity == activity) {
372+
updateCurrentActivity(null);
373+
}
374+
for (OnActivityPausedListener listener : onActivityPausedListeners) {
375+
listener.onPaused(activity);
376+
}
352377
}
353378
}
354-
}
355379

356-
@Override
357-
public void onActivityStopped(@NonNull Activity activity) {}
380+
@Override
381+
public void onActivityStopped(@NonNull Activity activity) {}
358382

359-
@Override
360-
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {}
383+
@Override
384+
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {}
361385

362-
@Override
363-
public void onActivityDestroyed(@NonNull Activity activity) {
364-
synchronized (lock) {
365-
// If an activity is destroyed, delete all references to it, including the previous activity
366-
if (currentActivity == activity) {
367-
updateCurrentActivity(null);
368-
}
369-
if (previousActivity == activity) {
370-
previousActivity = null;
371-
}
386+
@Override
387+
public void onActivityDestroyed(@NonNull Activity activity) {
388+
synchronized (lock) {
389+
// If an activity is destroyed, delete all references to it, including the previous activity
390+
if (currentActivity == activity) {
391+
updateCurrentActivity(null);
392+
}
393+
if (previousActivity == activity) {
394+
previousActivity = null;
395+
}
372396

373-
for (OnActivityDestroyedListener listener : onDestroyedListeners) {
374-
listener.onDestroyed(activity);
397+
for (OnActivityDestroyedListener listener : onDestroyedListeners) {
398+
listener.onDestroyed(activity);
399+
}
375400
}
376401
}
377402
}

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionRegistrar.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ private FirebaseAppDistribution buildFirebaseAppDistribution(
9999

100100
if (applicationContext instanceof Application) {
101101
Application application = (Application) applicationContext;
102-
application.registerActivityLifecycleCallbacks(appDistroComponent.getLifecycleNotifier());
102+
appDistroComponent.getLifecycleNotifier().registerActivityLifecycleCallbacks(application);
103103
} else {
104104
LogWrapper.e(
105105
TAG,

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/ScreenshotTaker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
import java.io.IOException;
3838
import java.util.concurrent.Executor;
3939
import javax.inject.Inject;
40+
import javax.inject.Singleton;
4041

4142
/** A class that takes screenshots of the host app. */
43+
@Singleton // All instances store images at the same URI, so there should really only be one
4244
class ScreenshotTaker {
4345

4446
static final String SCREENSHOT_FILE_NAME =

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/SignInStorage.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
import com.google.firebase.annotations.concurrent.Background;
2424
import java.util.concurrent.Executor;
2525
import javax.inject.Inject;
26+
import javax.inject.Singleton;
2627

2728
/** Class that handles storage for App Distribution SignIn persistence. */
29+
// TODO(b/266704696): This currently only supports one FirebaseAppDistribution instance app-wide
30+
@Singleton
2831
class SignInStorage {
2932
@VisibleForTesting
3033
static final String SIGNIN_PREFERENCES_NAME = "FirebaseAppDistributionSignInStorage";

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/TesterSignInManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@
3939
import java.util.List;
4040
import java.util.concurrent.Executor;
4141
import javax.inject.Inject;
42+
import javax.inject.Singleton;
4243

4344
/** Class that handles signing in the tester. */
45+
// TODO(b/266704696): This currently only supports one FirebaseAppDistribution instance app-wide
46+
@Singleton
4447
class TesterSignInManager {
4548
private static final String TAG = "TesterSignInManager";
4649

0 commit comments

Comments
 (0)