@@ -35,6 +35,31 @@ struct AndroidDisplayMetrics {
3535 width : f64 ,
3636 height : f64 ,
3737 rotation_quarter_turns : u16 ,
38+ corner_radii : AndroidCornerRadii ,
39+ }
40+
41+ #[ derive( Clone , Copy , Debug , PartialEq ) ]
42+ struct AndroidCornerRadii {
43+ top_left : f64 ,
44+ top_right : f64 ,
45+ bottom_right : f64 ,
46+ bottom_left : f64 ,
47+ }
48+
49+ impl AndroidCornerRadii {
50+ const ZERO : Self = Self {
51+ top_left : 0.0 ,
52+ top_right : 0.0 ,
53+ bottom_right : 0.0 ,
54+ bottom_left : 0.0 ,
55+ } ;
56+
57+ fn max ( self ) -> f64 {
58+ self . top_left
59+ . max ( self . top_right )
60+ . max ( self . bottom_right )
61+ . max ( self . bottom_left )
62+ }
3863}
3964
4065#[ derive( Clone , Default ) ]
@@ -497,15 +522,24 @@ impl AndroidBridge {
497522
498523 pub fn chrome_profile ( & self , id : & str ) -> Result < Value , AppError > {
499524 let serial = self . serial_for_id ( id) ?;
500- let ( width, height) = self . screen_size_for_serial ( & serial) ?;
525+ let metrics = self . display_metrics_for_serial ( & serial) ?;
526+ let width = metrics. width ;
527+ let height = metrics. height ;
528+ let radii = metrics. corner_radii ;
501529 Ok ( json ! ( {
502530 "totalWidth" : width,
503531 "totalHeight" : height,
504532 "screenX" : 0 ,
505533 "screenY" : 0 ,
506534 "screenWidth" : width,
507535 "screenHeight" : height,
508- "cornerRadius" : 0 ,
536+ "cornerRadius" : radii. max( ) ,
537+ "cornerRadii" : {
538+ "topLeft" : radii. top_left,
539+ "topRight" : radii. top_right,
540+ "bottomRight" : radii. bottom_right,
541+ "bottomLeft" : radii. bottom_left,
542+ } ,
509543 "hasScreenMask" : false ,
510544 } ) )
511545 }
@@ -744,6 +778,7 @@ impl AndroidBridge {
744778 width : 0.0 ,
745779 height : 0.0 ,
746780 rotation_quarter_turns : 0 ,
781+ corner_radii : AndroidCornerRadii :: ZERO ,
747782 } ) ;
748783 json ! ( {
749784 "displayReady" : metrics. width > 0.0 && metrics. height > 0.0 ,
@@ -903,6 +938,7 @@ impl AndroidBridge {
903938 width,
904939 height,
905940 rotation_quarter_turns : 0 ,
941+ corner_radii : AndroidCornerRadii :: ZERO ,
906942 } )
907943 }
908944
@@ -1370,6 +1406,7 @@ fn android_display_metrics_cache() -> &'static Mutex<DisplayMetricsCache> {
13701406
13711407fn parse_android_display_metrics ( output : & str ) -> Option < AndroidDisplayMetrics > {
13721408 let rotation = parse_android_display_rotation ( output) . unwrap_or ( 0 ) ;
1409+ let corner_radii = parse_android_rounded_corners ( output) . unwrap_or ( AndroidCornerRadii :: ZERO ) ;
13731410 if let Some ( line) = output
13741411 . lines ( )
13751412 . find ( |line| line. contains ( "mOverrideDisplayInfo=DisplayInfo" ) )
@@ -1379,6 +1416,7 @@ fn parse_android_display_metrics(output: &str) -> Option<AndroidDisplayMetrics>
13791416 width,
13801417 height,
13811418 rotation_quarter_turns : rotation,
1419+ corner_radii,
13821420 } ) ;
13831421 }
13841422 }
@@ -1387,11 +1425,44 @@ fn parse_android_display_metrics(output: &str) -> Option<AndroidDisplayMetrics>
13871425 width,
13881426 height,
13891427 rotation_quarter_turns : rotation,
1428+ corner_radii,
13901429 } ) ;
13911430 }
13921431 None
13931432}
13941433
1434+ fn parse_android_rounded_corners ( output : & str ) -> Option < AndroidCornerRadii > {
1435+ let mut radii = AndroidCornerRadii :: ZERO ;
1436+ let mut found = false ;
1437+
1438+ for chunk in output. split ( "RoundedCorner{" ) . skip ( 1 ) {
1439+ let section = chunk. split ( '}' ) . next ( ) . unwrap_or ( chunk) ;
1440+ let Some ( position) = parse_named_value ( section, "position=" ) else {
1441+ continue ;
1442+ } ;
1443+ let Some ( radius) =
1444+ parse_named_value ( section, "radius=" ) . and_then ( |value| value. parse :: < f64 > ( ) . ok ( ) )
1445+ else {
1446+ continue ;
1447+ } ;
1448+ match position {
1449+ "TopLeft" => radii. top_left = radius,
1450+ "TopRight" => radii. top_right = radius,
1451+ "BottomRight" => radii. bottom_right = radius,
1452+ "BottomLeft" => radii. bottom_left = radius,
1453+ _ => continue ,
1454+ }
1455+ found = true ;
1456+ }
1457+
1458+ found. then_some ( radii)
1459+ }
1460+
1461+ fn parse_named_value < ' a > ( input : & ' a str , key : & str ) -> Option < & ' a str > {
1462+ let ( _, value) = input. split_once ( key) ?;
1463+ Some ( value. split ( [ ',' , '}' , ']' ] ) . next ( ) . unwrap_or ( value) . trim ( ) )
1464+ }
1465+
13951466fn parse_android_display_rotation ( output : & str ) -> Option < u16 > {
13961467 output
13971468 . lines ( )
@@ -1734,6 +1805,7 @@ mod tests {
17341805 width: 2400.0 ,
17351806 height: 1080.0 ,
17361807 rotation_quarter_turns: 3 ,
1808+ corner_radii: AndroidCornerRadii :: ZERO ,
17371809 } )
17381810 ) ;
17391811 }
@@ -1751,6 +1823,31 @@ mod tests {
17511823 width: 1080.0 ,
17521824 height: 2400.0 ,
17531825 rotation_quarter_turns: 0 ,
1826+ corner_radii: AndroidCornerRadii :: ZERO ,
1827+ } )
1828+ ) ;
1829+ }
1830+
1831+ #[ test]
1832+ fn parse_android_display_metrics_reads_rounded_corners ( ) {
1833+ let output = r#"
1834+ DisplayDeviceInfo{"Built-in Screen", 1080 x 2400, roundedCorners RoundedCorners{[RoundedCorner{position=TopLeft, radius=104, center=Point(104, 104)}, RoundedCorner{position=TopRight, radius=104, center=Point(976, 104)}, RoundedCorner{position=BottomRight, radius=102, center=Point(978, 2298)}, RoundedCorner{position=BottomLeft, radius=102, center=Point(102, 2298)}]}}
1835+ mViewports=[DisplayViewport{type=INTERNAL, logicalFrame=Rect(0, 0 - 1080, 2400), physicalFrame=Rect(0, 0 - 1080, 2400)}]
1836+ mCurrentOrientation=0
1837+ "# ;
1838+
1839+ assert_eq ! (
1840+ parse_android_display_metrics( output) ,
1841+ Some ( AndroidDisplayMetrics {
1842+ width: 1080.0 ,
1843+ height: 2400.0 ,
1844+ rotation_quarter_turns: 0 ,
1845+ corner_radii: AndroidCornerRadii {
1846+ top_left: 104.0 ,
1847+ top_right: 104.0 ,
1848+ bottom_right: 102.0 ,
1849+ bottom_left: 102.0 ,
1850+ } ,
17541851 } )
17551852 ) ;
17561853 }
0 commit comments