mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Modal: FLAG_SECURE not respected in modal dialog (#48317)
Summary: Fixes https://github.com/facebook/react-native/issues/38537 Setting `WindowManager.LayoutParams.FLAG_SECURE` in the window flags is not respected in the Android Modal component, causing security issues with screenshots or screen recordings as the content in the modal is visible. The flag works correctly in the rest of the components, see the videos in the linked issue. This PR addresses that by checking whether this flag is set in the current activity and then setting it in the dialog when creating a new one in the `ReactModalHostView`. ## Changelog: [ANDROID][FIXED] - `FLAG_SECURE` not respected in Modal dialog Pull Request resolved: https://github.com/facebook/react-native/pull/48317 Test Plan: To test this, you need a physical device as with the emulator the flags don't seem to be respected either. The easiest way to test this in code is by setting the flags in the main activity. You can do so by adding this code snippet: <details> <summary>onCreate in RNTesterApplication.kt</summary> ```kt override fun onCreate() { ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik) super.onCreate() ... registerActivityLifecycleCallbacks( object : ActivityLifecycleCallbacks { override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { activity.window.setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE ) } override fun onActivityStarted(activity: Activity) {} override fun onActivityResumed(activity: Activity) {} override fun onActivityPaused(activity: Activity) {} override fun onActivityStopped(activity: Activity) {} override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {} override fun onActivityDestroyed(activity: Activity) {} } ) } ``` </details> Then, you can render a simple modal component: <details> <summary>RNTesterPlayground.js</summary> ```tsx function Playground() { const [modalVisible, setModalVisible] = React.useState(false); return ( <> <Modal visible={modalVisible} testID="playground-modal"> <Text testID="inner-text-test-id">Hello World!</Text> <Button title="Close Modal" onPress={() => setModalVisible(false)} /> </Modal> <Button title="Open Modal" onPress={() => { setModalVisible(true); }} /> </> ); } ``` </details> You can then try to record the screen or take screenshots. You will notice that before opening the modal, you won't be able to see anything in the recording, but when opening the modal, the content is visible. I've tried my best to record the before and after the fix, but as the screen recordings will mostly show a black screen, you have to forward a bit in both videos to see the difference. <details> <summary>Before the fix (notice the blank screen and then content visible)</summary> https://github.com/user-attachments/assets/fc5bbe26-d238-425b-90d3-0e43c89ccaac </details> <details> <summary>After the fix (notice all the screen recording is a black screen)</summary> https://github.com/user-attachments/assets/0d6991a0-974b-45c5-8f4a-bf4718c284e6 </details> Reviewed By: cipolleschi Differential Revision: D67368741 Pulled By: alanleedev fbshipit-source-id: 9f31063a9208a6df257da424bf3096bf15a5ddcb
This commit is contained in:
committed by
React Native Bot
parent
bf17c3be3a
commit
0750c6a91b
+14
@@ -220,6 +220,15 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
||||
|
||||
private fun getCurrentActivity(): Activity? = (context as ThemedReactContext).currentActivity
|
||||
|
||||
private fun isFlagSecureSet(activity: Activity?): Boolean {
|
||||
if (activity == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
val flags = activity.window.attributes.flags
|
||||
return (flags and WindowManager.LayoutParams.FLAG_SECURE) != 0
|
||||
}
|
||||
|
||||
/**
|
||||
* showOrUpdate will display the Dialog. It is called by the manager once all properties are set
|
||||
* because we need to know all of them before creating the Dialog. It is also smart during updates
|
||||
@@ -293,6 +302,11 @@ public class ReactModalHostView(context: ThemedReactContext) :
|
||||
if (hardwareAccelerated) {
|
||||
newDialog.window?.addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
|
||||
}
|
||||
val flagSecureSet = isFlagSecureSet(currentActivity)
|
||||
if (flagSecureSet) {
|
||||
newDialog.window?.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
if (currentActivity?.isFinishing == false) {
|
||||
newDialog.show()
|
||||
updateSystemAppearance()
|
||||
|
||||
Reference in New Issue
Block a user