use weak reference to activity when using threads

fixes #4366
This commit is contained in:
Daniel Gultsch 2022-09-09 19:06:37 +02:00
parent a95d0fa8d3
commit 82316d13b0
2 changed files with 66 additions and 36 deletions

View file

@ -18,6 +18,7 @@ import android.widget.Toast;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import java.io.File; import java.io.File;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -136,30 +137,41 @@ public class RecordingActivity extends Activity implements View.OnClickListener
} }
} }
if (saveFile) { if (saveFile) {
new Thread( new Thread(new Finisher(outputFileWrittenLatch, mOutputFile, this)).start();
() -> { }
try { }
if (!outputFileWrittenLatch.await(2, TimeUnit.SECONDS)) {
Log.d( private static class Finisher implements Runnable {
Config.LOGTAG,
"time out waiting for output file to be written"); private final CountDownLatch latch;
} private final File outputFile;
} catch (InterruptedException e) { private final WeakReference<Activity> activityReference;
Log.d(
Config.LOGTAG, private Finisher(CountDownLatch latch, File outputFile, Activity activity) {
"interrupted while waiting for output file to be written", this.latch = latch;
e); this.outputFile = outputFile;
} this.activityReference = new WeakReference<>(activity);
runOnUiThread( }
() -> {
setResult( @Override
Activity.RESULT_OK, public void run() {
new Intent() try {
.setData(Uri.fromFile(mOutputFile))); if (!latch.await(5, TimeUnit.SECONDS)) {
finish(); Log.d(Config.LOGTAG, "time out waiting for output file to be written");
}); }
}) } catch (final InterruptedException e) {
.start(); 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();
});
} }
} }

View file

@ -5,6 +5,7 @@ import static eu.siacs.conversations.utils.PermissionUtils.getFirstDenied;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PictureInPictureParams; import android.app.PictureInPictureParams;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
@ -297,21 +298,38 @@ public class RtpSessionActivity extends XmppActivity
} }
private void checkMicrophoneAvailabilityAsync() { private void checkMicrophoneAvailabilityAsync() {
new Thread(this::checkMicrophoneAvailability).start(); new Thread(new MicrophoneAvailabilityCheck(this)).start();
} }
private void checkMicrophoneAvailability() { private static class MicrophoneAvailabilityCheck implements Runnable {
final long start = SystemClock.elapsedRealtime();
final boolean isMicrophoneAvailable = AppRTCAudioManager.isMicrophoneAvailable(); private final WeakReference<Activity> activityReference;
final long stop = SystemClock.elapsedRealtime();
Log.d(Config.LOGTAG, "checking microphone availability took " + (stop - start) + "ms"); private MicrophoneAvailabilityCheck(final Activity activity) {
if (isMicrophoneAvailable) { this.activityReference = new WeakReference<>(activity);
return; }
@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() { private void putScreenInCallMode() {