mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-04-22 16:26:41 +00:00
Prevent PiP entry while the USB permission dialog is open
This commit is contained in:
@@ -87,7 +87,7 @@ import java.util.Locale;
|
|||||||
public class Game extends Activity implements SurfaceHolder.Callback,
|
public class Game extends Activity implements SurfaceHolder.Callback,
|
||||||
OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener,
|
OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener,
|
||||||
OnSystemUiVisibilityChangeListener, GameGestures, StreamView.InputCallbacks,
|
OnSystemUiVisibilityChangeListener, GameGestures, StreamView.InputCallbacks,
|
||||||
PerfOverlayListener
|
PerfOverlayListener, UsbDriverService.UsbDriverStateListener
|
||||||
{
|
{
|
||||||
private int lastButtonState = 0;
|
private int lastButtonState = 0;
|
||||||
|
|
||||||
@@ -121,6 +121,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
private boolean autoEnterPip = false;
|
private boolean autoEnterPip = false;
|
||||||
private boolean surfaceCreated = false;
|
private boolean surfaceCreated = false;
|
||||||
private boolean attemptedConnection = false;
|
private boolean attemptedConnection = false;
|
||||||
|
private int suppressPipRefCount = 0;
|
||||||
private String pcName;
|
private String pcName;
|
||||||
private String appName;
|
private String appName;
|
||||||
|
|
||||||
@@ -153,6 +154,8 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
||||||
UsbDriverService.UsbDriverBinder binder = (UsbDriverService.UsbDriverBinder) iBinder;
|
UsbDriverService.UsbDriverBinder binder = (UsbDriverService.UsbDriverBinder) iBinder;
|
||||||
binder.setListener(controllerHandler);
|
binder.setListener(controllerHandler);
|
||||||
|
binder.setStateListener(Game.this);
|
||||||
|
binder.start();
|
||||||
connectedToUsbDriverService = true;
|
connectedToUsbDriverService = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,11 +576,13 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPipAutoEnter(boolean autoEnter) {
|
private void updatePipAutoEnter() {
|
||||||
if (!prefConfig.enablePip) {
|
if (!prefConfig.enablePip) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean autoEnter = connected && suppressPipRefCount == 0;
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
setPictureInPictureParams(getPictureInPictureParams(autoEnter));
|
setPictureInPictureParams(getPictureInPictureParams(autoEnter));
|
||||||
}
|
}
|
||||||
@@ -1608,8 +1613,8 @@ 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;
|
||||||
|
updatePipAutoEnter();
|
||||||
|
|
||||||
controllerHandler.stop();
|
controllerHandler.stop();
|
||||||
|
|
||||||
@@ -1776,9 +1781,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
spinner = null;
|
spinner = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setPipAutoEnter(true);
|
|
||||||
connected = true;
|
connected = true;
|
||||||
connecting = false;
|
connecting = false;
|
||||||
|
updatePipAutoEnter();
|
||||||
|
|
||||||
// Hide the mouse cursor now after a short delay.
|
// Hide the mouse cursor now after a short delay.
|
||||||
// Doing it before dismissing the spinner seems to be undone
|
// Doing it before dismissing the spinner seems to be undone
|
||||||
@@ -1976,4 +1981,18 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUsbPermissionPromptStarting() {
|
||||||
|
// Disable PiP auto-enter while the USB permission prompt is on-screen. This prevents
|
||||||
|
// us from entering PiP while the user is interacting with the OS permission dialog.
|
||||||
|
suppressPipRefCount++;
|
||||||
|
updatePipAutoEnter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUsbPermissionPromptCompleted() {
|
||||||
|
suppressPipRefCount--;
|
||||||
|
updatePipAutoEnter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
|
|
||||||
private UsbManager usbManager;
|
private UsbManager usbManager;
|
||||||
private PreferenceConfiguration prefConfig;
|
private PreferenceConfiguration prefConfig;
|
||||||
|
private boolean started;
|
||||||
|
|
||||||
private final UsbEventReceiver receiver = new UsbEventReceiver();
|
private final UsbEventReceiver receiver = new UsbEventReceiver();
|
||||||
private final UsbDriverBinder binder = new UsbDriverBinder();
|
private final UsbDriverBinder binder = new UsbDriverBinder();
|
||||||
@@ -36,6 +37,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
private final ArrayList<AbstractController> controllers = new ArrayList<>();
|
private final ArrayList<AbstractController> controllers = new ArrayList<>();
|
||||||
|
|
||||||
private UsbDriverListener listener;
|
private UsbDriverListener listener;
|
||||||
|
private UsbDriverStateListener stateListener;
|
||||||
private int nextDeviceId;
|
private int nextDeviceId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -93,6 +95,11 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
else if (action.equals(ACTION_USB_PERMISSION)) {
|
else if (action.equals(ACTION_USB_PERMISSION)) {
|
||||||
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||||
|
|
||||||
|
// Permission dialog is now closed
|
||||||
|
if (stateListener != null) {
|
||||||
|
stateListener.onUsbPermissionPromptCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
// If we got this far, we've already found we're able to handle this device
|
// If we got this far, we've already found we're able to handle this device
|
||||||
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
|
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
|
||||||
handleUsbDeviceState(device);
|
handleUsbDeviceState(device);
|
||||||
@@ -112,6 +119,18 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStateListener(UsbDriverStateListener stateListener) {
|
||||||
|
UsbDriverService.this.stateListener = stateListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
UsbDriverService.this.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
UsbDriverService.this.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleUsbDeviceState(UsbDevice device) {
|
private void handleUsbDeviceState(UsbDevice device) {
|
||||||
@@ -121,20 +140,29 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
if (!usbManager.hasPermission(device)) {
|
if (!usbManager.hasPermission(device)) {
|
||||||
// Let's ask for permission
|
// Let's ask for permission
|
||||||
try {
|
try {
|
||||||
|
// Tell the state listener that we're about to display a permission dialog
|
||||||
|
if (stateListener != null) {
|
||||||
|
stateListener.onUsbPermissionPromptStarting();
|
||||||
|
}
|
||||||
|
|
||||||
|
int intentFlags = 0;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
// This PendingIntent must be mutable to allow the framework to populate EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED.
|
||||||
|
intentFlags |= PendingIntent.FLAG_MUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
// This function is not documented as throwing any exceptions (denying access
|
// This function is not documented as throwing any exceptions (denying access
|
||||||
// is indicated by calling the PendingIntent with a false result). However,
|
// is indicated by calling the PendingIntent with a false result). However,
|
||||||
// Samsung Knox has some policies which block this request, but rather than
|
// Samsung Knox has some policies which block this request, but rather than
|
||||||
// just returning a false result or returning 0 enumerated devices,
|
// just returning a false result or returning 0 enumerated devices,
|
||||||
// they throw an undocumented SecurityException from this call, crashing
|
// they throw an undocumented SecurityException from this call, crashing
|
||||||
// the whole app. :(
|
// the whole app. :(
|
||||||
int intentFlags = 0;
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
// This PendingIntent must be mutable to allow the framework to populate EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED.
|
|
||||||
intentFlags |= PendingIntent.FLAG_MUTABLE;
|
|
||||||
}
|
|
||||||
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), intentFlags));
|
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), intentFlags));
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
Toast.makeText(this, this.getText(R.string.error_usb_prohibited), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, this.getText(R.string.error_usb_prohibited), Toast.LENGTH_LONG).show();
|
||||||
|
if (stateListener != null) {
|
||||||
|
stateListener.onUsbPermissionPromptCompleted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -225,10 +253,12 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device));
|
((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void start() {
|
||||||
public void onCreate() {
|
if (started) {
|
||||||
this.usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
return;
|
||||||
this.prefConfig = PreferenceConfiguration.readPreferences(this);
|
}
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
|
||||||
// Register for USB attach broadcasts and permission completions
|
// Register for USB attach broadcasts and permission completions
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
@@ -250,14 +280,16 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void stop() {
|
||||||
public void onDestroy() {
|
if (!started) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
started = false;
|
||||||
|
|
||||||
// Stop the attachment receiver
|
// Stop the attachment receiver
|
||||||
unregisterReceiver(receiver);
|
unregisterReceiver(receiver);
|
||||||
|
|
||||||
// Remove listeners
|
|
||||||
listener = null;
|
|
||||||
|
|
||||||
// Stop all controllers
|
// Stop all controllers
|
||||||
while (controllers.size() > 0) {
|
while (controllers.size() > 0) {
|
||||||
// Stop and remove the controller
|
// Stop and remove the controller
|
||||||
@@ -265,8 +297,28 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
this.usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
||||||
|
this.prefConfig = PreferenceConfiguration.readPreferences(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
stop();
|
||||||
|
|
||||||
|
// Remove listeners
|
||||||
|
listener = null;
|
||||||
|
stateListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return binder;
|
return binder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface UsbDriverStateListener {
|
||||||
|
void onUsbPermissionPromptStarting();
|
||||||
|
void onUsbPermissionPromptCompleted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user