mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-01 14:16:49 +00:00
Hopefully prevent VoiceNotePlaybackService startup crash.
Addresses #13140
This commit is contained in:
committed by
Nicholas Tinsley
parent
6d4b487428
commit
bfc8b199b6
@@ -1,12 +1,15 @@
|
||||
package org.thoughtcrime.securesms.components.voice;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -29,7 +32,6 @@ import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
@@ -42,6 +44,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Android Service responsible for playback of voice notes.
|
||||
@@ -54,7 +57,6 @@ public class VoiceNotePlaybackService extends MediaSessionService {
|
||||
|
||||
private static final String TAG = Log.tag(VoiceNotePlaybackService.class);
|
||||
private static final String SESSION_ID = "VoiceNotePlayback";
|
||||
private static final String EMPTY_ROOT_ID = "empty-root-id";
|
||||
private static final int LOAD_MORE_THRESHOLD = 2;
|
||||
|
||||
private MediaSession mediaSession;
|
||||
@@ -69,8 +71,15 @@ public class VoiceNotePlaybackService extends MediaSessionService {
|
||||
player.addListener(new VoiceNotePlayerEventListener());
|
||||
|
||||
voiceNotePlayerCallback = new VoiceNotePlayerCallback(this, player);
|
||||
mediaSession = new MediaSession.Builder(this, player).setCallback(voiceNotePlayerCallback).setId(SESSION_ID).build();
|
||||
keyClearedReceiver = new KeyClearedReceiver(this, mediaSession.getToken());
|
||||
mediaSession = buildMediaSession(false);
|
||||
|
||||
if (mediaSession == null) {
|
||||
Log.e(TAG, "Unable to create media session at all, stopping service to avoid crash.");
|
||||
stopSelf();
|
||||
return;
|
||||
}
|
||||
|
||||
keyClearedReceiver = new KeyClearedReceiver(this, mediaSession.getToken());
|
||||
|
||||
setMediaNotificationProvider(new VoiceNoteMediaNotificationProvider(this));
|
||||
setListener(new MediaSessionServiceListener());
|
||||
@@ -184,6 +193,54 @@ public class VoiceNotePlaybackService extends MediaSessionService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some devices, such as the ASUS Zenfone 8, erroneously report multiple broadcast receivers for {@value Intent#ACTION_MEDIA_BUTTON} in the package manager.
|
||||
* This triggers a failure within the {@link MediaSession} initialization and throws an {@link IllegalStateException}.
|
||||
* This method will catch that exception and attempt to disable the duplicated broadcast receiver in the hopes of getting the package manager to
|
||||
* report only 1, avoiding the error.
|
||||
* If that doesn't work, it returns null, signaling the {@link MediaSession} cannot be built on this device.
|
||||
*
|
||||
* @return the built MediaSession, or null if the session cannot be built.
|
||||
*/
|
||||
private @Nullable MediaSession buildMediaSession(boolean isRetry) {
|
||||
try {
|
||||
return new MediaSession.Builder(this, player).setCallback(voiceNotePlayerCallback).setId(SESSION_ID).build();
|
||||
} catch (IllegalStateException e) {
|
||||
|
||||
if (isRetry) {
|
||||
Log.e(TAG, "Unable to create media session, even after retry.", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
Log.w(TAG, "Unable to create media session with default parameters.", e);
|
||||
PackageManager pm = this.getPackageManager();
|
||||
Intent queryIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
|
||||
queryIntent.setPackage(this.getPackageName());
|
||||
final List<ResolveInfo> mediaButtonReceivers = pm.queryBroadcastReceivers(queryIntent, /* flags= */ 0);
|
||||
|
||||
Log.d(TAG, "Found " + mediaButtonReceivers.size() + " BroadcastReceivers for " + Intent.ACTION_MEDIA_BUTTON);
|
||||
|
||||
boolean found = false;
|
||||
|
||||
if (mediaButtonReceivers.size() > 1) {
|
||||
for (ResolveInfo receiverInfo : mediaButtonReceivers) {
|
||||
|
||||
final ActivityInfo activityInfo = receiverInfo.activityInfo;
|
||||
|
||||
if (!found && activityInfo.packageName.contains("androidx.media.session")) {
|
||||
found = true;
|
||||
} else {
|
||||
pm.setComponentEnabledSetting(new ComponentName(activityInfo.packageName, activityInfo.name), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
}
|
||||
|
||||
return buildMediaSession(true);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable PlaybackParameters getPlaybackParametersForWindowPosition(int currentWindowIndex) {
|
||||
if (isAudioMessage(currentWindowIndex)) {
|
||||
return player.getPlaybackParameters();
|
||||
|
||||
Reference in New Issue
Block a user