| 
				
			 | 
			
			
				@@ -0,0 +1,85 @@ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				1
			 | 
			
			
				+package com.th3rdwave.safeareacontext; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				3
			 | 
			
			
				+import android.graphics.Rect; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				4
			 | 
			
			
				+import android.os.Build; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				5
			 | 
			
			
				+import android.view.Surface; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				6
			 | 
			
			
				+import android.view.View; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				+import android.view.WindowInsets; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				8
			 | 
			
			
				+import android.view.WindowManager; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				9
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				10
			 | 
			
			
				+import com.facebook.react.bridge.Arguments; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				11
			 | 
			
			
				+import com.facebook.react.bridge.ReadableMap; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				+import com.facebook.react.bridge.WritableMap; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				13
			 | 
			
			
				+import com.facebook.react.common.MapBuilder; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				14
			 | 
			
			
				+import com.facebook.react.uimanager.PixelUtil; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				+import java.util.Map; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				+/* package */ class SafeAreaUtils { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				+  static ReadableMap edgeInsetsToJsMap(EdgeInsets insets) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				+    WritableMap insetsMap = Arguments.createMap(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				+    insetsMap.putDouble("top", PixelUtil.toDIPFromPixel(insets.top)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				+    insetsMap.putDouble("right", PixelUtil.toDIPFromPixel(insets.right)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				+    insetsMap.putDouble("bottom", PixelUtil.toDIPFromPixel(insets.bottom)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				+    insetsMap.putDouble("left", PixelUtil.toDIPFromPixel(insets.left)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				+    return insetsMap; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				+  } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				27
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				28
			 | 
			
			
				+  static Map<String, Float> edgeInsetsToJavaMap(EdgeInsets insets) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				29
			 | 
			
			
				+    return MapBuilder.of( 
			 | 
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				+        "top", 
			 | 
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				+        PixelUtil.toDIPFromPixel(insets.top), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				32
			 | 
			
			
				+        "right", 
			 | 
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				+        PixelUtil.toDIPFromPixel(insets.right), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				+        "bottom", 
			 | 
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				+        PixelUtil.toDIPFromPixel(insets.bottom), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				+        "left", 
			 | 
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				+        PixelUtil.toDIPFromPixel(insets.left)); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				+  } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				+  static EdgeInsets getSafeAreaInsets(WindowManager windowManager, View rootView) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				+    // Window insets are parts of the window that are covered by system views (status bar, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				+    // navigation bar, notches). There are no apis the get these values for android < M so we 
			 | 
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				+    // do a best effort polyfill. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				+    EdgeInsets windowInsets; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				+      WindowInsets insets = rootView.getRootWindowInsets(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				+      windowInsets = new EdgeInsets( 
			 | 
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				+          insets.getSystemWindowInsetTop(), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				+          insets.getSystemWindowInsetRight(), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				+          insets.getSystemWindowInsetBottom(), 
			 | 
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				+          insets.getSystemWindowInsetLeft()); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				+    } else { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				+      int rotation = windowManager.getDefaultDisplay().getRotation(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				+      int statusBarHeight = 0; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				+      int resourceId = rootView.getResources().getIdentifier("status_bar_height", "dimen", "android"); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				+      if (resourceId > 0) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				+        statusBarHeight = rootView.getResources().getDimensionPixelSize(resourceId); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				+      } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				+      int navbarHeight = 0; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				+      resourceId = rootView.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				+      if (resourceId > 0) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				+        navbarHeight = rootView.getResources().getDimensionPixelSize(resourceId); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				+      } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				+      windowInsets = new EdgeInsets( 
			 | 
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				+          statusBarHeight, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				+          rotation == Surface.ROTATION_90 ? navbarHeight : 0, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				+          rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? navbarHeight : 0, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				+          rotation == Surface.ROTATION_270 ? navbarHeight : 0); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				+    } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				+    // Calculate the part of the root view that overlaps with window insets. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				+    View contentView = rootView.findViewById(android.R.id.content); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				+    float windowWidth = rootView.getWidth(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				+    float windowHeight = rootView.getHeight(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				+    Rect visibleRect = new Rect(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				+    contentView.getGlobalVisibleRect(visibleRect); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				+    windowInsets.top = Math.max(windowInsets.top - visibleRect.top, 0); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				+    windowInsets.left = Math.max(windowInsets.left - visibleRect.left, 0); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				+    windowInsets.bottom = Math.max(visibleRect.top + contentView.getHeight() + windowInsets.bottom - windowHeight, 0); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				+    windowInsets.right = Math.max(visibleRect.left + contentView.getWidth() + windowInsets.right - windowWidth, 0); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				+    return windowInsets; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				+  } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				+} 
			 |