Implement seamless PiP entry on Android 12

This commit is contained in:
Cameron Gutman
2021-07-14 20:00:53 -05:00
parent 41c5b62b1a
commit fc4fdd5ee2

View File

@@ -78,7 +78,6 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.lang.reflect.Field;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
@@ -118,6 +117,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private boolean displayedFailureDialog = false; private boolean displayedFailureDialog = false;
private boolean connecting = false; private boolean connecting = false;
private boolean connected = false; private boolean connected = false;
private boolean autoEnterPip = false;
private boolean surfaceCreated = false; private boolean surfaceCreated = false;
private boolean attemptedConnection = false; private boolean attemptedConnection = false;
@@ -571,23 +571,49 @@ public class Game extends Activity implements SurfaceHolder.Callback,
} }
} }
@TargetApi(Build.VERSION_CODES.O)
private PictureInPictureParams getPictureInPictureParams(boolean autoEnter) {
PictureInPictureParams.Builder builder =
new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
.setSourceRectHint(new Rect(
streamView.getLeft(), streamView.getTop(),
streamView.getRight(), streamView.getBottom()));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
builder.setAutoEnterEnabled(autoEnter);
builder.setSeamlessResizeEnabled(true);
}
return builder.build();
}
private void setPipAutoEnter(boolean autoEnter) {
if (!prefConfig.enablePip) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
setPictureInPictureParams(getPictureInPictureParams(autoEnter));
}
else {
autoEnterPip = autoEnter;
}
}
@Override @Override
public void onUserLeaveHint() { public void onUserLeaveHint() {
super.onUserLeaveHint(); super.onUserLeaveHint();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // PiP is only supported on Oreo and later, and we don't need to manually enter PiP on
if (prefConfig.enablePip && connected) { // Android S and later.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (autoEnterPip) {
try { try {
// This has thrown all sorts of weird exceptions on Samsung devices // This has thrown all sorts of weird exceptions on Samsung devices
// running Oreo. Just eat them and close gracefully on leave, rather // running Oreo. Just eat them and close gracefully on leave, rather
// than crashing. // than crashing.
enterPictureInPictureMode( enterPictureInPictureMode(getPictureInPictureParams(false));
new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
.setSourceRectHint(new Rect(
streamView.getLeft(), streamView.getTop(),
streamView.getRight(), streamView.getBottom()))
.build());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -800,6 +826,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private final Runnable hideSystemUi = new Runnable() { private final Runnable hideSystemUi = new Runnable() {
@Override @Override
public void run() { public void run() {
// TODO: Do we want to use WindowInsetsController here on R+ instead of
// SYSTEM_UI_FLAG_IMMERSIVE_STICKY? They seem to do the same thing as of S...
// In multi-window mode on N+, we need to drop our layout flags or we'll // In multi-window mode on N+, we need to drop our layout flags or we'll
// be drawing underneath the system UI. // be drawing underneath the system UI.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode()) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode()) {
@@ -1538,6 +1567,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private void stopConnection() { private void stopConnection() {
if (connecting || connected) { if (connecting || connected) {
setPipAutoEnter(false);
connecting = connected = false; connecting = connected = false;
controllerHandler.stop(); controllerHandler.stop();
@@ -1702,6 +1732,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
spinner = null; spinner = null;
} }
setPipAutoEnter(true);
connected = true; connected = true;
connecting = false; connecting = false;