/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġandroidx . compose . foundation . text . selection Ċ Ċ import Ġandroid . view . View Ċ import Ġandroid . view . WindowManager Ċ import Ġandroidx . compose . foundation . layout . Box Ċ import Ġandroidx . compose . foundation . layout . Spacer Ċ import Ġandroidx . compose . foundation . layout . offset Ċ import Ġandroidx . compose . foundation . layout . size Ċ import Ġandroidx . compose . foundation . text . Handle Ċ import Ġandroidx . compose . runtime . Composition Local Provider Ċ import Ġandroidx . compose . ui . Modifier Ċ import Ġandroidx . compose . ui . geometry . Offset Ċ import Ġandroidx . compose . ui . layout . on Glob ally Position ed Ċ import Ġandroidx . compose . ui . platform . Local Layout Direction Ċ import Ġandroidx . compose . ui . platform . Local View Ċ import Ġandroidx . compose . ui . platform . View Root For Test Ċ import Ġandroidx . compose . ui . test . junit 4 . Compose Test Rule Ċ import Ġandroidx . compose . ui . test . junit 4 . create Compose Rule Ċ import Ġandroidx . compose . ui . text . style . Resolved Text Direction Ċ import Ġandroidx . compose . ui . unit . Dp Ċ import Ġandroidx . compose . ui . unit . Int Offset Ċ import Ġandroidx . compose . ui . unit . Layout Direction Ċ import Ġandroidx . compose . ui . unit . dp Ċ import Ġandroidx . compose . ui . window . is Popup Layout Ċ import Ġandroidx . test . espress o . Esp ress o Ċ import Ġandroidx . test . espress o . Root Ċ import Ġandroidx . test . espress o . assertion . View Assertions Ċ import Ġandroidx . test . espress o . matcher . Bounded Matcher Ċ import Ġandroidx . test . ext . junit . runners . Android JUnit 4 Ċ import Ġandroidx . test . filters . Medium Test Ċ import Ġorg . hamcrest . Core Matchers Ċ import Ġorg . hamcrest . Description Ċ import Ġorg . hamcrest . Matcher Ċ import Ġorg . hamcrest . Type Safe Matcher Ċ import Ġorg . junit . Rule Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . runner . RunWith Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ @ Medium Test Ċ @ RunWith ( Android JUnit 4 :: class ) Ċ class ĠSelection Handle Popup Position Test Ġ{ ĊĠĠĠ Ġ@ get : Rule ĊĠĠĠ Ġval Ġrule Ġ= Ġcreate Compose Rule () ĊĊĠĠĠ Ġprivate Ġval Ġoffset Ġ= ĠOffset ( 1 2 0 f , Ġ 1 2 0 f ) ĊĠĠĠ Ġprivate Ġval Ġparent Size Width Ġ= Ġ 1 0 0 . dp ĊĠĠĠ Ġprivate Ġval Ġparent Size Height Ġ= Ġ 1 0 0 . dp ĊĊĠĠĠ Ġprivate Ġvar Ġcompose View Absolute Pos Ġ= ĠInt Offset ( 0 , Ġ 0 ) ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġleft Handle _ L tr _ correct Position () Ġ{ ĊĠĠĠĠĠĠĠ Ġ/* ĠExpected ĠTop End ĠPosition ĊĠĠĠĠĠĠĠĠĠĠ Ġx Ġ= Ġoffset . x Ġ- ĠHANDLE _ WIDTH ĊĠĠĠĠĠĠĠĠĠĠ Ġy Ġ= Ġoffset . y ĊĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Anchor Position X Ġ= Ġoffset . x . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Popup Position X Ġ= Ġexpected Anchor Position X Ġ- ĠHandle Width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position Y Ġ= Ġoffset . y . to Dp () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Selection Handle ( is Start Handle Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . single Selection Handle Matches ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatches Position ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . x . to Dp () Ġ+ Ġexpected Popup Position X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . y . to Dp () Ġ+ Ġexpected Position Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . on Node ( is Selection Handle ( Handle . Selection Start )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. assert Handle Position Matches ( expected Anchor Position X , Ġexpected Position Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġleft Handle _ R tl _ correct Position () Ġ{ ĊĠĠĠĠĠĠĠ Ġ/* ĠExpected ĠTop End ĠPosition ĊĠĠĠĠĠĠĠĠĠĠ Ġx Ġ= Ġoffset . x Ġ- ĠHANDLE _ WIDTH ĊĠĠĠĠĠĠĠĠĠĠ Ġy Ġ= Ġoffset . y ĊĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Anchor Position X Ġ= Ġoffset . x . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Popup Position X Ġ= Ġexpected Anchor Position X Ġ- ĠHandle Width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position Y Ġ= Ġoffset . y . to Dp () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Selection Handle ( is Start Handle Ġ= Ġtrue , Ġis R tl Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . single Selection Handle Matches ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatches Position ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . x . to Dp () Ġ+ Ġexpected Popup Position X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . y . to Dp () Ġ+ Ġexpected Position Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . on Node ( is Selection Handle ( Handle . Selection Start )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. assert Handle Position Matches ( expected Anchor Position X , Ġexpected Position Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġright Handle _ L tr _ correct Position () Ġ{ ĊĠĠĠĠĠĠĠ Ġ/* ĠExpected ĠTop Start ĠPosition ĊĠĠĠĠĠĠĠĠĠĠ Ġx Ġ= Ġoffset . x ĊĠĠĠĠĠĠĠĠĠĠ Ġy Ġ= Ġoffset . y ĊĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position X Ġ= Ġoffset . x . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position Y Ġ= Ġoffset . y . to Dp () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Selection Handle ( is Start Handle Ġ= Ġfalse ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . single Selection Handle Matches ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatches Position ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . x . to Dp () Ġ+ Ġexpected Position X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . y . to Dp () Ġ+ Ġexpected Position Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . on Node ( is Selection Handle ( Handle . Selection End )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. assert Handle Position Matches ( expected Position X , Ġexpected Position Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġright Handle _ R tl _ correct Position () Ġ{ ĊĠĠĠĠĠĠĠ Ġ/* ĠExpected ĠTop Start ĠPosition ĊĠĠĠĠĠĠĠĠĠĠ Ġx Ġ= Ġoffset . x ĊĠĠĠĠĠĠĠĠĠĠ Ġy Ġ= Ġoffset . y ĊĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position X Ġ= Ġoffset . x . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position Y Ġ= Ġoffset . y . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Selection Handle ( is Start Handle Ġ= Ġfalse , Ġis R tl Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . single Selection Handle Matches ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatches Position ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . x . to Dp () Ġ+ Ġexpected Position X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . y . to Dp () Ġ+ Ġexpected Position Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . on Node ( is Selection Handle ( Handle . Selection End )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. assert Handle Position Matches ( expected Position X , Ġexpected Position Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġleft Handle _ semantics Position _ is Relative To Container () Ġ{ ĊĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontainer Offset X Ġ= Ġ 2 0 . dp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontainer Offset Y Ġ= Ġ 3 0 . dp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSince Ġthe Ġsemantics Ġposition Ġis Ġrelative Ġto Ġthe Ġcontainer , Ġit Ġshouldn 't Ġinclude Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcontainer Ġoffset . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Semantics Position X Ġ= Ġoffset . x . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Semantics Position Y Ġ= Ġoffset . y . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHowever , Ġthe Ġpopup Ġposition , Ġwhich Ġis Ġin Ġabsolute Ġscreen Ġcoordinates , Ġshould Ġinclude ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġcontainer Ġoffset . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Popup Position X Ġ= Ġcontainer Offset X Ġ+ Ġexpected Semantics Position X Ġ- ĠHandle Width ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Popup Position Y Ġ= Ġcontainer Offset Y Ġ+ Ġexpected Semantics Position Y ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Selection Handle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Start Handle Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Modifier Ġ= ĠModifier . offset ( container Offset X , Ġcontainer Offset Y ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . single Selection Handle Matches ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatches Position ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . x . to Dp () Ġ+ Ġexpected Popup Position X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . y . to Dp () Ġ+ Ġexpected Popup Position Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . on Node ( is Selection Handle ( Handle . Selection Start )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. assert Handle Position Matches ( expected Semantics Position X , Ġexpected Semantics Position Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġright Handle _ semantics Position _ is Relative To Container () Ġ{ ĊĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontainer Offset X Ġ= Ġ 2 0 . dp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontainer Offset Y Ġ= Ġ 3 0 . dp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSince Ġthe Ġsemantics Ġposition Ġis Ġrelative Ġto Ġthe Ġcontainer , Ġit Ġshouldn 't Ġinclude Ġthe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcontainer Ġoffset . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Semantics Position X Ġ= Ġoffset . x . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Semantics Position Y Ġ= Ġoffset . y . to Dp () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHowever , Ġthe Ġpopup Ġposition , Ġwhich Ġis Ġin Ġabsolute Ġscreen Ġcoordinates , Ġshould Ġinclude ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġcontainer Ġoffset . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Popup Position X Ġ= Ġcontainer Offset X Ġ+ Ġexpected Semantics Position X ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Popup Position Y Ġ= Ġcontainer Offset Y Ġ+ Ġexpected Semantics Position Y ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Selection Handle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Start Handle Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Modifier Ġ= ĠModifier . offset ( container Offset X , Ġcontainer Offset Y ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . single Selection Handle Matches ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmatches Position ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . x . to Dp () Ġ+ Ġexpected Popup Position X , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos . y . to Dp () Ġ+ Ġexpected Popup Position Y ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrule . on Node ( is Selection Handle ( Handle . Selection End )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. assert Handle Position Matches ( expected Semantics Position X , Ġexpected Semantics Position Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Selection Handle ( ĊĠĠĠĠĠĠĠ Ġis Start Handle : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġcontainer Modifier : ĠModifier Ġ= ĠModifier , ĊĠĠĠĠĠĠĠ Ġis R tl : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmeasure Latch Ġ= ĠCount DownLatch ( 1 ) ĊĊĠĠĠĠĠĠĠ Ġrule . setContent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBox ( container Modifier ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġcompose Ġview Ġposition Ġon Ġscreen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompose View Ġ= ĠLocal View . current ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Array Ġ= ĠInt Array ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View . getLocation On Screen ( position Array ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompose View Absolute Pos Ġ= ĠInt Offset ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition Array [ 0 ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition Array [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAlign Ġthe Ġparent Ġof Ġthe Ġpopup Ġon Ġthe Ġtop Ġleft Ġcorner , Ġthis Ġresults Ġin Ġthe Ġglobal ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġposition Ġof Ġthe Ġparent Ġto Ġbe Ġ( 0 , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlayout Direction Ġ= Ġif Ġ( is R tl ) ĠLayout Direction . R tl Ġelse ĠLayout Direction . L tr ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠComp osition Local Provider ( Local Layout Direction Ġprovides Ġlayout Direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSimple Layout Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSp acer ( Modifier . size ( parent Size Width , Ġparent Size Height )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSelection Handle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition Ġ= Ġoffset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Start Handle Ġ= Ġis Start Handle , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection Ġ= ĠResolved Text Direction . L tr , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandles C ros sed Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . on Glob ally Position ed Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeasure Latch . count Down () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġmeasure Latch . await ( 1 , ĠTimeUnit . SECONDS ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmatches Position ( expected Position X : ĠD p , Ġexpected Position Y : ĠD p ): ĊĠĠĠĠĠĠĠ ĠBo unded Matcher < View , ĠView > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġobject Ġ: ĠBo unded Matcher < View , ĠView >( View :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ(- 1 , Ġ- 1 ) Ġno Ġposition Ġfound ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġposition Found Ġ= ĠInt Offset (- 1 , Ġ- 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġmatches S af ely ( item : ĠView ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Ġ= ĠInt Array ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem ?. getLocation On Screen ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition Found Ġ= ĠInt Offset ( position [ 0 ], Ġposition [ 1 ]) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position X Int Ġ= Ġexpected Position X . value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected Position Y Int Ġ= Ġexpected Position Y . value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Found X Int Ġ= Ġposition Found . x . to Dp (). value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Found Y Int Ġ= Ġposition Found . y . to Dp (). value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġexpected Position X Int Ġ== Ġposition Found X Int Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpected Position Y Int Ġ== Ġposition Found Y Int ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdescribe To ( description : ĠDescription ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith ( rule . density ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription ?. append Text ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" with Ġexpected Ġposition : Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ expected Position X . value }, Ġ${ expected Position Y . value } Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" but Ġposition Ġfound :" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ position Found . x . to Dp (). value }, Ġ${ position Found . y . to Dp (). value }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠCompose Test Rule . single Selection Handle Matches ( view Matcher : ĠMatcher < in ĠView >) Ġ{ ĊĠĠĠ Ġ// ĠMake Ġsure Ġthat Ġcurrent Ġmeasurement / drawing Ġis Ġfinished ĊĠĠĠ ĠwaitFor Idle () ĊĠĠĠ ĠE sp ress o . on View ( Core Matchers . instance Of ( View Root For Test :: class . java )) ĊĠĠĠĠĠĠĠ Ġ. in Root ( Single Selection Handle Matcher ()) ĊĠĠĠĠĠĠĠ Ġ. check ( View Assertions . matches ( view Matcher )) Ċ } Ċ Ċ private Ġclass ĠSingle Selection Handle Matcher Ġ: ĠType Safe Matcher < Root >() Ġ{ ĊĊĠĠĠ Ġvar Ġlast Seen Window Params : ĠWindow Manager . LayoutParams ? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġfun Ġdescribe To ( description : ĠDescription ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġdescription ?. append Text (" Popup Layout Matcher ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmatches S af ely ( item : ĠRoot ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmatches Ġ= Ġitem Ġ!= Ġnull Ġ&& Ġis Popup Layout ( item . decor View ) ĊĠĠĠĠĠĠĠ Ġif Ġ( matches ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Seen Window Params Ġ= Ġitem !!. window LayoutParams . get () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmatches ĊĠĠĠ Ġ} Ċ }