mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-21 02:08:40 +00:00
Resume call PIP on app foreground.
This commit is contained in:
@@ -137,6 +137,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
public static final String EXTRA_ENABLE_VIDEO_IF_AVAILABLE = WebRtcCallActivity.class.getCanonicalName() + ".ENABLE_VIDEO_IF_AVAILABLE";
|
||||
public static final String EXTRA_STARTED_FROM_FULLSCREEN = WebRtcCallActivity.class.getCanonicalName() + ".STARTED_FROM_FULLSCREEN";
|
||||
public static final String EXTRA_STARTED_FROM_CALL_LINK = WebRtcCallActivity.class.getCanonicalName() + ".STARTED_FROM_CALL_LINK";
|
||||
public static final String EXTRA_LAUNCH_IN_PIP = WebRtcCallActivity.class.getCanonicalName() + ".STARTED_FROM_CALL_LINK";
|
||||
|
||||
private CallParticipantsListUpdatePopupWindow participantUpdateWindow;
|
||||
private CallStateUpdatePopupWindow callStateUpdatePopupWindow;
|
||||
@@ -159,6 +160,8 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
private LifecycleDisposable lifecycleDisposable;
|
||||
private long lastCallLinkDisconnectDialogShowTime;
|
||||
private ControlsAndInfoController controlsAndInfo;
|
||||
private boolean enterPipOnResume;
|
||||
private long lastProcessedIntentTimestamp;
|
||||
|
||||
private Disposable ephemeralStateDisposable = Disposable.empty();
|
||||
|
||||
@@ -264,6 +267,11 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
}
|
||||
}, TimeUnit.SECONDS.toMillis(1));
|
||||
}
|
||||
|
||||
if (enterPipOnResume) {
|
||||
enterPipOnResume = false;
|
||||
enterPipModeIfPossible();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -303,8 +311,12 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
|
||||
if (!viewModel.isCallStarting()) {
|
||||
CallParticipantsState state = viewModel.getCallParticipantsStateSnapshot();
|
||||
if (state != null && state.getCallState().isPreJoinOrNetworkUnavailable()) {
|
||||
ApplicationDependencies.getSignalCallManager().cancelPreJoin();
|
||||
if (state != null) {
|
||||
if (state.getCallState().isPreJoinOrNetworkUnavailable()) {
|
||||
ApplicationDependencies.getSignalCallManager().cancelPreJoin();
|
||||
} else if (state.getCallState().getInOngoingCall() && isInPipMode()) {
|
||||
ApplicationDependencies.getSignalCallManager().relaunchPipOnForeground();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,6 +375,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
Log.d(TAG, "Intent: Action: " + intent.getAction());
|
||||
Log.d(TAG, "Intent: EXTRA_STARTED_FROM_FULLSCREEN: " + intent.getBooleanExtra(EXTRA_STARTED_FROM_FULLSCREEN, false));
|
||||
Log.d(TAG, "Intent: EXTRA_ENABLE_VIDEO_IF_AVAILABLE: " + intent.getBooleanExtra(EXTRA_ENABLE_VIDEO_IF_AVAILABLE, false));
|
||||
Log.d(TAG, "Intent: EXTRA_LAUNCH_IN_PIP: " + intent.getBooleanExtra(EXTRA_LAUNCH_IN_PIP, false));
|
||||
}
|
||||
|
||||
private void processIntent(@NonNull Intent intent) {
|
||||
@@ -375,6 +388,12 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
} else if (END_CALL_ACTION.equals(intent.getAction())) {
|
||||
handleEndCall();
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - lastProcessedIntentTimestamp > TimeUnit.SECONDS.toMillis(1)) {
|
||||
enterPipOnResume = intent.getBooleanExtra(EXTRA_LAUNCH_IN_PIP, false);
|
||||
}
|
||||
|
||||
lastProcessedIntentTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void initializePendingParticipantFragmentListener() {
|
||||
@@ -853,8 +872,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
|
||||
}
|
||||
|
||||
private boolean isSystemPipEnabledAndAvailable() {
|
||||
return Build.VERSION.SDK_INT >= 26 &&
|
||||
getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
|
||||
return Build.VERSION.SDK_INT >= 26 && getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
|
||||
}
|
||||
|
||||
private void delayedFinish() {
|
||||
|
||||
@@ -47,7 +47,10 @@ class WebRtcViewModel(state: WebRtcServiceState) {
|
||||
get() = this == CALL_PRE_JOIN || this == NETWORK_FAILURE
|
||||
|
||||
val isPassedPreJoin: Boolean
|
||||
get() = ordinal > ordinal
|
||||
get() = ordinal > CALL_PRE_JOIN.ordinal
|
||||
|
||||
val inOngoingCall: Boolean
|
||||
get() = this == CALL_INCOMING || this == CALL_OUTGOING || this == CALL_CONNECTED || this == CALL_RINGING || this == CALL_RECONNECTING
|
||||
}
|
||||
|
||||
enum class GroupCallState {
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.service.webrtc;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
@@ -125,14 +126,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
|
||||
@Nullable private final CallManager callManager;
|
||||
|
||||
private final Context context;
|
||||
private final ExecutorService serviceExecutor;
|
||||
private final Executor networkExecutor;
|
||||
private final LockManager lockManager;
|
||||
private final Context context;
|
||||
private final ExecutorService serviceExecutor;
|
||||
private final Executor networkExecutor;
|
||||
private final LockManager lockManager;
|
||||
|
||||
private WebRtcServiceState serviceState;
|
||||
private RxStore<WebRtcEphemeralState> ephemeralStateStore;
|
||||
private boolean needsToSetSelfUuid = true;
|
||||
private boolean needsToSetSelfUuid = true;
|
||||
|
||||
private RxStore<Map<RecipientId, CallLinkPeekInfo>> linkPeekInfoStore;
|
||||
|
||||
@@ -182,8 +183,8 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
}
|
||||
|
||||
private void process(@NonNull ProcessAction action) {
|
||||
Throwable t = new Throwable();
|
||||
String caller = t.getStackTrace().length > 1 ? t.getStackTrace()[1].getMethodName() : "unknown";
|
||||
Throwable t = new Throwable();
|
||||
String caller = t.getStackTrace().length > 1 ? t.getStackTrace()[1].getMethodName() : "unknown";
|
||||
|
||||
if (callManager == null) {
|
||||
Log.w(TAG, "Unable to process action, call manager is not initialized");
|
||||
@@ -1151,6 +1152,10 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
return new SignalCallLinkManager(Objects.requireNonNull(callManager));
|
||||
}
|
||||
|
||||
public void relaunchPipOnForeground() {
|
||||
ApplicationDependencies.getAppForegroundObserver().addListener(new RelaunchListener(ApplicationDependencies.getAppForegroundObserver().isForegrounded()));
|
||||
}
|
||||
|
||||
private void processSendMessageFailureWithChangeDetection(@NonNull RemotePeer remotePeer,
|
||||
@NonNull ProcessAction failureProcessAction)
|
||||
{
|
||||
@@ -1169,6 +1174,44 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
});
|
||||
}
|
||||
|
||||
private class RelaunchListener implements AppForegroundObserver.Listener {
|
||||
private boolean canRelaunch;
|
||||
|
||||
public RelaunchListener(boolean isForegrounded) {
|
||||
canRelaunch = !isForegrounded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onForeground() {
|
||||
if (canRelaunch) {
|
||||
if (isSystemPipEnabledAndAvailable()) {
|
||||
process((s, p) -> {
|
||||
WebRtcViewModel.State callState = s.getCallInfoState().getCallState();
|
||||
|
||||
if (callState.getInOngoingCall()) {
|
||||
Intent intent = new Intent(context, WebRtcCallActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(WebRtcCallActivity.EXTRA_LAUNCH_IN_PIP, true);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
return s;
|
||||
});
|
||||
}
|
||||
ApplicationDependencies.getAppForegroundObserver().removeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackground() {
|
||||
canRelaunch = true;
|
||||
}
|
||||
|
||||
private boolean isSystemPipEnabledAndAvailable() {
|
||||
return Build.VERSION.SDK_INT >= 26 && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
|
||||
}
|
||||
}
|
||||
|
||||
interface ProcessAction {
|
||||
@NonNull WebRtcServiceState process(@NonNull WebRtcServiceState currentState, @NonNull WebRtcActionProcessor processor);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user