Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,9 @@ private suspend fun validateResponse(response: HttpResponse) {
throw PromptBlockedException(message)
}
if (message.contains("genai config not found")) {
throw APINotConfiguredException()
throw APINotConfiguredException(
"The Gemini Developer API is not enabled, to enable and configure, see https://firebase.google.com/docs/ai-logic/faq-and-troubleshooting?api=dev#error-genai-config-not-found"
)
}
getServiceDisabledErrorDetailsOrNull(error)?.let {
val errorMessage =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,13 @@ internal class UnsupportedUserLocationException(cause: Throwable? = null) :
FirebaseCommonAIException("User location is not supported for the API use.", cause)

/**
* The user's project does not have the Gemini Developer API enabled in the Firebase Console.
* The user's project has not been configured and enabled for the selected API.
*
* See the Firebase documentation for the
* For the Gemini Developer API, see
* [steps](https://firebase.google.com/docs/ai-logic/faq-and-troubleshooting?api=dev#error-genai-config-not-found)
* to enable the Gemini Developer API.
*/
internal class APINotConfiguredException(cause: Throwable? = null) :
FirebaseCommonAIException("Gemini Developer API not enabled in Firebase console.", cause)
internal class APINotConfiguredException(message: String, cause: Throwable? = null) :
FirebaseCommonAIException(message, cause)

/**
* Some form of state occurred that shouldn't have.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal constructor(message: String, cause: Throwable? = null) : RuntimeExcepti
is com.google.firebase.ai.common.QuotaExceededException ->
QuotaExceededException(cause.message ?: "", cause.cause)
is com.google.firebase.ai.common.APINotConfiguredException ->
APINotConfiguredException(cause.cause)
APINotConfiguredException(cause.message ?: "", cause.cause)
else -> UnknownException(cause.message ?: "", cause)
}
is TimeoutCancellationException ->
Expand Down Expand Up @@ -152,14 +152,14 @@ public class UnsupportedUserLocationException internal constructor(cause: Throwa
FirebaseAIException("User location is not supported for the API use.", cause)

/**
* The user's project does not have the Gemini Developer API enabled in the Firebase Console.
* The user's project has not been configured and enabled for the selected API.
*
* See the Firebase documentation for the
* For the Gemini Developer API, see
* [steps](https://firebase.google.com/docs/ai-logic/faq-and-troubleshooting?api=dev#error-genai-config-not-found)
* to enable the Gemini Developer API.
*/
public class APINotConfiguredException internal constructor(cause: Throwable? = null) :
FirebaseAIException("Gemini Developer API not enabled in Firebase console.", cause)
public class APINotConfiguredException
internal constructor(message: String, cause: Throwable? = null) :
FirebaseAIException(message, cause)

/**
* Some form of state occurred that shouldn't have.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
package com.google.firebase.datastorage

import android.content.Context
import android.os.Process
import android.util.Log
import androidx.datastore.core.DataStore
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.preferences.SharedPreferencesMigration
import androidx.datastore.preferences.core.MutablePreferences
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.preferencesDataStore
import com.google.firebase.annotations.concurrent.Background
import kotlinx.coroutines.flow.firstOrNull
Expand Down Expand Up @@ -60,7 +64,16 @@ class JavaDataStorage(val context: Context, val name: String) {
private val Context.dataStore: DataStore<Preferences> by
preferencesDataStore(
name = name,
produceMigrations = { listOf(SharedPreferencesMigration(it, name)) }
produceMigrations = { listOf(SharedPreferencesMigration(it, name)) },
corruptionHandler =
ReplaceFileCorruptionHandler { ex ->
Log.w(
JavaDataStorage::class.simpleName,
"CorruptionException in ${name} DataStore running in process ${Process.myPid()}",
ex
)
emptyPreferences()
}
)

private val dataStore = context.dataStore
Expand Down
7 changes: 3 additions & 4 deletions firebase-crashlytics-ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Unreleased

* [changed] Updated `firebase-crashlytics` dependency to 20.0.1

# 20.0.0
* [changed] **Breaking Change**: Updated minSdkVersion to API level 23 or higher.
Expand Down Expand Up @@ -243,12 +243,12 @@ change. The following release notes describe changes in the new SDK.
<li>If you're using [crashlytics] for NDK crash reporting in your app for
the first time, follow the
<a href="/docs/crashlytics/get-started-new-sdk?platform=android">getting
started instructions</a>.
started instructions</a>.
</li>
<li>If you're upgrading from the legacy Fabric SDK to the
[firebase_crashlytics] SDK for NDK crash reporting, follow the
<a href="/docs/crashlytics/upgrade-sdk?platform=android">upgrade
instructions</a> to update your app with the following SDK changes.
instructions</a> to update your app with the following SDK changes.
</li>
</ul>
</aside>
Expand All @@ -259,4 +259,3 @@ change. The following release notes describe changes in the new SDK.
uploading symbol files to [crashlytics] servers. See the
[[crashlytics] Gradle plugin documentation](/docs/crashlytics/ndk-reports-new-sdk)
for more information.

7 changes: 3 additions & 4 deletions firebase-crashlytics/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Unreleased

** [changed] Updated `firebase-sessions` dependency to v3.0.1

# 20.0.0
* [changed] **Breaking Change**: Removed deprecated public constructor `KeyValueBuilder(crashlytics: FirebaseCrashlytics)`
Expand Down Expand Up @@ -683,12 +683,12 @@ The following release notes describe changes in the new SDK.
<li>If you're using [crashlytics] for NDK crash reporting in your app for
the first time, follow the
<a href="/docs/crashlytics/get-started-new-sdk?platform=android">getting
started instructions</a>.
started instructions</a>.
</li>
<li>If you're upgrading from the legacy Fabric SDK to the
[firebase_crashlytics] SDK, follow the
<a href="/docs/crashlytics/upgrade-sdk?platform=android">upgrade
instructions</a> to update your app with the following SDK changes.
instructions</a> to update your app with the following SDK changes.
</li>
</ul>
</aside>
Expand All @@ -702,4 +702,3 @@ The following release notes describe changes in the new SDK.
from your `AndroidManifest.xml` file.
* [removed] The `fabric.properties` and `crashlytics.properties` files are no
longer supported. Remove them from your app.

1 change: 0 additions & 1 deletion firebase-perf/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Unreleased
* [fixed] Fixed an ANR on app launch. [#4831]
* [fixed] Fixed app start traces on API 34+. [#5920]

# 22.0.0
* [changed] **Breaking Change**: Updated minSdkVersion to API level 23 or higher.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ public class AppStartTrace implements ActivityLifecycleCallbacks, LifecycleObser
private static final @NonNull Timer PERF_CLASS_LOAD_TIME = new Clock().getTime();
private static final long MAX_LATENCY_BEFORE_UI_INIT = TimeUnit.MINUTES.toMicros(1);

private static final long MAX_BACKGROUND_RUNNABLE_DELAY = TimeUnit.MILLISECONDS.toMicros(100);

// Core pool size 0 allows threads to shut down if they're idle
private static final int CORE_POOL_SIZE = 0;
private static final int MAX_POOL_SIZE = 1; // Only need single thread
Expand Down Expand Up @@ -113,8 +111,6 @@ public class AppStartTrace implements ActivityLifecycleCallbacks, LifecycleObser
private final @Nullable Timer processStartTime;
private final @Nullable Timer firebaseClassLoadTime;
private Timer onCreateTime = null;

private Timer mainThreadRunnableTime = null;
private Timer onStartTime = null;
private Timer onResumeTime = null;
private Timer firstForegroundTime = null;
Expand Down Expand Up @@ -323,26 +319,8 @@ private void recordOnDrawFrontOfQueue() {
logExperimentTrace(this.experimentTtid);
}

private void resolveIsStartedFromBackground() {
// If the mainThreadRunnableTime is null, either the runnable hasn't run, or this check has
// already been made.
if (mainThreadRunnableTime == null) {
return;
}

// Set it to true if the runnable ran more than 100ms prior to onActivityCreated()
if (mainThreadRunnableTime.getDurationMicros() > MAX_BACKGROUND_RUNNABLE_DELAY) {
isStartedFromBackground = true;
}

// Set this to null to prevent additional checks if `onActivityCreated()` is called again.
mainThreadRunnableTime = null;
}

@Override
public synchronized void onActivityCreated(Activity activity, Bundle savedInstanceState) {
resolveIsStartedFromBackground();

if (isStartedFromBackground || onCreateTime != null // An activity already called onCreate()
) {
return;
Expand Down Expand Up @@ -582,7 +560,8 @@ public static boolean isScreenOn(Context appContext) {
* We use StartFromBackgroundRunnable to detect if app is started from background or foreground.
* If app is started from background, we do not generate AppStart trace. This runnable is posted
* to main UI thread from FirebasePerfEarly. If app is started from background, this runnable will
* be executed earlier than 100ms of any activity's onCreate() method.
* be executed before any activity's onCreate() method. If app is started from foreground,
* activity's onCreate() method is executed before this runnable.
*/
public static class StartFromBackgroundRunnable implements Runnable {
private final AppStartTrace trace;
Expand All @@ -593,7 +572,10 @@ public StartFromBackgroundRunnable(final AppStartTrace trace) {

@Override
public void run() {
trace.mainThreadRunnableTime = new Timer();
// if no activity has ever been created.
if (trace.onCreateTime == null) {
trace.isStartedFromBackground = true;
}
}
}

Expand Down Expand Up @@ -632,7 +614,7 @@ Timer getOnResumeTime() {
}

@VisibleForTesting
void setMainThreadRunnableTime(Timer timer) {
mainThreadRunnableTime = timer;
void setIsStartFromBackground() {
isStartedFromBackground = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -239,42 +238,11 @@ public void testDelayedAppStart() {
}

@Test
public void testStartFromBackground_within100ms() {
public void testStartFromBackground() {
FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService();
Timer fakeTimer = spy(new Timer(currentTime));
AppStartTrace trace =
new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService);
trace.registerActivityLifecycleCallbacks(appContext);
trace.setMainThreadRunnableTime(fakeTimer);

when(fakeTimer.getDurationMicros()).thenReturn(99L);
trace.onActivityCreated(activity1, bundle);
Assert.assertNotNull(trace.getOnCreateTime());
++currentTime;
trace.onActivityStarted(activity1);
Assert.assertNotNull(trace.getOnStartTime());
++currentTime;
trace.onActivityResumed(activity1);
Assert.assertNotNull(trace.getOnResumeTime());
fakeExecutorService.runAll();
// There should be a trace sent since the delay between the main thread and onActivityCreated
// is limited.
verify(transportManager, times(1))
.log(
traceArgumentCaptor.capture(),
ArgumentMatchers.nullable(ApplicationProcessState.class));
}

@Test
public void testStartFromBackground_moreThan100ms() {
FakeScheduledExecutorService fakeExecutorService = new FakeScheduledExecutorService();
Timer fakeTimer = spy(new Timer(currentTime));
AppStartTrace trace =
new AppStartTrace(transportManager, clock, configResolver, fakeExecutorService);
trace.registerActivityLifecycleCallbacks(appContext);
trace.setMainThreadRunnableTime(fakeTimer);

when(fakeTimer.getDurationMicros()).thenReturn(TimeUnit.MILLISECONDS.toMicros(100) + 1);
trace.setIsStartFromBackground();
trace.onActivityCreated(activity1, bundle);
Assert.assertNull(trace.getOnCreateTime());
++currentTime;
Expand All @@ -284,7 +252,6 @@ public void testStartFromBackground_moreThan100ms() {
trace.onActivityResumed(activity1);
Assert.assertNull(trace.getOnResumeTime());
// There should be no trace sent.
fakeExecutorService.runAll();
verify(transportManager, times(0))
.log(
traceArgumentCaptor.capture(),
Expand Down
5 changes: 3 additions & 2 deletions firebase-sessions/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

* [fixed] Bumped DataStore dependency to include the mitigation for
`CorruptionException` released in version `1.1.5`. See Jetpacks' DataStore
[release notes](https://developer.android.com/jetpack/androidx/releases/datastore#1.1.5).

# 3.0.0
* [changed] Added internal api for Crashlytics to notify Sessions of crash events
Expand Down Expand Up @@ -55,4 +57,3 @@

# 1.0.0
* [feature] Initial Firebase sessions library.

4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ constraintlayout = "2.1.4"
coreKtx = "1.12.0"
coroutines = "1.9.0"
dagger = "2.51" # Don't bump above 2.51 as it causes a bug in AppDistro FeedbackSender JPEG code
datastore = "1.1.3"
datastore = "1.1.7"
dexmaker = "2.28.1"
dexmakerVersion = "1.2"
espressoCore = "3.6.1"
Expand Down Expand Up @@ -238,4 +238,4 @@ spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
protobuf = { id = "com.google.protobuf", version.ref = "protobufGradlePlugin" }
errorprone = { id = "net.ltgt.errorprone", version.ref = "gradleErrorpronePlugin" }
google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" }
crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsGradle" }
crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsGradle" }
7 changes: 7 additions & 0 deletions release.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "m169",
"libraries": [
":firebase-ai",
":firebase-perf"
]
}
Loading
Loading