apt: Refactor sleep/home state handling to be more intuitive, see details:
- Added functions for checking APT state: - aptIsActive - aptShouldClose - aptShouldJumpToHome - aptCheckHomePressRejected (replaces aptIsHomePressed) - Added functions for handling incoming requests: - aptHandleSleep - aptHandleJumpToHome - Added aptJumpToHomeMenu (callable anytime) because why not - aptMainLoop is now aptHandleSleep/JumpToHome + return !aptShouldClose - APTHOOK_ONEXIT is now called during aptExit - Internal refactoring
This commit is contained in:
parent
b48b5da211
commit
5986713066
@ -148,39 +148,52 @@ void aptExit(void);
|
||||
*/
|
||||
Result aptSendCommand(u32* aptcmdbuf);
|
||||
|
||||
/**
|
||||
* @brief Gets whether to allow the system to enter sleep mode.
|
||||
* @return Whether sleep mode is allowed.
|
||||
*/
|
||||
/// Returns true if the application is currently in the foreground.
|
||||
bool aptIsActive(void);
|
||||
|
||||
/// Returns true if the system has told the application to close.
|
||||
bool aptShouldClose(void);
|
||||
|
||||
/// Returns true if the system can enter sleep mode while the application is active.
|
||||
bool aptIsSleepAllowed(void);
|
||||
|
||||
/**
|
||||
* @brief Sets whether to allow the system to enter sleep mode.
|
||||
* @param allowed Whether to allow sleep mode.
|
||||
*/
|
||||
/// Configures whether the system can enter sleep mode while the application is active.
|
||||
void aptSetSleepAllowed(bool allowed);
|
||||
|
||||
/**
|
||||
* @brief Gets whether to allow the system to go back to HOME menu.
|
||||
* @return Whether going back to HOME menu is allowed.
|
||||
*/
|
||||
/// Handles incoming sleep mode requests.
|
||||
void aptHandleSleep(void);
|
||||
|
||||
/// Returns true if the user can press the HOME button to jump back to the HOME menu while the application is active.
|
||||
bool aptIsHomeAllowed(void);
|
||||
|
||||
/**
|
||||
* @brief Sets whether to allow the system to go back to HOME menu.
|
||||
* @param allowed Whether going back to HOME menu is allowed.
|
||||
*/
|
||||
/// Configures whether the user can press the HOME button to jump back to the HOME menu while the application is active.
|
||||
void aptSetHomeAllowed(bool allowed);
|
||||
|
||||
/**
|
||||
* @brief Returns when the HOME button is pressed.
|
||||
* @return Whether the HOME button is being pressed.
|
||||
*/
|
||||
bool aptIsHomePressed(void);
|
||||
/// Returns true if the system requires the application to jump back to the HOME menu.
|
||||
bool aptShouldJumpToHome(void);
|
||||
|
||||
/// Returns true if there is an incoming HOME button press rejected by the policy set by \ref aptSetHomeAllowed (use this to show a "no HOME allowed" icon).
|
||||
bool aptCheckHomePressRejected(void);
|
||||
|
||||
/// \deprecated Alias for \ref aptCheckHomePressRejected.
|
||||
static inline DEPRECATED bool aptIsHomePressed(void)
|
||||
{
|
||||
return aptCheckHomePressRejected();
|
||||
}
|
||||
|
||||
/// Jumps back to the HOME menu.
|
||||
void aptJumpToHomeMenu(void);
|
||||
|
||||
/// Handles incoming jump-to-HOME requests.
|
||||
static inline void aptHandleJumpToHome(void)
|
||||
{
|
||||
if (aptShouldJumpToHome())
|
||||
aptJumpToHomeMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the current APT status. Generally used within a main loop.
|
||||
* @return Whether the application should continue running.
|
||||
* @brief Main function which handles sleep mode and HOME/power buttons - call this at the beginning of every frame.
|
||||
* @return true if the application should keep running, false otherwise (see \ref aptShouldClose).
|
||||
*/
|
||||
bool aptMainLoop(void);
|
||||
|
||||
|
@ -36,22 +36,33 @@ static void* aptMessageFuncData;
|
||||
|
||||
enum
|
||||
{
|
||||
// Current applet state
|
||||
FLAG_ACTIVE = BIT(0),
|
||||
FLAG_ALLOWSLEEP = BIT(1),
|
||||
FLAG_ORDERTOCLOSE = BIT(2),
|
||||
FLAG_SHUTDOWN = BIT(3),
|
||||
FLAG_POWERBUTTON = BIT(4),
|
||||
FLAG_WKUPBYCANCEL = BIT(5),
|
||||
FLAG_WANTSTOSLEEP = BIT(6),
|
||||
FLAG_SLEEPING = BIT(7),
|
||||
FLAG_SPURIOUS = BIT(30),
|
||||
FLAG_EXITED = BIT(31),
|
||||
FLAG_SLEEPING = BIT(1),
|
||||
|
||||
// Sleep handling flags
|
||||
FLAG_ALLOWSLEEP = BIT(2),
|
||||
FLAG_SHOULDSLEEP = BIT(3),
|
||||
|
||||
// Home button flags
|
||||
FLAG_ALLOWHOME = BIT(4),
|
||||
FLAG_SHOULDHOME = BIT(5),
|
||||
FLAG_HOMEREJECTED = BIT(6),
|
||||
|
||||
// Power button flags
|
||||
FLAG_POWERBUTTON = BIT(7),
|
||||
FLAG_SHUTDOWN = BIT(8),
|
||||
|
||||
// Close handling flags
|
||||
FLAG_ORDERTOCLOSE = BIT(9),
|
||||
FLAG_CANCELLED = BIT(10),
|
||||
|
||||
// Miscellaneous
|
||||
FLAG_SPURIOUS = BIT(31),
|
||||
};
|
||||
|
||||
static u8 aptHomeButtonState;
|
||||
static u8 aptRecentHomeButtonState;
|
||||
static u32 aptFlags;
|
||||
static bool aptHomeAllowed = true;
|
||||
static u32 aptParameters[0x1000/4];
|
||||
static u64 aptChainloadTid;
|
||||
static u8 aptChainloadMediatype;
|
||||
@ -178,8 +189,6 @@ Result aptInit(void)
|
||||
|
||||
if (AtomicPostIncrement(&aptRefCount)) return 0;
|
||||
|
||||
aptHomeAllowed = osGetSystemCoreVersion() == 2;
|
||||
|
||||
// Retrieve APT lock
|
||||
ret = APT_GetLockHandle(0x0, &aptLockHandle);
|
||||
if (R_FAILED(ret)) goto _fail;
|
||||
@ -199,8 +208,12 @@ Result aptInit(void)
|
||||
aptEventHandlerThread = threadCreate(aptEventHandler, 0x0, APT_HANDLER_STACKSIZE, 0x31, -2, true);
|
||||
if (!aptEventHandlerThread) goto _fail3;
|
||||
|
||||
// Enable APT
|
||||
// By default allow sleep mode and home button presses
|
||||
aptFlags = FLAG_ALLOWSLEEP;
|
||||
if (osGetSystemCoreVersion() == 2) // ... except in safe mode, which doesn't have home menu running
|
||||
aptFlags |= FLAG_ALLOWHOME;
|
||||
|
||||
// Enable APT
|
||||
ret = APT_Enable(attr);
|
||||
if (R_FAILED(ret)) goto _fail3;
|
||||
|
||||
@ -228,6 +241,16 @@ _fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool aptIsActive(void)
|
||||
{
|
||||
return (aptFlags & FLAG_ACTIVE) != 0;
|
||||
}
|
||||
|
||||
bool aptShouldClose(void)
|
||||
{
|
||||
return (aptFlags & (FLAG_ORDERTOCLOSE|FLAG_CANCELLED)) != 0;
|
||||
}
|
||||
|
||||
bool aptIsSleepAllowed(void)
|
||||
{
|
||||
return (aptFlags & FLAG_ALLOWSLEEP) != 0;
|
||||
@ -250,17 +273,37 @@ void aptSetSleepAllowed(bool allowed)
|
||||
|
||||
bool aptIsHomeAllowed(void)
|
||||
{
|
||||
return aptHomeAllowed;
|
||||
return (aptFlags & FLAG_ALLOWHOME) != 0;
|
||||
}
|
||||
|
||||
void aptSetHomeAllowed(bool allowed)
|
||||
{
|
||||
aptHomeAllowed = allowed;
|
||||
if (allowed)
|
||||
aptFlags |= FLAG_ALLOWHOME;
|
||||
else
|
||||
aptFlags &= ~FLAG_ALLOWHOME;
|
||||
}
|
||||
|
||||
bool aptIsHomePressed(void)
|
||||
bool aptShouldJumpToHome(void)
|
||||
{
|
||||
return aptRecentHomeButtonState;
|
||||
return aptHomeButtonState || (aptFlags & (FLAG_SHOULDHOME|FLAG_POWERBUTTON)) != 0;
|
||||
}
|
||||
|
||||
bool aptCheckHomePressRejected(void)
|
||||
{
|
||||
if (aptFlags & FLAG_HOMEREJECTED)
|
||||
{
|
||||
aptFlags &= ~FLAG_HOMEREJECTED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void aptClearJumpToHome(void)
|
||||
{
|
||||
aptHomeButtonState = 0;
|
||||
APT_UnlockTransition(0x01);
|
||||
APT_SleepIfShellClosed();
|
||||
}
|
||||
|
||||
void aptSetChainloader(u64 programID, u8 mediatype)
|
||||
@ -283,10 +326,12 @@ void aptExit(void)
|
||||
|
||||
if (!aptIsCrippled())
|
||||
{
|
||||
bool exited = (aptFlags & FLAG_EXITED) != 0;
|
||||
if (exited || !aptIsReinit())
|
||||
bool closing = aptShouldClose();
|
||||
if (closing)
|
||||
aptCallHook(APTHOOK_ONEXIT);
|
||||
if (closing || !aptIsReinit())
|
||||
{
|
||||
if (!exited && aptIsChainload())
|
||||
if (!closing && aptIsChainload())
|
||||
{
|
||||
// Check if Home Menu exists and has been launched
|
||||
bool hmRegistered;
|
||||
@ -390,18 +435,24 @@ void aptEventHandler(void *arg)
|
||||
switch (signal)
|
||||
{
|
||||
case APTSIGNAL_HOMEBUTTON:
|
||||
if (!aptHomeButtonState) aptHomeButtonState = 1;
|
||||
break;
|
||||
case APTSIGNAL_HOMEBUTTON2:
|
||||
if (!aptHomeButtonState) aptHomeButtonState = 2;
|
||||
if (!aptIsActive())
|
||||
break;
|
||||
else if (!aptIsHomeAllowed())
|
||||
{
|
||||
aptFlags |= FLAG_HOMEREJECTED;
|
||||
aptClearJumpToHome();
|
||||
}
|
||||
else if (!aptHomeButtonState)
|
||||
aptHomeButtonState = signal == APTSIGNAL_HOMEBUTTON ? 1 : 2;
|
||||
break;
|
||||
case APTSIGNAL_SLEEP_QUERY:
|
||||
{
|
||||
APT_QueryReply reply;
|
||||
if (aptFlags & (FLAG_ORDERTOCLOSE|FLAG_WKUPBYCANCEL))
|
||||
if (aptShouldClose())
|
||||
// Reject sleep if we are expected to close
|
||||
reply = APTREPLY_REJECT;
|
||||
else if (aptFlags & FLAG_ACTIVE)
|
||||
else if (aptIsActive())
|
||||
// Accept sleep based on user setting if we are active
|
||||
reply = aptIsSleepAllowed() ? APTREPLY_ACCEPT : APTREPLY_REJECT;
|
||||
else
|
||||
@ -414,24 +465,24 @@ void aptEventHandler(void *arg)
|
||||
break;
|
||||
}
|
||||
case APTSIGNAL_SLEEP_CANCEL:
|
||||
if (aptFlags & FLAG_ACTIVE)
|
||||
aptFlags &= ~FLAG_WANTSTOSLEEP;
|
||||
if (aptIsActive())
|
||||
aptFlags &= ~FLAG_SHOULDSLEEP;
|
||||
break;
|
||||
case APTSIGNAL_SLEEP_ENTER:
|
||||
_aptDebug(10, aptFlags);
|
||||
if (aptFlags & FLAG_ACTIVE)
|
||||
aptFlags |= FLAG_WANTSTOSLEEP;
|
||||
if (aptIsActive())
|
||||
aptFlags |= FLAG_SHOULDSLEEP;
|
||||
else
|
||||
// Since we are not active, this must be handled here.
|
||||
APT_ReplySleepNotificationComplete(envGetAptAppId());
|
||||
break;
|
||||
case APTSIGNAL_SLEEP_WAKEUP:
|
||||
if (!(aptFlags & FLAG_ACTIVE))
|
||||
if (!aptIsActive())
|
||||
break;
|
||||
if (aptFlags & FLAG_SLEEPING)
|
||||
LightEvent_Signal(&aptSleepEvent);
|
||||
else
|
||||
aptFlags &= ~FLAG_WANTSTOSLEEP;
|
||||
aptFlags &= ~FLAG_SHOULDSLEEP;
|
||||
break;
|
||||
case APTSIGNAL_SHUTDOWN:
|
||||
aptFlags |= FLAG_ORDERTOCLOSE | FLAG_SHUTDOWN;
|
||||
@ -504,7 +555,7 @@ APT_Command aptWaitForWakeUp(APT_Transition transition)
|
||||
}
|
||||
|
||||
if (cmd == APTCMD_WAKEUP_CANCEL)
|
||||
aptFlags |= FLAG_WKUPBYCANCEL;
|
||||
aptFlags |= FLAG_CANCELLED;
|
||||
|
||||
if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
|
||||
{
|
||||
@ -512,6 +563,7 @@ APT_Command aptWaitForWakeUp(APT_Transition transition)
|
||||
APT_SleepIfShellClosed();
|
||||
} else
|
||||
{
|
||||
aptFlags |= FLAG_SHOULDHOME;
|
||||
aptHomeButtonState = 1;
|
||||
APT_LockTransition(0x01, true);
|
||||
}
|
||||
@ -519,11 +571,7 @@ APT_Command aptWaitForWakeUp(APT_Transition transition)
|
||||
if (transition == TR_JUMPTOMENU || transition == TR_LIBAPPLET || transition == TR_SYSAPPLET || transition == TR_APPJUMP)
|
||||
{
|
||||
if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
|
||||
{
|
||||
aptHomeButtonState = 0;
|
||||
APT_UnlockTransition(0x01);
|
||||
APT_SleepIfShellClosed();
|
||||
}
|
||||
aptClearJumpToHome();
|
||||
}
|
||||
|
||||
return cmd;
|
||||
@ -637,12 +685,12 @@ static void aptScreenTransfer(NS_APPID appId, bool sysApplet)
|
||||
APT_SendCaptureBufferInfo(&capinfo);
|
||||
}
|
||||
|
||||
static void aptProcessJumpToMenu(void)
|
||||
void aptJumpToHomeMenu(void)
|
||||
{
|
||||
bool sleep = aptIsSleepAllowed();
|
||||
aptSetSleepAllowed(false);
|
||||
|
||||
aptFlags &= ~FLAG_SPURIOUS; // If we haven't received a spurious wakeup by now, we probably never will (see aptInit)
|
||||
aptFlags &= ~(FLAG_SHOULDHOME|FLAG_SPURIOUS); // If we haven't received a spurious wakeup by now, we probably never will (see aptInit)
|
||||
APT_PrepareToJumpToHomeMenu();
|
||||
|
||||
aptCallHook(APTHOOK_ONSUSPEND);
|
||||
@ -658,46 +706,27 @@ static void aptProcessJumpToMenu(void)
|
||||
aptSetSleepAllowed(sleep);
|
||||
}
|
||||
|
||||
void aptHandleSleep(void)
|
||||
{
|
||||
if (!(aptFlags & FLAG_SHOULDSLEEP))
|
||||
return;
|
||||
|
||||
aptFlags = (aptFlags &~ FLAG_SHOULDSLEEP) | FLAG_SLEEPING;
|
||||
aptCallHook(APTHOOK_ONSLEEP);
|
||||
APT_ReplySleepNotificationComplete(envGetAptAppId());
|
||||
LightEvent_Wait(&aptSleepEvent);
|
||||
aptFlags &= ~FLAG_SLEEPING;
|
||||
|
||||
if (aptIsActive())
|
||||
GSPGPU_SetLcdForceBlack(0);
|
||||
aptCallHook(APTHOOK_ONWAKEUP);
|
||||
}
|
||||
|
||||
bool aptMainLoop(void)
|
||||
{
|
||||
if (aptIsCrippled()) return true;
|
||||
if (aptFlags & FLAG_EXITED) return false;
|
||||
|
||||
if (aptRecentHomeButtonState) aptRecentHomeButtonState = 0;
|
||||
|
||||
if (aptFlags & FLAG_WANTSTOSLEEP)
|
||||
{
|
||||
aptFlags = (aptFlags &~ FLAG_WANTSTOSLEEP) | FLAG_SLEEPING;
|
||||
aptCallHook(APTHOOK_ONSLEEP);
|
||||
APT_ReplySleepNotificationComplete(envGetAptAppId());
|
||||
LightEvent_Wait(&aptSleepEvent);
|
||||
aptFlags &= ~FLAG_SLEEPING;
|
||||
|
||||
if (aptFlags & FLAG_ACTIVE)
|
||||
GSPGPU_SetLcdForceBlack(0);
|
||||
aptCallHook(APTHOOK_ONWAKEUP);
|
||||
}
|
||||
else if ((aptFlags & FLAG_POWERBUTTON) || aptHomeButtonState)
|
||||
{
|
||||
if (aptHomeAllowed || (aptFlags & FLAG_POWERBUTTON))
|
||||
aptProcessJumpToMenu();
|
||||
else
|
||||
{
|
||||
aptRecentHomeButtonState = aptHomeButtonState;
|
||||
aptHomeButtonState = 0;
|
||||
APT_UnlockTransition(0x01);
|
||||
APT_SleepIfShellClosed();
|
||||
}
|
||||
}
|
||||
|
||||
if (aptFlags & (FLAG_ORDERTOCLOSE|FLAG_WKUPBYCANCEL))
|
||||
{
|
||||
aptFlags |= FLAG_EXITED;
|
||||
aptCallHook(APTHOOK_ONEXIT);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
aptHandleSleep();
|
||||
aptHandleJumpToHome();
|
||||
return !aptShouldClose();
|
||||
}
|
||||
|
||||
void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param)
|
||||
|
Loading…
Reference in New Issue
Block a user