Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SurfaceProducer.Callback lifecycle hooks #53280

Merged
merged 14 commits into from
Jun 24, 2024
1 change: 1 addition & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ embedding_dependencies_jars = [
"//third_party/android_embedding_dependencies/lib/lifecycle-common-java8-2.2.0.jar",
"//third_party/android_embedding_dependencies/lib/lifecycle-livedata-2.0.0.jar",
"//third_party/android_embedding_dependencies/lib/lifecycle-livedata-core-2.0.0.jar",
"//third_party/android_embedding_dependencies/lib/lifecycle-process-2.2.0.jar",
"//third_party/android_embedding_dependencies/lib/lifecycle-runtime-2.2.0.jar",
"//third_party/android_embedding_dependencies/lib/lifecycle-viewmodel-2.1.0.jar",
"//third_party/android_embedding_dependencies/lib/loader-1.0.0.jar",
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ android {
}
}

dependencies {
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary - do the new classes not resolve in android studio for you without it?

If they don't resolve without, I may need to revert #50840, I think something about that PR may have messed up how we resolve the android_embedding_dependencies jars

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I'm not sure. I think this was auto-added by IntelliJ. Let me try removing and resyncing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to work fine w/o, removing.

}

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.view.TextureRegistry;
Expand Down Expand Up @@ -78,6 +81,8 @@ public class FlutterRenderer implements TextureRegistry {
private final Set<WeakReference<TextureRegistry.OnTrimMemoryListener>> onTrimMemoryListeners =
new HashSet<>();

@NonNull private final List<SurfaceProducer> producers = new ArrayList<>();

@NonNull
private final FlutterUiDisplayListener flutterUiDisplayListener =
new FlutterUiDisplayListener() {
Expand All @@ -95,6 +100,18 @@ public void onFlutterUiNoLongerDisplayed() {
public FlutterRenderer(@NonNull FlutterJNI flutterJNI) {
this.flutterJNI = flutterJNI;
this.flutterJNI.addIsDisplayingFlutterUiListener(flutterUiDisplayListener);
ProcessLifecycleOwner.get()
.getLifecycle()
.addObserver(
new DefaultLifecycleObserver() {
@Override
public void onResume(@NonNull LifecycleOwner owner) {
Log.v(TAG, "onResume called; notifying SurfaceProducers");
for (SurfaceProducer producer : producers) {
producer.surfaceRecreated();
}
}
});
}

/**
Expand Down Expand Up @@ -211,6 +228,7 @@ public SurfaceProducer createSurfaceProducer() {
Log.v(TAG, "New SurfaceTextureSurfaceProducer ID: " + texture.id());
entry = producer;
}
producers.add(entry);
return entry;
}

Expand Down Expand Up @@ -453,6 +471,7 @@ final class ImageReaderSurfaceProducer
new HashMap<ImageReader, PerImageReader>();
private PerImage lastDequeuedImage = null;
private PerImageReader lastReaderDequeuedFrom = null;
private SurfaceProducer.OnSurfaceRecreatedCallback callback = null;

/** Internal class: state held per Image produced by ImageReaders. */
private class PerImage {
Expand Down Expand Up @@ -732,6 +751,18 @@ private void maybeWaitOnFence(Image image) {
this.id = id;
}

@Override
public void surfaceRecreated() {
if (callback != null) {
callback.onSurfaceRecreated();
}
}

@Override
public void setOnSurfaceRecreatedCallback(SurfaceProducer.OnSurfaceRecreatedCallback callback) {
this.callback = callback;
}

@Override
public long id() {
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ public void release() {
released = true;
}

@Override
public void surfaceRecreated() {
// Intentionally blank: SurfaceTextures don't need to be recreated.
}

@Override
public void setOnSurfaceRecreatedCallback(
TextureRegistry.SurfaceProducer.OnSurfaceRecreatedCallback callback) {
// Intentionally blank: SurfaceTextures don't need to be recreated.
}

@Override
@NonNull
public SurfaceTexture getSurfaceTexture() {
Expand Down
37 changes: 36 additions & 1 deletion shell/platform/android/io/flutter/view/TextureRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.graphics.SurfaceTexture;
import android.media.Image;
import android.view.Surface;
import android.view.SurfaceHolder;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -79,7 +80,12 @@ interface SurfaceProducer extends TextureEntry {
int getHeight();

/**
* Get a Surface that can be used to update the texture contents.
* Direct access to the surface object.
*
* <p>When using this API, you will usually need to implement {@link SurfaceHolder.Callback} and
* provide it to {@link #setOnSurfaceRecreatedCallback(OnSurfaceRecreatedCallback)} in order to
* be notified when a new surface has been created, such as after a backgrounded app has been\
* resumed.
*
* <p>NOTE: You should not cache the returned surface but instead invoke getSurface each time
* you need to draw. The surface may change when the texture is resized or has its format
Expand All @@ -89,6 +95,35 @@ interface SurfaceProducer extends TextureEntry {
*/
Surface getSurface();

/**
* Sets a callback that is notified when
*
* @param callback The callback to notify, or null to remove the callback.
*/
void setOnSurfaceRecreatedCallback(OnSurfaceRecreatedCallback callback);

/** Callback invoked by {@link #setOnSurfaceRecreatedCallback(OnSurfaceRecreatedCallback)}. */
interface OnSurfaceRecreatedCallback {
/**
* Invoked when a new surface was forcibly recreated by {@link SurfaceProducer}.
*
* <p>Typically plugins will use this callback as a signal to redraw.
*/
void onSurfaceRecreated();
matanlurey marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @deprecated This method is not officially part of the public API surface and will be removed.
*/
@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
void surfaceRecreated();

/**
* @deprecated This method is not officially part of the public API surface and will be removed.
*/
@Deprecated
@SuppressWarnings("DeprecatedIsStillUsed")
void scheduleFrame();
};

Expand Down
1 change: 1 addition & 0 deletions testing/scenario_app/android/app/gradle.lockfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ androidx.lifecycle:lifecycle-common-java8:2.2.0=debugAndroidTestCompileClasspath
androidx.lifecycle:lifecycle-common:2.3.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.lifecycle:lifecycle-livedata-core:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.lifecycle:lifecycle-livedata:2.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.lifecycle:lifecycle-process:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.lifecycle:lifecycle-runtime:2.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.lifecycle:lifecycle-viewmodel:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
Expand Down
22 changes: 10 additions & 12 deletions tools/androidx/files.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@
"url": "https://maven.google.com/androidx/lifecycle/lifecycle-common-java8/2.2.0/lifecycle-common-java8-2.2.0.jar",
"out_file_name": "androidx_lifecycle_common_java8.jar",
"maven_dependency": "androidx.lifecycle:lifecycle-common-java8:2.2.0",
"provides": [
"androidx.lifecycle.DefaultLifecycleObserver"
]
"provides": ["androidx.lifecycle.DefaultLifecycleObserver"]
},
{
"url": "https://maven.google.com/androidx/lifecycle/lifecycle-process/2.2.0/lifecycle-process-2.2.0.aar",
"out_file_name": "androidx_lifecycle_process.aar",
"maven_dependency": "androidx.lifecycle:lifecycle-process:2.2.0",
"provides": ["androidx.lifecycle.ProcessLifecycleOwner"]
},
{
"url": "https://maven.google.com/androidx/lifecycle/lifecycle-runtime/2.2.0/lifecycle-runtime-2.2.0.aar",
"out_file_name": "androidx_lifecycle_runtime.aar",
"maven_dependency": "androidx.lifecycle:lifecycle-runtime:2.2.0",
"provides": [
"androidx.lifecycle.LifecycleRegistry"
]
"provides": ["androidx.lifecycle.LifecycleRegistry"]
},
{
"url": "https://maven.google.com/androidx/fragment/fragment/1.1.0/fragment-1.1.0.aar",
Expand Down Expand Up @@ -54,17 +56,13 @@
"url": "https://maven.google.com/androidx/tracing/tracing/1.0.0/tracing-1.0.0.aar",
"out_file_name": "androidx_tracing.aar",
"maven_dependency": "androidx.tracing:tracing:1.0.0",
"provides": [
"androidx.tracing.Trace"
]
"provides": ["androidx.tracing.Trace"]
},
{
"url": "https://dl.google.com/android/maven2/androidx/core/core/1.6.0/core-1.6.0.aar",
"out_file_name": "androidx_core.aar",
"maven_dependency": "androidx.core:core:1.6.0",
"provides": [
"androidx.core.view.WindowInsetsControllerCompat"
]
"provides": ["androidx.core.view.WindowInsetsControllerCompat"]
},
{
"url": "https://maven.google.com/androidx/window/window-java/1.0.0-beta04/window-java-1.0.0-beta04.aar",
Expand Down
2 changes: 1 addition & 1 deletion tools/cipd/android_embedding_bundle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:3.5.0"
classpath "com.android.tools.build:gradle:7.0.2"
}
}

Expand Down