From 82316d13b09eeb9184456013e62a6a6956cb6f98 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 9 Sep 2022 19:06:37 +0200 Subject: [PATCH] use weak reference to activity when using threads fixes #4366 --- .../conversations/ui/RecordingActivity.java | 60 +++++++++++-------- .../conversations/ui/RtpSessionActivity.java | 42 +++++++++---- 2 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java index bc9972316..6c58a404d 100644 --- a/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RecordingActivity.java @@ -18,6 +18,7 @@ import android.widget.Toast; import androidx.databinding.DataBindingUtil; import java.io.File; +import java.lang.ref.WeakReference; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -136,30 +137,41 @@ public class RecordingActivity extends Activity implements View.OnClickListener } } if (saveFile) { - new Thread( - () -> { - try { - if (!outputFileWrittenLatch.await(2, TimeUnit.SECONDS)) { - Log.d( - Config.LOGTAG, - "time out waiting for output file to be written"); - } - } catch (InterruptedException e) { - Log.d( - Config.LOGTAG, - "interrupted while waiting for output file to be written", - e); - } - runOnUiThread( - () -> { - setResult( - Activity.RESULT_OK, - new Intent() - .setData(Uri.fromFile(mOutputFile))); - finish(); - }); - }) - .start(); + new Thread(new Finisher(outputFileWrittenLatch, mOutputFile, this)).start(); + } + } + + private static class Finisher implements Runnable { + + private final CountDownLatch latch; + private final File outputFile; + private final WeakReference activityReference; + + private Finisher(CountDownLatch latch, File outputFile, Activity activity) { + this.latch = latch; + this.outputFile = outputFile; + this.activityReference = new WeakReference<>(activity); + } + + @Override + public void run() { + try { + if (!latch.await(5, TimeUnit.SECONDS)) { + Log.d(Config.LOGTAG, "time out waiting for output file to be written"); + } + } catch (final InterruptedException e) { + Log.d(Config.LOGTAG, "interrupted while waiting for output file to be written", e); + } + final Activity activity = activityReference.get(); + if (activity == null) { + return; + } + activity.runOnUiThread( + () -> { + activity.setResult( + Activity.RESULT_OK, new Intent().setData(Uri.fromFile(outputFile))); + activity.finish(); + }); } } diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index cbf00d04b..e73fdb23c 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -5,6 +5,7 @@ import static eu.siacs.conversations.utils.PermissionUtils.getFirstDenied; import android.Manifest; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.PictureInPictureParams; import android.content.ActivityNotFoundException; import android.content.Context; @@ -297,21 +298,38 @@ public class RtpSessionActivity extends XmppActivity } private void checkMicrophoneAvailabilityAsync() { - new Thread(this::checkMicrophoneAvailability).start(); + new Thread(new MicrophoneAvailabilityCheck(this)).start(); } - private void checkMicrophoneAvailability() { - final long start = SystemClock.elapsedRealtime(); - final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable(); - final long stop = SystemClock.elapsedRealtime(); - Log.d(Config.LOGTAG, "checking microphone availability took " + (stop - start) + "ms"); - if (isMicrophoneAvailable) { - return; + private static class MicrophoneAvailabilityCheck implements Runnable { + + private final WeakReference activityReference; + + private MicrophoneAvailabilityCheck(final Activity activity) { + this.activityReference = new WeakReference<>(activity); + } + + @Override + public void run() { + final long start = SystemClock.elapsedRealtime(); + final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable(); + final long stop = SystemClock.elapsedRealtime(); + Log.d(Config.LOGTAG, "checking microphone availability took " + (stop - start) + "ms"); + if (isMicrophoneAvailable) { + return; + } + final Activity activity = activityReference.get(); + if (activity == null) { + return; + } + activity.runOnUiThread( + () -> + Toast.makeText( + activity, + R.string.microphone_unavailable, + Toast.LENGTH_LONG) + .show()); } - runOnUiThread( - () -> - Toast.makeText(this, R.string.microphone_unavailable, Toast.LENGTH_LONG) - .show()); } private void putScreenInCallMode() {