@@ -5351,6 +5351,83 @@ public void Devices_CanSkipProcessingEventsWhileInBackground()
53515351 Assert . That ( performedCount , Is . EqualTo ( 1 ) ) ;
53525352 }
53535353
5354+ [ Test ]
5355+ [ Category ( "Devices" ) ]
5356+ [ TestCase ( true , true ) ]
5357+ [ TestCase ( true , false ) ]
5358+ [ TestCase ( false , true ) ]
5359+ [ TestCase ( false , false ) ]
5360+ /*
5361+ * Ignore focus | ResetAndDisableNonBackgroundDevices | ResetAndDisableAllDevices
5362+ * runinbackground true & device runinbackground true run run dont run
5363+ * runinbackground true & device runinbackground false run dont run dont run
5364+ * runinbackground false & device runinbackground true dont run dont run dont run
5365+ * runinbackground false & device runinbackground false dont run dont run dont run
5366+
5367+ * in editor run in background is always true and gameview is treated as gain/lose focus
5368+ ** in development players on desktop platforms, the setting run in background is force-enabled during the build process.
5369+ *** on platforms such as Android and iOS, the app will not run when it is not in the foreground
5370+ */
5371+ public unsafe void Devices_GamepadCanSkipEventsWhileInBackground ( bool runInBackground , bool runDeviceInBackground )
5372+ {
5373+ InputSystem . runInBackground = runInBackground ;
5374+ InputSystem . settings . backgroundBehavior = InputSettings . BackgroundBehavior . ResetAndDisableNonBackgroundDevices ;
5375+
5376+ var time = 0 ;
5377+ var gamepad = InputSystem . AddDevice < Gamepad > ( ) ;
5378+ var pressAction = new InputAction ( "Press" , binding : "<Gamepad>/buttonSouth" ) ;
5379+ var performedCount = 0 ;
5380+
5381+ long DeviceCallback ( string device , InputDeviceCommand * command , bool canRunInBackground )
5382+ {
5383+ if ( command ->type == QueryCanRunInBackground . Type )
5384+ {
5385+ ( ( QueryCanRunInBackground * ) command ) ->canRunInBackground = canRunInBackground ;
5386+ return InputDeviceCommand . GenericSuccess ;
5387+ }
5388+ return InputDeviceCommand . GenericFailure ;
5389+ }
5390+
5391+ runtime . SetDeviceCommandCallback ( gamepad ,
5392+ ( id , command ) =>
5393+ DeviceCallback ( "Gamepad" , command , runDeviceInBackground ) ) ;
5394+
5395+ pressAction . performed += ctx =>
5396+ {
5397+ performedCount ++ ;
5398+ } ;
5399+ pressAction . Enable ( ) ;
5400+
5401+ Assert . That ( gamepad . enabled , Is . True ) ;
5402+
5403+ // Lose focus
5404+ ScheduleFocusChangedEvent ( applicationHasFocus : false ) ;
5405+ InputSystem . Update ( InputUpdateType . Dynamic ) ;
5406+
5407+ Assert . That ( gamepad . canRunInBackground , Is . EqualTo ( runDeviceInBackground ) ) ;
5408+
5409+ // Device should only be enabled if app runs in background and device can run in background
5410+ if ( runInBackground && runDeviceInBackground )
5411+ Assert . That ( gamepad . enabled , Is . True ) ;
5412+ else
5413+ Assert . That ( gamepad . enabled , Is . False ) ;
5414+
5415+ // Simulate noisy controller sending many events while in background
5416+ for ( int i = 0 ; i < 100 ; i ++ )
5417+ {
5418+ Press ( gamepad . buttonSouth , queueEventOnly : true , time : time ++ ) ;
5419+ Release ( gamepad . buttonSouth , queueEventOnly : true , time : time ++ ) ;
5420+ }
5421+
5422+ InputSystem . Update ( InputUpdateType . Dynamic ) ;
5423+
5424+ // If device should be disabled, events should have been discarded
5425+ if ( runInBackground && runDeviceInBackground )
5426+ Assert . That ( performedCount , Is . EqualTo ( 100 ) ) ;
5427+ else
5428+ Assert . That ( performedCount , Is . EqualTo ( 0 ) ) ;
5429+ }
5430+
53545431 [ Test ]
53555432 [ Category ( "Devices" ) ]
53565433 public void Devices_CanMarkDeviceAsBeingAbleToRunInBackground_ThroughIOCTL ( )
0 commit comments