Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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<ImageReaderSurfaceProducer> imageReaderProducers = new ArrayList<>();

@NonNull
private final FlutterUiDisplayListener flutterUiDisplayListener =
new FlutterUiDisplayListener() {
Expand All @@ -95,6 +100,20 @@ 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.w(TAG, "onResume called; notifying SurfaceProducers");
for (ImageReaderSurfaceProducer producer : imageReaderProducers) {
if (producer.callback != null) {
producer.callback.onSurfaceChanged();
}
}
}
});
}

/**
Expand Down Expand Up @@ -197,6 +216,7 @@ public SurfaceProducer createSurfaceProducer() {
final ImageReaderSurfaceProducer producer = new ImageReaderSurfaceProducer(id);
registerImageTexture(id, producer);
addOnTrimMemoryListener(producer);
imageReaderProducers.add(producer);
Log.v(TAG, "New ImageReaderSurfaceProducer ID: " + id);
entry = producer;
} else {
Expand Down Expand Up @@ -453,6 +473,7 @@ final class ImageReaderSurfaceProducer
new HashMap<ImageReader, PerImageReader>();
private PerImage lastDequeuedImage = null;
private PerImageReader lastReaderDequeuedFrom = null;
private Callback callback = null;

/** Internal class: state held per Image produced by ImageReaders. */
private class PerImage {
Expand Down Expand Up @@ -678,6 +699,7 @@ public void onTrimMemory(int level) {
private void releaseInternal() {
cleanup();
released = true;
imageReaderProducers.remove(this);
}

private void cleanup() {
Expand All @@ -699,6 +721,9 @@ private void cleanup() {
}
imageReaderQueue.clear();
}
if (this.callback != null) {
this.callback.onSurfaceDestroyed();
}
}

@TargetApi(API_LEVELS.API_33)
Expand Down Expand Up @@ -732,6 +757,11 @@ private void maybeWaitOnFence(Image image) {
this.id = id;
}

@Override
public void setCallback(Callback 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,11 @@ public void release() {
released = true;
}

@Override
public void setCallback(Callback callback) {
// Intentionally blank: SurfaceTextures don't get platform notifications or cleanup.
}

@Override
@NonNull
public SurfaceTexture getSurfaceTexture() {
Expand Down
1 change: 1 addition & 0 deletions shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ public ImageTextureEntry createImageTexture() {
throw new UnsupportedOperationException("Image textures are not supported in this mode.");
}

@NonNull
@Override
public SurfaceProducer createSurfaceProducer() {
throw new UnsupportedOperationException(
Expand Down
52 changes: 45 additions & 7 deletions shell/platform/android/io/flutter/view/TextureRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ interface TextureEntry {
/** @return The identity of this texture. */
long id();

/** Deregisters and releases all resources . */
/** De-registers and releases all resources . */
void release();
}

Expand All @@ -79,18 +79,56 @@ 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>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
* <p>When using this API, you will usually need to implement {@link SurfaceProducer.Callback}
* and provide it to {@link #setCallback(Callback)} in order to be notified when an existing
* surface has been destroyed (such as when the application goes to the background) or a new
* surface has been created (such as when the application is resumed back to the foreground).
*
* <p>NOTE: You should not cache the returned surface but instead invoke {@code getSurface} each
* time you need to draw. The surface may change when the texture is resized or has its format
* changed.
*
* @return a Surface to use for a drawing target for various APIs.
*/
Surface getSurface();

/**
* Sets a callback that is notified when a previously created {@link Surface} returned by {@link
* SurfaceProducer#getSurface()} is no longer valid, either due to being destroyed or being
* changed.
*
* @param callback The callback to notify, or null to remove the callback.
*/
void setCallback(Callback callback);

/** Callback invoked by {@link #setCallback(Callback)}. */
interface Callback {
Copy link
Contributor

Choose a reason for hiding this comment

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

naming nit: Callbacks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/**
* Invoked when a previous surface is now invalid and a new surface is now available.
*
* <p>Typically plugins will use this callback as a signal to redraw, such as due to the
* texture being resized, the format being changed, or the application being resumed after
* being suspended in the background.
*/
void onSurfaceChanged();

/**
* Invoked when a previous surface is now invalid.
*
* <p>Typically plugins will use this callback as a signal to release resources.
*/
void onSurfaceDestroyed();
}

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

/** A registry entry for a managed SurfaceTexture. */
@Keep
Expand Down Expand Up @@ -144,7 +182,7 @@ interface ImageConsumer {
* @return Image or null.
*/
@Nullable
public Image acquireLatestImage();
Image acquireLatestImage();
}

@Keep
Expand All @@ -155,6 +193,6 @@ interface GLTextureConsumer {
* @return SurfaceTexture.
*/
@NonNull
public SurfaceTexture getSurfaceTexture();
SurfaceTexture getSurfaceTexture();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1582,13 +1582,16 @@ private static void attachToFlutterView(
new TextureRegistry() {
public void TextureRegistry() {}

@NonNull
@Override
public SurfaceTextureEntry createSurfaceTexture() {
return registerSurfaceTexture(mock(SurfaceTexture.class));
}

@NonNull
@Override
public SurfaceTextureEntry registerSurfaceTexture(SurfaceTexture surfaceTexture) {
public SurfaceTextureEntry registerSurfaceTexture(
@NonNull SurfaceTexture surfaceTexture) {
return new SurfaceTextureEntry() {
@NonNull
@Override
Expand All @@ -1606,6 +1609,7 @@ public void release() {}
};
}

@NonNull
@Override
public ImageTextureEntry createImageTexture() {
return new ImageTextureEntry() {
Expand All @@ -1622,9 +1626,13 @@ public void pushImage(Image image) {}
};
}

@NonNull
@Override
public SurfaceProducer createSurfaceProducer() {
return new SurfaceProducer() {
@Override
public void setCallback(SurfaceProducer.Callback cb) {}

@Override
public long id() {
return 0;
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