Page MenuHomePhabricator

[native] c++ interface to kill app on iOS and Android
ClosedPublic

Authored by kamil on Nov 11 2022, 6:05 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Dec 19, 8:16 PM
Unknown Object (File)
Thu, Dec 19, 8:16 PM
Unknown Object (File)
Thu, Dec 19, 8:16 PM
Unknown Object (File)
Thu, Dec 19, 8:16 PM
Unknown Object (File)
Thu, Dec 19, 8:16 PM
Unknown Object (File)
Thu, Dec 19, 8:14 PM
Unknown Object (File)
Sat, Nov 30, 8:23 PM
Unknown Object (File)
Sat, Nov 30, 11:06 AM

Details

Summary

context: ENG-2158

This code will not generate crash reports, but simply exit the app.

It uses the same killing methods as already used react-native-exit-app but it's adapted to use this on c++ level and wrapped inside our logic.

Probably in the future, we can remove react-native-exit-app dependency and use this function exposed via CommCoreModule.

Test Plan
  1. Expose terminate function via CommCoreModule and pin to eg. dev tools inside profile tab.
  2. Build this for both iOS and Android, check if it exits the app without any additional errors.
  3. Check if the crash report wasn't generated.
  4. Test on both physical devices.

Diff Detail

Repository
rCOMM Comm
Branch
interface-to-kill-app
Lint
No Lint Coverage
Unit
No Test Coverage

Event Timeline

kamil held this revision as a draft.
kamil published this revision for review.Nov 11 2022, 6:21 AM
kamil edited the summary of this revision. (Show Details)
kamil edited the test plan for this revision. (Show Details)
native/android/app/src/main/java/app/comm/android/fbjni/TerminateApp.java
5 ↗(On Diff #18378)
native/ios/Comm/TerminateApp.mm
9 ↗(On Diff #18378)

I think it is important that you get familiar with the discussion under this link: https://stackoverflow.com/questions/355168/proper-way-to-exit-iphone-application.
In summary people say it is strongly discouraged by Apple to use exit(0) to programatically exit the app and by doing so we risk that we might not pass apple review. Some comments share Obj-C code snippets on how to programatically exit app "Apple-approved" way.

Looks like you were probably inspired by https://github.com/wumke/react-native-exit-app. Therefore I have to withdraw my concerns from previous comments.

Just because react-native-exit-app does something doesn't mean it's correct... do we have some special reason to trust that package, other than the fact that we use it in the app today?

marcin requested changes to this revision.Nov 16 2022, 1:42 AM
marcin added inline comments.
native/ios/Comm/TerminateApp.mm
4 ↗(On Diff #18378)

I think this import is not necessary. According to source code: https://github.com/facebook/react-native/blob/main/React/Base/RCTBridgeModule.h, exit function is not defined there. What you need is to import native Apple library https://developer.apple.com/documentation/foundation/nsthread/1409404-exit?language=objc:
#import <Foundation/Foundation.h>

This revision now requires changes to proceed.Nov 16 2022, 1:42 AM

Just because react-native-exit-app does something doesn't mean it's correct... do we have some special reason to trust that package, other than the fact that we use it in the app today?

On one hand, as stated in my comments, my concern was that usage of exit(0) to programatically close the app might be rejected during Apple review. On the other hand we have been using react-native-exit-app for some time and I don't recall it being rejected during apple review. The question here is how intrinsic apple review is - do they look into the code of libraries used. If they do then using exit(0) should be fine, but if they don't we might get ourselves into trouble. @ashoat do you think it is reasonable to submit our app for mock apple review to validate this code? We did similar thing when we changes Podfile to enable forbidden API compilation in NotificationService.

I did some research, so few conclusions (about iOS because it seems like the only problem):

In stack overflow posts and any other forums, there is a citation from Apple's Human User Guidelines saying that

Don’t Quit Programmatically
Never quit an iOS application programmatically because people tend to interpret this as a crash. However, if external circumstances prevent your application from functioning as intended, you need to tell your users about the situation and explain what they can do about it. Depending on how severe the application malfunction is, you have two choices.
Display an attractive screen that describes the problem and suggests a correction. A screen provides feedback that reassures users that there’s nothing wrong with your application. It puts users in control, letting them decide whether they want to take corrective action and continue using your application or press the Home button and open a different application
If only some of your application's features are not working, display either a screen or an alert when people activate the feature. Display the alert only when people try to access the feature that isn’t functioning.

which says that any app termination is not agreed by apple, which means that no matter we will use exit(0) or something like UIApplication.shared.perform(#selector(NSXPCConnection.suspend)) appp should not pass apple review. On the other hand, there is this post saying exactly about exit function: https://developer.apple.com/library/archive/qa/qa1561/_index.html#//apple_ref/doc/uid/DTS40007952 but it's really old and not sure it's still applicable.

As far as I know, Apple does not check source code but decompiled binary bundle and is looking for certain symbols. This fact makes it riskier because previously there was library code in the bundle, now terminating code is part of the main workflow in native code, which in my opinion increase the risk of app being rejected.

However, I've searched through the newest Human Interface Guidelines as well as App Store Review Guidelines and I couldn't find anything about this, which means apple does not check this anymore or I didn't dive deep enough (it's a lot of information to search through).

@ashoat do you think it is reasonable to submit our app for mock apple review to validate this code?

I think like this is the best what we can do for now (if this is possible) because I am not sure we can rely on posts from stack overflow that are based on outdated apple documentation and looks like it always be risky because apple in the past was rejecting any way of termination.

kamil edited the summary of this revision. (Show Details)

update import

Let's not think too much harder about this, I think it's fine to land this now and revisit if review rejects us. No reason for mock review, we'll be submitting regularly for regular review anyways

native/ios/Comm/TerminateApp.mm
1 ↗(On Diff #18476)

This newline isn't necessary

Human Interface Guidelines are more about making app better but it shouldn't affect the review too much (if the app follows this guideline, it might be highlighted by Apple, which is nice).

In the future, we can consider avoiding killing the app at all, and instead e.g. display an alert with some steps a user might take. Usually the step might be to restart the app, though.

Haven't worked with jni before but looks reasonable. Let's make sure to remove the newline at the top of TerminateApp.mm before landing.

This revision is now accepted and ready to land.Nov 17 2022, 9:47 AM

rebase before landing, remove additional line

native/ios/Comm.xcodeproj/project.pbxproj
45 ↗(On Diff #18561)

After this diff, when I run cd native/ios && pod install (as part of yarn cleaninstall), I get one more occurence of TerminateApp.mm getting added to my project.pbxproj. Created ENG-2297 to track