From f01fe428413aac20d7299496019e33703e8d9209 Mon Sep 17 00:00:00 2001 From: shubang Date: Wed, 24 May 2023 16:49:45 -0700 Subject: [PATCH] [TIAF] Dup AdBuffer early to avoid race conditions If we dup the buffer in the main thread, it's possible that the buffer has been released and is no longer valid. Bug: 280886498 Test: atest TvInteractiveAppServiceTest#testNotifyAdBufferReady Change-Id: I7f07f4ab42f59c2cf91d47d1dd8a8aca93ae70d2 --- media/java/android/media/tv/TvInputService.java | 14 +++++++++++++- .../tv/interactive/TvInteractiveAppService.java | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 85b02ad547184..720d9a6291de6 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -63,6 +63,7 @@ import android.widget.FrameLayout; import com.android.internal.os.SomeArgs; import com.android.internal.util.Preconditions; +import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -1009,6 +1010,13 @@ public abstract class TvInputService extends Service { * @param buffer the {@link AdBuffer} that was consumed. */ public void notifyAdBufferConsumed(@NonNull AdBuffer buffer) { + AdBuffer dupBuffer; + try { + dupBuffer = AdBuffer.dupAdBuffer(buffer); + } catch (IOException e) { + Log.w(TAG, "dup AdBuffer error in notifyAdBufferConsumed:", e); + return; + } executeOrPostRunnableOnMainThread(new Runnable() { @MainThread @Override @@ -1016,10 +1024,14 @@ public abstract class TvInputService extends Service { try { if (DEBUG) Log.d(TAG, "notifyAdBufferConsumed"); if (mSessionCallback != null) { - mSessionCallback.onAdBufferConsumed(buffer); + mSessionCallback.onAdBufferConsumed(dupBuffer); } } catch (RemoteException e) { Log.w(TAG, "error in notifyAdBufferConsumed", e); + } finally { + if (dupBuffer != null) { + dupBuffer.getSharedMemory().close(); + } } } }); diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java index ec85cc7af4992..241940486a149 100755 --- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java +++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java @@ -1964,6 +1964,13 @@ public abstract class TvInteractiveAppService extends Service { */ @CallSuper public void notifyAdBufferReady(@NonNull AdBuffer buffer) { + AdBuffer dupBuffer; + try { + dupBuffer = AdBuffer.dupAdBuffer(buffer); + } catch (IOException e) { + Log.w(TAG, "dup AdBuffer error in notifyAdBufferReady:", e); + return; + } executeOrPostRunnableOnMainThread(new Runnable() { @MainThread @Override @@ -1974,10 +1981,14 @@ public abstract class TvInteractiveAppService extends Service { "notifyAdBufferReady(buffer=" + buffer + ")"); } if (mSessionCallback != null) { - mSessionCallback.onAdBufferReady(AdBuffer.dupAdBuffer(buffer)); + mSessionCallback.onAdBufferReady(dupBuffer); } - } catch (RemoteException | IOException e) { + } catch (RemoteException e) { Log.w(TAG, "error in notifyAdBuffer", e); + } finally { + if (dupBuffer != null) { + dupBuffer.getSharedMemory().close(); + } } } });