1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 05:58:14 +03:00
This commit is contained in:
Anton Afanasyeu
2026-05-15 17:50:46 +02:00
parent 65af9331be
commit 4de71d5400
4 changed files with 44 additions and 31 deletions

View File

@@ -143,7 +143,6 @@ public class ReceiverCastService extends Service {
private void restartListening(String pin) {
stopSessionOnly();
closePlaybackUi();
resetStreamState();
phase = Phase.LISTENING;
acquireWakeLock();
@@ -233,15 +232,16 @@ public class ReceiverCastService extends Service {
});
session.start();
updateStatus(getString(R.string.receiver_ready, pin, settings.getTransport().toUpperCase()));
openPlaybackAwaiting(R.string.playback_listening);
Log.i(TAG, "Listening PIN=" + pin + " audio=" + allowIncomingAudio);
}
private void onSenderConnected(String senderName) {
phase = Phase.CONNECTED;
audioAccepted = null;
playbackLaunched = false;
updateStatus(getString(R.string.casting_from, senderName));
broadcastAuthenticated(senderName);
openPlaybackAwaiting(R.string.playback_awaiting_stream);
Log.i(TAG, "Sender connected: " + senderName);
}
@@ -250,15 +250,16 @@ public class ReceiverCastService extends Service {
audioAccepted = null;
hasPendingConfig = false;
awaitingKeyframe = true;
resetDecoderState();
detachSurfaceOnly();
broadcastDisconnected();
openPlaybackAwaiting(R.string.playback_stream_lost);
updateStatus(getString(R.string.waiting_sender));
Log.i(TAG, "Sender disconnected");
}
private void resetStreamState() {
hasPendingConfig = false;
playbackLaunched = false;
awaitingKeyframe = true;
pendingWidth = 0;
pendingHeight = 0;
@@ -328,26 +329,28 @@ public class ReceiverCastService extends Service {
hasPendingConfig = true;
decoderActive = false;
mainHandler.postDelayed(() -> awaitingKeyframe = false, 2000);
if (!playbackLaunched) {
playbackLaunched = true;
launchPlaybackActivity(pendingWidth, pendingHeight);
} else {
notifyPlaybackDimensions(pendingWidth, pendingHeight);
}
notifyPlaybackDimensions(pendingWidth, pendingHeight);
tryConfigureDecoder();
reconfiguring = false;
Log.i(TAG, "Stream config " + pendingWidth + "x" + pendingHeight);
}
private void launchPlaybackActivity(int width, int height) {
/** Opens or refreshes fullscreen UI with robot overlay (listening / waiting for stream). */
private void openPlaybackAwaiting(int messageResId) {
playbackLaunched = true;
Intent intent = new Intent(this, ReceiverPlaybackActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(ReceiverPlaybackActivity.EXTRA_SHOW_AWAITING, true);
intent.putExtra(ReceiverPlaybackActivity.EXTRA_AWAITING_MESSAGE, messageResId);
startActivity(intent);
}
private void notifyPlaybackDimensions(int width, int height) {
Intent intent = new Intent(this, ReceiverPlaybackActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(ReceiverPlaybackActivity.EXTRA_WIDTH, width);
intent.putExtra(ReceiverPlaybackActivity.EXTRA_HEIGHT, height);
startActivity(intent);
}
private void notifyPlaybackDimensions(int width, int height) {
broadcastStreamStarted(width, height);
}
@@ -510,6 +513,7 @@ public class ReceiverCastService extends Service {
private void releaseAll() {
phase = Phase.IDLE;
resetStreamState();
playbackLaunched = false;
audioAccepted = null;
stopSessionOnly();
closePlaybackUi();

View File

@@ -23,11 +23,16 @@ import com.foxx.androidcast.ICastStatusCallback;
import com.foxx.androidcast.R;
import com.foxx.androidcast.ui.AspectRatioFrameLayout;
/** Fullscreen video playback — robot overlay while waiting or after stream loss. */
/**
* Fullscreen display: dancing-robot overlay while listening / waiting;
* video surface shown only after the first decoded frame.
*/
public class ReceiverPlaybackActivity extends AppCompatActivity implements SurfaceHolder.Callback {
public static final String EXTRA_WIDTH = "video_width";
public static final String EXTRA_HEIGHT = "video_height";
public static final String EXTRA_FINISH = "finish_playback";
public static final String EXTRA_SHOW_AWAITING = "show_awaiting";
public static final String EXTRA_AWAITING_MESSAGE = "awaiting_message";
private AspectRatioFrameLayout aspectContainer;
private SurfaceView surfaceView;
@@ -46,13 +51,7 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
private final ICastStatusCallback.Stub statusCallback = new ICastStatusCallback.Stub() {
@Override
public void onStatus(String status) {
runOnUiThread(() -> {
if (status != null && status.toLowerCase().contains("waiting")) {
showAwaitingOverlay(R.string.playback_awaiting_stream);
}
});
}
public void onStatus(String status) {}
@Override
public void onAuthenticated(String senderName) {
@@ -85,10 +84,6 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
bound = true;
try {
receiverService.registerCallback(statusCallback);
String status = receiverService.getStatus();
if (status != null && status.toLowerCase().contains("waiting")) {
showAwaitingOverlay(R.string.playback_awaiting_stream);
}
} catch (RemoteException ignored) {
}
attachSurfaceIfReady();
@@ -119,9 +114,14 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
awaitingMessage = findViewById(R.id.text_awaiting_message);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceView.setZOrderMediaOverlay(false);
robotDance = AnimationUtils.loadAnimation(this, R.anim.robot_dance);
applyAspectRatio();
showAwaitingOverlay(R.string.playback_awaiting_stream);
if (getIntent().getBooleanExtra(EXTRA_SHOW_AWAITING, true)) {
int msg = getIntent().getIntExtra(EXTRA_AWAITING_MESSAGE, R.string.playback_listening);
showAwaitingOverlay(msg);
}
}
@Override
@@ -133,8 +133,9 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
}
readSizeFromIntent(intent);
updateVideoSize(videoWidth, videoHeight);
if (!streamRendering) {
showAwaitingOverlay(R.string.playback_awaiting_stream);
if (intent.getBooleanExtra(EXTRA_SHOW_AWAITING, false)) {
int msg = intent.getIntExtra(EXTRA_AWAITING_MESSAGE, R.string.playback_listening);
showAwaitingOverlay(msg);
}
}
@@ -198,7 +199,11 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
if (awaitingOverlay == null) {
return;
}
if (surfaceView != null) {
surfaceView.setVisibility(View.INVISIBLE);
}
awaitingOverlay.setVisibility(View.VISIBLE);
awaitingOverlay.bringToFront();
if (awaitingMessage != null) {
awaitingMessage.setText(messageResId);
}
@@ -206,10 +211,12 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
}
private void hideAwaitingOverlay() {
if (awaitingOverlay == null) {
return;
if (awaitingOverlay != null) {
awaitingOverlay.setVisibility(View.GONE);
}
if (surfaceView != null) {
surfaceView.setVisibility(View.VISIBLE);
}
awaitingOverlay.setVisibility(View.GONE);
stopRobotAnimation();
}

View File

@@ -5,6 +5,7 @@
android:layout_height="match_parent"
android:background="#CC000000"
android:clickable="true"
android:elevation="16dp"
android:focusable="true">
<LinearLayout

View File

@@ -42,6 +42,7 @@
<string name="label_receiver_audio">Play incoming cast audio on this device</string>
<string name="start_receiver">Start listening (keeps running in background)</string>
<string name="playback_buffering">Connected — waiting for video…</string>
<string name="playback_listening">Listening for cast — awaiting sender…</string>
<string name="playback_awaiting_stream">Awaiting for stream to come…</string>
<string name="playback_stream_lost">Stream lost — awaiting for stream to come…</string>
<string name="receiver_starting">Starting receiver service…</string>