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);
|
Result aptSendCommand(u32* aptcmdbuf);
|
||||||
|
|
||||||
/**
|
/// Returns true if the application is currently in the foreground.
|
||||||
* @brief Gets whether to allow the system to enter sleep mode.
|
bool aptIsActive(void);
|
||||||
* @return Whether sleep mode is allowed.
|
|
||||||
*/
|
/// 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);
|
bool aptIsSleepAllowed(void);
|
||||||
|
|
||||||
/**
|
/// Configures whether the system can enter sleep mode while the application is active.
|
||||||
* @brief Sets whether to allow the system to enter sleep mode.
|
|
||||||
* @param allowed Whether to allow sleep mode.
|
|
||||||
*/
|
|
||||||
void aptSetSleepAllowed(bool allowed);
|
void aptSetSleepAllowed(bool allowed);
|
||||||
|
|
||||||
/**
|
/// Handles incoming sleep mode requests.
|
||||||
* @brief Gets whether to allow the system to go back to HOME menu.
|
void aptHandleSleep(void);
|
||||||
* @return Whether going back to HOME menu is allowed.
|
|
||||||
*/
|
/// 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);
|
bool aptIsHomeAllowed(void);
|
||||||
|
|
||||||
/**
|
/// Configures whether the user can press the HOME button to jump back to the HOME menu while the application is active.
|
||||||
* @brief Sets whether to allow the system to go back to HOME menu.
|
|
||||||
* @param allowed Whether going back to HOME menu is allowed.
|
|
||||||
*/
|
|
||||||
void aptSetHomeAllowed(bool allowed);
|
void aptSetHomeAllowed(bool allowed);
|
||||||
|
|
||||||
/**
|
/// Returns true if the system requires the application to jump back to the HOME menu.
|
||||||
* @brief Returns when the HOME button is pressed.
|
bool aptShouldJumpToHome(void);
|
||||||
* @return Whether the HOME button is being pressed.
|
|
||||||
*/
|
/// 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 aptIsHomePressed(void);
|
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.
|
* @brief Main function which handles sleep mode and HOME/power buttons - call this at the beginning of every frame.
|
||||||
* @return Whether the application should continue running.
|
* @return true if the application should keep running, false otherwise (see \ref aptShouldClose).
|
||||||
*/
|
*/
|
||||||
bool aptMainLoop(void);
|
bool aptMainLoop(void);
|
||||||
|
|
||||||
|
@ -36,22 +36,33 @@ static void* aptMessageFuncData;
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
// Current applet state
|
||||||
FLAG_ACTIVE = BIT(0),
|
FLAG_ACTIVE = BIT(0),
|
||||||
FLAG_ALLOWSLEEP = BIT(1),
|
FLAG_SLEEPING = BIT(1),
|
||||||
FLAG_ORDERTOCLOSE = BIT(2),
|
|
||||||
FLAG_SHUTDOWN = BIT(3),
|
// Sleep handling flags
|
||||||
FLAG_POWERBUTTON = BIT(4),
|
FLAG_ALLOWSLEEP = BIT(2),
|
||||||
FLAG_WKUPBYCANCEL = BIT(5),
|
FLAG_SHOULDSLEEP = BIT(3),
|
||||||
FLAG_WANTSTOSLEEP = BIT(6),
|
|
||||||
FLAG_SLEEPING = BIT(7),
|
// Home button flags
|
||||||
FLAG_SPURIOUS = BIT(30),
|
FLAG_ALLOWHOME = BIT(4),
|
||||||
FLAG_EXITED = BIT(31),
|
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 aptHomeButtonState;
|
||||||
static u8 aptRecentHomeButtonState;
|
|
||||||
static u32 aptFlags;
|
static u32 aptFlags;
|
||||||
static bool aptHomeAllowed = true;
|
|
||||||
static u32 aptParameters[0x1000/4];
|
static u32 aptParameters[0x1000/4];
|
||||||
static u64 aptChainloadTid;
|
static u64 aptChainloadTid;
|
||||||
static u8 aptChainloadMediatype;
|
static u8 aptChainloadMediatype;
|
||||||
@ -178,8 +189,6 @@ Result aptInit(void)
|
|||||||
|
|
||||||
if (AtomicPostIncrement(&aptRefCount)) return 0;
|
if (AtomicPostIncrement(&aptRefCount)) return 0;
|
||||||
|
|
||||||
aptHomeAllowed = osGetSystemCoreVersion() == 2;
|
|
||||||
|
|
||||||
// Retrieve APT lock
|
// Retrieve APT lock
|
||||||
ret = APT_GetLockHandle(0x0, &aptLockHandle);
|
ret = APT_GetLockHandle(0x0, &aptLockHandle);
|
||||||
if (R_FAILED(ret)) goto _fail;
|
if (R_FAILED(ret)) goto _fail;
|
||||||
@ -199,8 +208,12 @@ Result aptInit(void)
|
|||||||
aptEventHandlerThread = threadCreate(aptEventHandler, 0x0, APT_HANDLER_STACKSIZE, 0x31, -2, true);
|
aptEventHandlerThread = threadCreate(aptEventHandler, 0x0, APT_HANDLER_STACKSIZE, 0x31, -2, true);
|
||||||
if (!aptEventHandlerThread) goto _fail3;
|
if (!aptEventHandlerThread) goto _fail3;
|
||||||
|
|
||||||
// Enable APT
|
// By default allow sleep mode and home button presses
|
||||||
aptFlags = FLAG_ALLOWSLEEP;
|
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);
|
ret = APT_Enable(attr);
|
||||||
if (R_FAILED(ret)) goto _fail3;
|
if (R_FAILED(ret)) goto _fail3;
|
||||||
|
|
||||||
@ -228,6 +241,16 @@ _fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool aptIsActive(void)
|
||||||
|
{
|
||||||
|
return (aptFlags & FLAG_ACTIVE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool aptShouldClose(void)
|
||||||
|
{
|
||||||
|
return (aptFlags & (FLAG_ORDERTOCLOSE|FLAG_CANCELLED)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool aptIsSleepAllowed(void)
|
bool aptIsSleepAllowed(void)
|
||||||
{
|
{
|
||||||
return (aptFlags & FLAG_ALLOWSLEEP) != 0;
|
return (aptFlags & FLAG_ALLOWSLEEP) != 0;
|
||||||
@ -250,17 +273,37 @@ void aptSetSleepAllowed(bool allowed)
|
|||||||
|
|
||||||
bool aptIsHomeAllowed(void)
|
bool aptIsHomeAllowed(void)
|
||||||
{
|
{
|
||||||
return aptHomeAllowed;
|
return (aptFlags & FLAG_ALLOWHOME) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aptSetHomeAllowed(bool allowed)
|
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)
|
void aptSetChainloader(u64 programID, u8 mediatype)
|
||||||
@ -283,10 +326,12 @@ void aptExit(void)
|
|||||||
|
|
||||||
if (!aptIsCrippled())
|
if (!aptIsCrippled())
|
||||||
{
|
{
|
||||||
bool exited = (aptFlags & FLAG_EXITED) != 0;
|
bool closing = aptShouldClose();
|
||||||
if (exited || !aptIsReinit())
|
if (closing)
|
||||||
|
aptCallHook(APTHOOK_ONEXIT);
|
||||||
|
if (closing || !aptIsReinit())
|
||||||
{
|
{
|
||||||
if (!exited && aptIsChainload())
|
if (!closing && aptIsChainload())
|
||||||
{
|
{
|
||||||
// Check if Home Menu exists and has been launched
|
// Check if Home Menu exists and has been launched
|
||||||
bool hmRegistered;
|
bool hmRegistered;
|
||||||
@ -390,18 +435,24 @@ void aptEventHandler(void *arg)
|
|||||||
switch (signal)
|
switch (signal)
|
||||||
{
|
{
|
||||||
case APTSIGNAL_HOMEBUTTON:
|
case APTSIGNAL_HOMEBUTTON:
|
||||||
if (!aptHomeButtonState) aptHomeButtonState = 1;
|
|
||||||
break;
|
|
||||||
case APTSIGNAL_HOMEBUTTON2:
|
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;
|
break;
|
||||||
case APTSIGNAL_SLEEP_QUERY:
|
case APTSIGNAL_SLEEP_QUERY:
|
||||||
{
|
{
|
||||||
APT_QueryReply reply;
|
APT_QueryReply reply;
|
||||||
if (aptFlags & (FLAG_ORDERTOCLOSE|FLAG_WKUPBYCANCEL))
|
if (aptShouldClose())
|
||||||
// Reject sleep if we are expected to close
|
// Reject sleep if we are expected to close
|
||||||
reply = APTREPLY_REJECT;
|
reply = APTREPLY_REJECT;
|
||||||
else if (aptFlags & FLAG_ACTIVE)
|
else if (aptIsActive())
|
||||||
// Accept sleep based on user setting if we are active
|
// Accept sleep based on user setting if we are active
|
||||||
reply = aptIsSleepAllowed() ? APTREPLY_ACCEPT : APTREPLY_REJECT;
|
reply = aptIsSleepAllowed() ? APTREPLY_ACCEPT : APTREPLY_REJECT;
|
||||||
else
|
else
|
||||||
@ -414,24 +465,24 @@ void aptEventHandler(void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APTSIGNAL_SLEEP_CANCEL:
|
case APTSIGNAL_SLEEP_CANCEL:
|
||||||
if (aptFlags & FLAG_ACTIVE)
|
if (aptIsActive())
|
||||||
aptFlags &= ~FLAG_WANTSTOSLEEP;
|
aptFlags &= ~FLAG_SHOULDSLEEP;
|
||||||
break;
|
break;
|
||||||
case APTSIGNAL_SLEEP_ENTER:
|
case APTSIGNAL_SLEEP_ENTER:
|
||||||
_aptDebug(10, aptFlags);
|
_aptDebug(10, aptFlags);
|
||||||
if (aptFlags & FLAG_ACTIVE)
|
if (aptIsActive())
|
||||||
aptFlags |= FLAG_WANTSTOSLEEP;
|
aptFlags |= FLAG_SHOULDSLEEP;
|
||||||
else
|
else
|
||||||
// Since we are not active, this must be handled here.
|
// Since we are not active, this must be handled here.
|
||||||
APT_ReplySleepNotificationComplete(envGetAptAppId());
|
APT_ReplySleepNotificationComplete(envGetAptAppId());
|
||||||
break;
|
break;
|
||||||
case APTSIGNAL_SLEEP_WAKEUP:
|
case APTSIGNAL_SLEEP_WAKEUP:
|
||||||
if (!(aptFlags & FLAG_ACTIVE))
|
if (!aptIsActive())
|
||||||
break;
|
break;
|
||||||
if (aptFlags & FLAG_SLEEPING)
|
if (aptFlags & FLAG_SLEEPING)
|
||||||
LightEvent_Signal(&aptSleepEvent);
|
LightEvent_Signal(&aptSleepEvent);
|
||||||
else
|
else
|
||||||
aptFlags &= ~FLAG_WANTSTOSLEEP;
|
aptFlags &= ~FLAG_SHOULDSLEEP;
|
||||||
break;
|
break;
|
||||||
case APTSIGNAL_SHUTDOWN:
|
case APTSIGNAL_SHUTDOWN:
|
||||||
aptFlags |= FLAG_ORDERTOCLOSE | FLAG_SHUTDOWN;
|
aptFlags |= FLAG_ORDERTOCLOSE | FLAG_SHUTDOWN;
|
||||||
@ -504,7 +555,7 @@ APT_Command aptWaitForWakeUp(APT_Transition transition)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == APTCMD_WAKEUP_CANCEL)
|
if (cmd == APTCMD_WAKEUP_CANCEL)
|
||||||
aptFlags |= FLAG_WKUPBYCANCEL;
|
aptFlags |= FLAG_CANCELLED;
|
||||||
|
|
||||||
if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
|
if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
|
||||||
{
|
{
|
||||||
@ -512,6 +563,7 @@ APT_Command aptWaitForWakeUp(APT_Transition transition)
|
|||||||
APT_SleepIfShellClosed();
|
APT_SleepIfShellClosed();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
aptFlags |= FLAG_SHOULDHOME;
|
||||||
aptHomeButtonState = 1;
|
aptHomeButtonState = 1;
|
||||||
APT_LockTransition(0x01, true);
|
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 (transition == TR_JUMPTOMENU || transition == TR_LIBAPPLET || transition == TR_SYSAPPLET || transition == TR_APPJUMP)
|
||||||
{
|
{
|
||||||
if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
|
if (cmd != APTCMD_WAKEUP_JUMPTOHOME)
|
||||||
{
|
aptClearJumpToHome();
|
||||||
aptHomeButtonState = 0;
|
|
||||||
APT_UnlockTransition(0x01);
|
|
||||||
APT_SleepIfShellClosed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
@ -637,12 +685,12 @@ static void aptScreenTransfer(NS_APPID appId, bool sysApplet)
|
|||||||
APT_SendCaptureBufferInfo(&capinfo);
|
APT_SendCaptureBufferInfo(&capinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aptProcessJumpToMenu(void)
|
void aptJumpToHomeMenu(void)
|
||||||
{
|
{
|
||||||
bool sleep = aptIsSleepAllowed();
|
bool sleep = aptIsSleepAllowed();
|
||||||
aptSetSleepAllowed(false);
|
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();
|
APT_PrepareToJumpToHomeMenu();
|
||||||
|
|
||||||
aptCallHook(APTHOOK_ONSUSPEND);
|
aptCallHook(APTHOOK_ONSUSPEND);
|
||||||
@ -658,46 +706,27 @@ static void aptProcessJumpToMenu(void)
|
|||||||
aptSetSleepAllowed(sleep);
|
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)
|
bool aptMainLoop(void)
|
||||||
{
|
{
|
||||||
if (aptIsCrippled()) return true;
|
aptHandleSleep();
|
||||||
if (aptFlags & FLAG_EXITED) return false;
|
aptHandleJumpToHome();
|
||||||
|
return !aptShouldClose();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param)
|
void aptHook(aptHookCookie* cookie, aptHookFn callback, void* param)
|
||||||
|
Loading…
Reference in New Issue
Block a user