capture_mode_camera_unittests.cc 193 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/accessibility/accessibility_controller_impl.h"
  5. #include "ash/accessibility/autoclick/autoclick_controller.h"
  6. #include "ash/capture_mode/capture_mode_bar_view.h"
  7. #include "ash/capture_mode/capture_mode_button.h"
  8. #include "ash/capture_mode/capture_mode_camera_controller.h"
  9. #include "ash/capture_mode/capture_mode_camera_preview_view.h"
  10. #include "ash/capture_mode/capture_mode_constants.h"
  11. #include "ash/capture_mode/capture_mode_controller.h"
  12. #include "ash/capture_mode/capture_mode_menu_group.h"
  13. #include "ash/capture_mode/capture_mode_metrics.h"
  14. #include "ash/capture_mode/capture_mode_session.h"
  15. #include "ash/capture_mode/capture_mode_session_test_api.h"
  16. #include "ash/capture_mode/capture_mode_settings_test_api.h"
  17. #include "ash/capture_mode/capture_mode_settings_view.h"
  18. #include "ash/capture_mode/capture_mode_test_util.h"
  19. #include "ash/capture_mode/capture_mode_toast_controller.h"
  20. #include "ash/capture_mode/capture_mode_toggle_button.h"
  21. #include "ash/capture_mode/capture_mode_types.h"
  22. #include "ash/capture_mode/capture_mode_util.h"
  23. #include "ash/capture_mode/fake_camera_device.h"
  24. #include "ash/capture_mode/fake_folder_selection_dialog_factory.h"
  25. #include "ash/capture_mode/fake_video_source_provider.h"
  26. #include "ash/capture_mode/test_capture_mode_delegate.h"
  27. #include "ash/display/window_tree_host_manager.h"
  28. #include "ash/public/cpp/capture_mode/capture_mode_test_api.h"
  29. #include "ash/public/cpp/window_properties.h"
  30. #include "ash/resources/vector_icons/vector_icons.h"
  31. #include "ash/shell.h"
  32. #include "ash/strings/grit/ash_strings.h"
  33. #include "ash/style/ash_color_provider.h"
  34. #include "ash/system/accessibility/autoclick_menu_bubble_controller.h"
  35. #include "ash/system/unified/unified_system_tray.h"
  36. #include "ash/test/ash_test_base.h"
  37. #include "ash/wm/window_state.h"
  38. #include "base/strings/stringprintf.h"
  39. #include "base/strings/utf_string_conversions.h"
  40. #include "base/system/system_monitor.h"
  41. #include "base/test/bind.h"
  42. #include "base/test/metrics/histogram_tester.h"
  43. #include "base/timer/timer.h"
  44. #include "cc/paint/skia_paint_canvas.h"
  45. #include "media/base/video_facing.h"
  46. #include "media/base/video_frame.h"
  47. #include "media/renderers/paint_canvas_video_renderer.h"
  48. #include "third_party/skia/include/core/SkBitmap.h"
  49. #include "ui/base/l10n/l10n_util.h"
  50. #include "ui/base/ui_base_types.h"
  51. #include "ui/compositor/compositor_switches.h"
  52. #include "ui/compositor/layer.h"
  53. #include "ui/gfx/geometry/point.h"
  54. #include "ui/gfx/geometry/rect.h"
  55. #include "ui/gfx/geometry/size.h"
  56. #include "ui/gfx/geometry/vector2d.h"
  57. #include "ui/gfx/image/image_unittest_util.h"
  58. #include "ui/gfx/paint_vector_icon.h"
  59. #include "ui/views/view.h"
  60. #include "ui/views/view_observer.h"
  61. #include "ui/views/widget/widget.h"
  62. #include "ui/wm/core/coordinate_conversion.h"
  63. #include "ui/wm/core/window_util.h"
  64. namespace ash {
  65. namespace {
  66. constexpr char kDefaultCameraDeviceId[] = "/dev/videoX";
  67. constexpr char kDefaultCameraDisplayName[] = "Default Cam";
  68. constexpr char kDefaultCameraModelId[] = "0def:c000";
  69. TestCaptureModeDelegate* GetTestDelegate() {
  70. return static_cast<TestCaptureModeDelegate*>(
  71. CaptureModeController::Get()->delegate_for_testing());
  72. }
  73. CaptureModeCameraController* GetCameraController() {
  74. return CaptureModeController::Get()->camera_controller();
  75. }
  76. // Returns the current root window where the current capture activities are
  77. // hosted in.
  78. aura::Window* GetCurrentRoot() {
  79. auto* controller = CaptureModeController::Get();
  80. if (controller->IsActive())
  81. return controller->capture_mode_session()->current_root();
  82. if (controller->is_recording_in_progress()) {
  83. return controller->video_recording_watcher_for_testing()
  84. ->window_being_recorded()
  85. ->GetRootWindow();
  86. }
  87. return Shell::GetPrimaryRootWindow();
  88. }
  89. bool IsWindowStackedRightBelow(aura::Window* window, aura::Window* sibling) {
  90. DCHECK_EQ(window->parent(), sibling->parent());
  91. const auto& children = window->parent()->children();
  92. const int sibling_index =
  93. std::find(children.begin(), children.end(), sibling) - children.begin();
  94. return sibling_index > 0 && children[sibling_index - 1] == window;
  95. }
  96. // Defines a waiter for the camera devices change notifications.
  97. class CameraDevicesChangeWaiter : public CaptureModeCameraController::Observer {
  98. public:
  99. CameraDevicesChangeWaiter() { GetCameraController()->AddObserver(this); }
  100. CameraDevicesChangeWaiter(const CameraDevicesChangeWaiter&) = delete;
  101. CameraDevicesChangeWaiter& operator=(const CameraDevicesChangeWaiter&) =
  102. delete;
  103. ~CameraDevicesChangeWaiter() override {
  104. GetCameraController()->RemoveObserver(this);
  105. }
  106. int camera_change_event_count() const { return camera_change_event_count_; }
  107. int selected_camera_change_event_count() const {
  108. return selected_camera_change_event_count_;
  109. }
  110. void Wait() { loop_.Run(); }
  111. // CaptureModeCameraController::Observer:
  112. void OnAvailableCamerasChanged(const CameraInfoList& cameras) override {
  113. ++camera_change_event_count_;
  114. loop_.Quit();
  115. }
  116. void OnSelectedCameraChanged(const CameraId& camera_id) override {
  117. ++selected_camera_change_event_count_;
  118. }
  119. private:
  120. base::RunLoop loop_;
  121. // Tracks the number of times the observer call `OnAvailableCamerasChanged()`
  122. // was triggered.
  123. int camera_change_event_count_ = 0;
  124. // Tracks the number of times `OnSelectedCameraChanged()` was triggered.
  125. int selected_camera_change_event_count_ = 0;
  126. };
  127. // Defines a waiter to observe the visibility change of the view.
  128. class ViewVisibilityChangeWaiter : public views::ViewObserver {
  129. public:
  130. explicit ViewVisibilityChangeWaiter(views::View* view) : view_(view) {
  131. view_->AddObserver(this);
  132. }
  133. ~ViewVisibilityChangeWaiter() override { view_->RemoveObserver(this); }
  134. void Wait() { wait_loop_.Run(); }
  135. // views::ViewObserver:
  136. void OnViewVisibilityChanged(views::View* observed_view,
  137. views::View* starting_view) override {
  138. wait_loop_.Quit();
  139. }
  140. private:
  141. views::View* const view_;
  142. base::RunLoop wait_loop_;
  143. };
  144. gfx::Rect GetTooSmallToFitCameraRegion() {
  145. return {100, 100,
  146. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera - 1,
  147. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera - 1};
  148. }
  149. } // namespace
  150. class CaptureModeCameraTest : public AshTestBase {
  151. public:
  152. CaptureModeCameraTest() = default;
  153. CaptureModeCameraTest(const CaptureModeCameraTest&) = delete;
  154. CaptureModeCameraTest& operator=(const CaptureModeCameraTest&) = delete;
  155. ~CaptureModeCameraTest() override = default;
  156. // AshTestBase:
  157. void SetUp() override {
  158. AshTestBase::SetUp();
  159. FakeFolderSelectionDialogFactory::Start();
  160. window_ = CreateTestWindow(gfx::Rect(30, 40, 600, 500));
  161. }
  162. void TearDown() override {
  163. window_.reset();
  164. FakeFolderSelectionDialogFactory::Stop();
  165. AshTestBase::TearDown();
  166. }
  167. aura::Window* window() const { return window_.get(); }
  168. void StartRecordingFromSource(CaptureModeSource source) {
  169. auto* controller = CaptureModeController::Get();
  170. controller->SetSource(source);
  171. switch (source) {
  172. case CaptureModeSource::kFullscreen:
  173. case CaptureModeSource::kRegion:
  174. break;
  175. case CaptureModeSource::kWindow:
  176. GetEventGenerator()->MoveMouseTo(
  177. window_->GetBoundsInScreen().CenterPoint());
  178. break;
  179. }
  180. CaptureModeTestApi().PerformCapture();
  181. WaitForRecordingToStart();
  182. EXPECT_TRUE(controller->is_recording_in_progress());
  183. }
  184. void AddFakeCamera(const std::string& device_id,
  185. const std::string& display_name,
  186. const std::string& model_id,
  187. media::VideoFacingMode camera_facing_mode =
  188. media::MEDIA_VIDEO_FACING_NONE) {
  189. CameraDevicesChangeWaiter waiter;
  190. GetTestDelegate()->video_source_provider()->AddFakeCamera(
  191. device_id, display_name, model_id, camera_facing_mode);
  192. waiter.Wait();
  193. }
  194. void RemoveFakeCamera(const std::string& device_id) {
  195. CameraDevicesChangeWaiter waiter;
  196. GetTestDelegate()->video_source_provider()->RemoveFakeCamera(device_id);
  197. waiter.Wait();
  198. }
  199. void AddDefaultCamera() {
  200. AddFakeCamera(kDefaultCameraDeviceId, kDefaultCameraDisplayName,
  201. kDefaultCameraModelId);
  202. }
  203. void RemoveDefaultCamera() { RemoveFakeCamera(kDefaultCameraDeviceId); }
  204. // Adds the default camera, sets it as the selected camera, then removes it,
  205. // which triggers the camera disconnection grace period. Returns a pointer to
  206. // the `CaptureModeCameraController`.
  207. CaptureModeCameraController* AddAndRemoveCameraAndTriggerGracePeriod() {
  208. AddDefaultCamera();
  209. auto* camera_controller = GetCameraController();
  210. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  211. RemoveDefaultCamera();
  212. return camera_controller;
  213. }
  214. void OpenSettingsView() {
  215. CaptureModeSession* session =
  216. CaptureModeController::Get()->capture_mode_session();
  217. DCHECK(session);
  218. ClickOnView(CaptureModeSessionTestApi(session)
  219. .GetCaptureModeBarView()
  220. ->settings_button(),
  221. GetEventGenerator());
  222. }
  223. void DragPreviewToPoint(views::Widget* preview_widget,
  224. const gfx::Point& screen_location,
  225. bool by_touch_gestures = false,
  226. bool drop = true) {
  227. DCHECK(preview_widget);
  228. auto* event_generator = GetEventGenerator();
  229. event_generator->set_current_screen_location(
  230. preview_widget->GetWindowBoundsInScreen().CenterPoint());
  231. if (by_touch_gestures) {
  232. event_generator->PressTouch();
  233. // Move the touch by an enough amount in X to make sure it generates a
  234. // serial of gesture scroll events instead of a fling event.
  235. event_generator->MoveTouchBy(50, 0);
  236. event_generator->MoveTouch(screen_location);
  237. if (drop)
  238. event_generator->ReleaseTouch();
  239. } else {
  240. event_generator->PressLeftButton();
  241. event_generator->MoveMouseTo(screen_location);
  242. if (drop)
  243. event_generator->ReleaseLeftButton();
  244. }
  245. }
  246. CaptureModeButton* GetPreviewResizeButton() const {
  247. return GetCameraController()->camera_preview_view()->resize_button();
  248. }
  249. // Verifies that the camera preview is placed on the correct position based on
  250. // current preview snap position and the given `confine_bounds_in_screen`.
  251. void VerifyPreviewAlignment(const gfx::Rect& confine_bounds_in_screen) {
  252. auto* camera_controller = GetCameraController();
  253. const auto* preview_widget = camera_controller->camera_preview_widget();
  254. DCHECK(preview_widget);
  255. const gfx::Rect camera_preview_bounds =
  256. preview_widget->GetWindowBoundsInScreen();
  257. switch (camera_controller->camera_preview_snap_position()) {
  258. case CameraPreviewSnapPosition::kTopLeft: {
  259. gfx::Point expect_origin = confine_bounds_in_screen.origin();
  260. expect_origin.Offset(capture_mode::kSpaceBetweenCameraPreviewAndEdges,
  261. capture_mode::kSpaceBetweenCameraPreviewAndEdges);
  262. EXPECT_EQ(expect_origin, camera_preview_bounds.origin());
  263. break;
  264. }
  265. case CameraPreviewSnapPosition::kBottomLeft: {
  266. const gfx::Point expect_bottom_left =
  267. gfx::Point(confine_bounds_in_screen.x() +
  268. capture_mode::kSpaceBetweenCameraPreviewAndEdges,
  269. confine_bounds_in_screen.bottom() -
  270. capture_mode::kSpaceBetweenCameraPreviewAndEdges);
  271. EXPECT_EQ(expect_bottom_left, camera_preview_bounds.bottom_left());
  272. break;
  273. }
  274. case CameraPreviewSnapPosition::kBottomRight: {
  275. const gfx::Point expect_bottom_right =
  276. gfx::Point(confine_bounds_in_screen.right() -
  277. capture_mode::kSpaceBetweenCameraPreviewAndEdges,
  278. confine_bounds_in_screen.bottom() -
  279. capture_mode::kSpaceBetweenCameraPreviewAndEdges);
  280. EXPECT_EQ(expect_bottom_right, camera_preview_bounds.bottom_right());
  281. break;
  282. }
  283. case CameraPreviewSnapPosition::kTopRight: {
  284. const gfx::Point expect_top_right =
  285. gfx::Point(confine_bounds_in_screen.right() -
  286. capture_mode::kSpaceBetweenCameraPreviewAndEdges,
  287. confine_bounds_in_screen.y() +
  288. capture_mode::kSpaceBetweenCameraPreviewAndEdges);
  289. EXPECT_EQ(expect_top_right, camera_preview_bounds.top_right());
  290. break;
  291. }
  292. }
  293. }
  294. // Verifies that the icon image and the tooltip of the resize button gets
  295. // updated correctly when pressed.
  296. void VerifyResizeButton(bool is_collapsed, CaptureModeButton* resize_button) {
  297. SkColor color = AshColorProvider::Get()->GetContentLayerColor(
  298. AshColorProvider::ContentLayerType::kIconColorPrimary);
  299. const gfx::ImageSkia collapse_icon_image =
  300. gfx::CreateVectorIcon(kCaptureModeCameraPreviewCollapseIcon, color);
  301. const gfx::ImageSkia expand_icon_image =
  302. gfx::CreateVectorIcon(kCaptureModeCameraPreviewExpandIcon, color);
  303. const SkBitmap* expected_icon = is_collapsed ? expand_icon_image.bitmap()
  304. : collapse_icon_image.bitmap();
  305. const SkBitmap* actual_icon =
  306. resize_button->GetImage(views::ImageButton::ButtonState::STATE_NORMAL)
  307. .bitmap();
  308. EXPECT_TRUE(gfx::test::AreBitmapsEqual(*actual_icon, *expected_icon));
  309. const auto expected_tooltip_text = l10n_util::GetStringUTF16(
  310. is_collapsed ? IDS_ASH_SCREEN_CAPTURE_TOOLTIP_EXPAND_SELFIE_CAMERA
  311. : IDS_ASH_SCREEN_CAPTURE_TOOLTIP_COLLAPSE_SELFIE_CAMERA);
  312. EXPECT_EQ(resize_button->GetTooltipText(), expected_tooltip_text);
  313. }
  314. // Select capture region by pressing and dragging the mouse.
  315. void SelectCaptureRegion(const gfx::Rect& region, bool release_mouse = true) {
  316. auto* controller = CaptureModeController::Get();
  317. ASSERT_TRUE(controller->IsActive());
  318. ASSERT_EQ(CaptureModeSource::kRegion, controller->source());
  319. auto* event_generator = GetEventGenerator();
  320. event_generator->set_current_screen_location(region.origin());
  321. event_generator->PressLeftButton();
  322. event_generator->MoveMouseTo(region.bottom_right());
  323. if (release_mouse)
  324. event_generator->ReleaseLeftButton();
  325. EXPECT_EQ(region, controller->user_capture_region());
  326. }
  327. void ConvertToPipWindow(aura::Window* pip_window) {
  328. WindowState* window_state = WindowState::Get(pip_window);
  329. DCHECK(!window_state->IsPip());
  330. views::Widget::GetWidgetForNativeWindow(pip_window)
  331. ->SetZOrderLevel(ui::ZOrderLevel::kFloatingWindow);
  332. pip_window->SetProperty(kWindowPipTypeKey, true);
  333. DCHECK(window_state->IsPip());
  334. }
  335. private:
  336. std::unique_ptr<aura::Window> window_;
  337. };
  338. TEST_F(CaptureModeCameraTest, SizeSpecsBigEnoughRegion) {
  339. gfx::Size confine_bounds_size(800, 700);
  340. {
  341. auto specs = capture_mode_util::CalculateCameraPreviewSizeSpecs(
  342. confine_bounds_size,
  343. /*is_collapsed=*/false);
  344. EXPECT_TRUE(specs.is_collapsible);
  345. EXPECT_TRUE(specs.should_be_visible);
  346. EXPECT_EQ(specs.size.width(), specs.size.height());
  347. EXPECT_EQ(specs.size.width(),
  348. 700 / capture_mode::kCaptureSurfaceShortSideDivider);
  349. }
  350. // Transposing the confine bounds (e.g. due to rotation) should have no effect
  351. // since we always consider the shorter side.
  352. confine_bounds_size.Transpose();
  353. {
  354. auto specs = capture_mode_util::CalculateCameraPreviewSizeSpecs(
  355. confine_bounds_size,
  356. /*is_collapsed=*/false);
  357. EXPECT_TRUE(specs.is_collapsible);
  358. EXPECT_TRUE(specs.should_be_visible);
  359. EXPECT_EQ(specs.size.width(),
  360. 700 / capture_mode::kCaptureSurfaceShortSideDivider);
  361. }
  362. {
  363. auto specs = capture_mode_util::CalculateCameraPreviewSizeSpecs(
  364. confine_bounds_size,
  365. /*is_collapsed=*/true);
  366. EXPECT_TRUE(specs.is_collapsible);
  367. EXPECT_TRUE(specs.should_be_visible);
  368. EXPECT_EQ(specs.size.width(), capture_mode::kMinCameraPreviewDiameter);
  369. }
  370. }
  371. TEST_F(CaptureModeCameraTest, SizeSpecsNotCollapsible) {
  372. gfx::Size confine_bounds_size(800, 500);
  373. auto specs = capture_mode_util::CalculateCameraPreviewSizeSpecs(
  374. confine_bounds_size,
  375. /*is_collapsed=*/false);
  376. EXPECT_FALSE(specs.is_collapsible);
  377. EXPECT_TRUE(specs.should_be_visible);
  378. EXPECT_EQ(specs.size.width(), specs.size.height());
  379. EXPECT_EQ(specs.size.width(),
  380. 500 / capture_mode::kCaptureSurfaceShortSideDivider);
  381. EXPECT_FALSE(specs.is_surface_too_small);
  382. }
  383. TEST_F(CaptureModeCameraTest, SizeSpecsHiddenPreview) {
  384. gfx::Size confine_bounds_size(800, 170);
  385. auto specs = capture_mode_util::CalculateCameraPreviewSizeSpecs(
  386. confine_bounds_size,
  387. /*is_collapsed=*/false);
  388. EXPECT_FALSE(specs.is_collapsible);
  389. EXPECT_FALSE(specs.should_be_visible);
  390. EXPECT_EQ(specs.size.width(), specs.size.height());
  391. EXPECT_EQ(specs.size.width(), capture_mode::kMinCameraPreviewDiameter);
  392. EXPECT_TRUE(specs.is_surface_too_small);
  393. }
  394. TEST_F(CaptureModeCameraTest, CameraDevicesChanges) {
  395. auto* camera_controller = GetCameraController();
  396. ASSERT_TRUE(camera_controller);
  397. EXPECT_TRUE(camera_controller->available_cameras().empty());
  398. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  399. EXPECT_FALSE(camera_controller->should_show_preview());
  400. EXPECT_FALSE(camera_controller->camera_preview_widget());
  401. const std::string device_id = "/dev/video0";
  402. const std::string display_name = "Integrated Webcam";
  403. const std::string model_id = "0123:4567";
  404. AddFakeCamera(device_id, display_name, model_id);
  405. EXPECT_EQ(1u, camera_controller->available_cameras().size());
  406. EXPECT_TRUE(camera_controller->available_cameras()[0].camera_id.is_valid());
  407. EXPECT_EQ(model_id, camera_controller->available_cameras()[0]
  408. .camera_id.model_id_or_display_name());
  409. EXPECT_EQ(1, camera_controller->available_cameras()[0].camera_id.number());
  410. EXPECT_EQ(device_id, camera_controller->available_cameras()[0].device_id);
  411. EXPECT_EQ(display_name,
  412. camera_controller->available_cameras()[0].display_name);
  413. EXPECT_FALSE(camera_controller->should_show_preview());
  414. EXPECT_FALSE(camera_controller->camera_preview_widget());
  415. RemoveFakeCamera(device_id);
  416. EXPECT_TRUE(camera_controller->available_cameras().empty());
  417. EXPECT_FALSE(camera_controller->should_show_preview());
  418. EXPECT_FALSE(camera_controller->camera_preview_widget());
  419. }
  420. TEST_F(CaptureModeCameraTest, CameraRemovedWhileWaitingForCameraDevices) {
  421. auto* camera_controller = GetCameraController();
  422. AddDefaultCamera();
  423. EXPECT_EQ(1u, camera_controller->available_cameras().size());
  424. // The system monitor can trigger several notifications about devices changes
  425. // for the same camera addition event. We will simulate a camera getting
  426. // removed right while we're still waiting for the video source provider to
  427. // send us the list. https://crbug.com/1295377.
  428. auto* video_source_provider = GetTestDelegate()->video_source_provider();
  429. {
  430. base::RunLoop loop;
  431. video_source_provider->set_on_replied_with_source_infos(
  432. base::BindLambdaForTesting([&]() { loop.Quit(); }));
  433. base::SystemMonitor::Get()->ProcessDevicesChanged(
  434. base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
  435. loop.Run();
  436. }
  437. RemoveDefaultCamera();
  438. EXPECT_TRUE(camera_controller->available_cameras().empty());
  439. }
  440. TEST_F(CaptureModeCameraTest, SelectingUnavailableCamera) {
  441. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  442. auto* camera_controller = GetCameraController();
  443. EXPECT_FALSE(camera_controller->camera_preview_widget());
  444. // Selecting a camera that doesn't exist in the list shouldn't show its
  445. // preview.
  446. camera_controller->SetSelectedCamera(CameraId("model", 1));
  447. EXPECT_FALSE(camera_controller->camera_preview_widget());
  448. }
  449. TEST_F(CaptureModeCameraTest, SelectingAvailableCamera) {
  450. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  451. auto* camera_controller = GetCameraController();
  452. EXPECT_FALSE(camera_controller->camera_preview_widget());
  453. AddDefaultCamera();
  454. EXPECT_EQ(1u, camera_controller->available_cameras().size());
  455. EXPECT_FALSE(camera_controller->camera_preview_widget());
  456. // Selecting an available camera while showing the preview is allowed should
  457. // result in creating the preview widget.
  458. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  459. EXPECT_TRUE(camera_controller->camera_preview_widget());
  460. }
  461. TEST_F(CaptureModeCameraTest, SelectedCameraBecomesAvailable) {
  462. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  463. auto* camera_controller = GetCameraController();
  464. EXPECT_FALSE(camera_controller->camera_preview_widget());
  465. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  466. EXPECT_FALSE(camera_controller->camera_preview_widget());
  467. // The selected camera becomes available while `should_show_preview_` is still
  468. // true. The preview should show in this case.
  469. AddDefaultCamera();
  470. EXPECT_TRUE(camera_controller->camera_preview_widget());
  471. // Clearing the selected camera should hide the preview.
  472. camera_controller->SetSelectedCamera(CameraId());
  473. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  474. EXPECT_FALSE(camera_controller->camera_preview_widget());
  475. }
  476. TEST_F(CaptureModeCameraTest, SelectingDifferentCameraCreatesNewPreviewWidget) {
  477. AddDefaultCamera();
  478. const std::string device_id = "/dev/video0";
  479. const std::string display_name = "Integrated Webcam";
  480. const std::string model_id = "0123:4567";
  481. AddFakeCamera(device_id, display_name, model_id);
  482. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  483. auto* camera_controller = GetCameraController();
  484. EXPECT_FALSE(camera_controller->camera_preview_widget());
  485. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  486. auto* current_preview_widget = camera_controller->camera_preview_widget();
  487. EXPECT_TRUE(current_preview_widget);
  488. // Selecting a different camera should result in the recreation of the preview
  489. // widget.
  490. camera_controller->SetSelectedCamera(CameraId(model_id, 1));
  491. EXPECT_TRUE(camera_controller->camera_preview_widget());
  492. EXPECT_NE(current_preview_widget, camera_controller->camera_preview_widget());
  493. }
  494. TEST_F(CaptureModeCameraTest, MultipleCamerasOfTheSameModel) {
  495. auto* camera_controller = GetCameraController();
  496. const std::string device_id_1 = "/dev/video0";
  497. const std::string display_name = "Integrated Webcam";
  498. const std::string model_id = "0123:4567";
  499. AddFakeCamera(device_id_1, display_name, model_id);
  500. const auto& available_cameras = camera_controller->available_cameras();
  501. EXPECT_EQ(1u, available_cameras.size());
  502. EXPECT_EQ(1, available_cameras[0].camera_id.number());
  503. EXPECT_EQ(model_id,
  504. available_cameras[0].camera_id.model_id_or_display_name());
  505. // Adding a new camera of the same model should be correctly tracked with a
  506. // different ID.
  507. const std::string device_id_2 = "/dev/video1";
  508. AddFakeCamera(device_id_2, display_name, model_id);
  509. EXPECT_EQ(2u, available_cameras.size());
  510. EXPECT_EQ(2, available_cameras[1].camera_id.number());
  511. EXPECT_EQ(model_id,
  512. available_cameras[1].camera_id.model_id_or_display_name());
  513. EXPECT_NE(available_cameras[0].camera_id, available_cameras[1].camera_id);
  514. }
  515. TEST_F(CaptureModeCameraTest, MissingCameraModelId) {
  516. auto* camera_controller = GetCameraController();
  517. const std::string device_id = "/dev/video0";
  518. const std::string display_name = "Integrated Webcam";
  519. AddFakeCamera(device_id, display_name, /*model_id=*/"");
  520. // The camera's display name should be used instead of a model ID when it's
  521. // missing.
  522. const auto& available_cameras = camera_controller->available_cameras();
  523. EXPECT_EQ(1u, available_cameras.size());
  524. EXPECT_TRUE(available_cameras[0].camera_id.is_valid());
  525. EXPECT_EQ(1, available_cameras[0].camera_id.number());
  526. EXPECT_EQ(display_name,
  527. available_cameras[0].camera_id.model_id_or_display_name());
  528. // If the SystemMonitor triggered a device change alert for some reason, but
  529. // the actual list of cameras didn't change, observers should never be
  530. // notified again.
  531. {
  532. base::RunLoop loop;
  533. camera_controller->SetOnCameraListReceivedForTesting(loop.QuitClosure());
  534. CameraDevicesChangeWaiter observer;
  535. base::SystemMonitor::Get()->ProcessDevicesChanged(
  536. base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
  537. loop.Run();
  538. EXPECT_EQ(0, observer.camera_change_event_count());
  539. }
  540. }
  541. TEST_F(CaptureModeCameraTest, CameraFramesFlipping) {
  542. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  543. auto* camera_controller = GetCameraController();
  544. int index = 0;
  545. for (const auto facing_mode :
  546. {media::MEDIA_VIDEO_FACING_NONE, media::MEDIA_VIDEO_FACING_USER,
  547. media::MEDIA_VIDEO_FACING_ENVIRONMENT}) {
  548. const std::string device_id = base::StringPrintf("/dev/video%d", index);
  549. const std::string display_name = base::StringPrintf("Camera %d", index);
  550. AddFakeCamera(device_id, display_name, display_name, facing_mode);
  551. camera_controller->SetSelectedCamera(CameraId(display_name, 1));
  552. EXPECT_TRUE(camera_controller->camera_preview_widget());
  553. const bool should_be_flipped =
  554. facing_mode != media::MEDIA_VIDEO_FACING_ENVIRONMENT;
  555. EXPECT_EQ(should_be_flipped, camera_controller->camera_preview_view()
  556. ->should_flip_frames_horizontally())
  557. << "Failed for facing mode: " << facing_mode;
  558. ++index;
  559. }
  560. }
  561. TEST_F(CaptureModeCameraTest, DisconnectSelectedCamera) {
  562. AddDefaultCamera();
  563. auto* camera_controller = GetCameraController();
  564. const CameraId camera_id(kDefaultCameraModelId, 1);
  565. camera_controller->SetSelectedCamera(camera_id);
  566. // Disconnect a selected camera, and expect that the grace period timer is
  567. // running.
  568. RemoveDefaultCamera();
  569. base::OneShotTimer* timer =
  570. camera_controller->camera_reconnect_timer_for_test();
  571. EXPECT_TRUE(timer->IsRunning());
  572. EXPECT_EQ(camera_id, camera_controller->selected_camera());
  573. // When the timer fires before the camera gets reconnected, the selected
  574. // camera ID is cleared.
  575. timer->FireNow();
  576. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  577. EXPECT_FALSE(timer->IsRunning());
  578. }
  579. TEST_F(CaptureModeCameraTest, SelectUnavailableCameraDuringGracePeriod) {
  580. auto* camera_controller = AddAndRemoveCameraAndTriggerGracePeriod();
  581. base::OneShotTimer* timer =
  582. camera_controller->camera_reconnect_timer_for_test();
  583. EXPECT_TRUE(timer->IsRunning());
  584. // Selecting an unavailable camera during the grace period should keep the
  585. // timer running for another grace period.
  586. const CameraId new_camera_id("Different Camera", 1);
  587. camera_controller->SetSelectedCamera(new_camera_id);
  588. EXPECT_TRUE(timer->IsRunning());
  589. EXPECT_EQ(new_camera_id, camera_controller->selected_camera());
  590. // Once the timer fires the new ID will also be cleared.
  591. timer->FireNow();
  592. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  593. EXPECT_FALSE(timer->IsRunning());
  594. }
  595. TEST_F(CaptureModeCameraTest, SelectAvailableCameraDuringGracePeriod) {
  596. const std::string device_id = "/dev/video0";
  597. const std::string display_name = "Integrated Webcam";
  598. const CameraId available_camera_id(display_name, 1);
  599. AddFakeCamera(device_id, display_name, /*model_id=*/"");
  600. // This adds the default camera as the selected one, and removes it triggering
  601. // a grace period.
  602. auto* camera_controller = AddAndRemoveCameraAndTriggerGracePeriod();
  603. base::OneShotTimer* timer =
  604. camera_controller->camera_reconnect_timer_for_test();
  605. EXPECT_TRUE(timer->IsRunning());
  606. // Selecting the available camera during the grace period should stop the
  607. // timer immediately.
  608. camera_controller->SetSelectedCamera(available_camera_id);
  609. EXPECT_FALSE(timer->IsRunning());
  610. EXPECT_EQ(available_camera_id, camera_controller->selected_camera());
  611. }
  612. // This tests simulates a flaky camera connection.
  613. TEST_F(CaptureModeCameraTest, ReconnectDuringGracePeriod) {
  614. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  615. auto* camera_controller = AddAndRemoveCameraAndTriggerGracePeriod();
  616. base::OneShotTimer* timer =
  617. camera_controller->camera_reconnect_timer_for_test();
  618. EXPECT_TRUE(timer->IsRunning());
  619. EXPECT_FALSE(camera_controller->camera_preview_widget());
  620. // Re-add the camera during the grace period, the timer should stop, and the
  621. // preview should reshow.
  622. AddDefaultCamera();
  623. EXPECT_FALSE(timer->IsRunning());
  624. EXPECT_TRUE(camera_controller->camera_preview_widget());
  625. }
  626. // Tests a flaky camera that disconnects before recording begins and reconnects
  627. // during recording within the grace period.
  628. TEST_F(CaptureModeCameraTest, ReconnectDuringGracePeriodAfterRecordingStarts) {
  629. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  630. auto* camera_controller = AddAndRemoveCameraAndTriggerGracePeriod();
  631. base::OneShotTimer* timer =
  632. camera_controller->camera_reconnect_timer_for_test();
  633. EXPECT_TRUE(timer->IsRunning());
  634. EXPECT_FALSE(camera_controller->camera_preview_widget());
  635. // Start recording, and expect that `should_show_preview_` will change to
  636. // false.
  637. EXPECT_TRUE(camera_controller->should_show_preview());
  638. StartVideoRecordingImmediately();
  639. EXPECT_FALSE(camera_controller->should_show_preview());
  640. // Re-add the camera during the grace period, the timer should stop, but the
  641. // preview should not be recreated.
  642. AddDefaultCamera();
  643. EXPECT_FALSE(timer->IsRunning());
  644. EXPECT_FALSE(camera_controller->camera_preview_widget());
  645. }
  646. TEST_F(CaptureModeCameraTest, SelectedCameraChangedObserver) {
  647. AddDefaultCamera();
  648. auto* camera_controller = GetCameraController();
  649. const CameraId camera_id(kDefaultCameraModelId, 1);
  650. CameraDevicesChangeWaiter observer;
  651. camera_controller->SetSelectedCamera(camera_id);
  652. EXPECT_EQ(1, observer.selected_camera_change_event_count());
  653. // Selecting the same camera ID again should not trigger an observer call.
  654. camera_controller->SetSelectedCamera(camera_id);
  655. EXPECT_EQ(1, observer.selected_camera_change_event_count());
  656. // Clearing the ID should.
  657. camera_controller->SetSelectedCamera(CameraId());
  658. EXPECT_EQ(2, observer.selected_camera_change_event_count());
  659. }
  660. TEST_F(CaptureModeCameraTest, ShouldShowPreviewTest) {
  661. auto* controller = CaptureModeController::Get();
  662. auto* camera_controller = GetCameraController();
  663. controller->SetSource(CaptureModeSource::kFullscreen);
  664. controller->SetType(CaptureModeType::kVideo);
  665. controller->Start(CaptureModeEntryType::kQuickSettings);
  666. // should_show_preview() should return true when CaptureModeSession is started
  667. // in video recording mode.
  668. EXPECT_TRUE(camera_controller->should_show_preview());
  669. // Switch to image capture mode, should_show_preview() should return false.
  670. controller->SetType(CaptureModeType::kImage);
  671. EXPECT_FALSE(camera_controller->should_show_preview());
  672. // Stop an existing capture session, should_show_preview() should return
  673. // false.
  674. controller->Stop();
  675. EXPECT_FALSE(camera_controller->should_show_preview());
  676. EXPECT_FALSE(controller->IsActive());
  677. // Start another capture session and start video recording,
  678. // should_show_preview() should return false when video recording ends.
  679. controller->SetType(CaptureModeType::kVideo);
  680. controller->Start(CaptureModeEntryType::kQuickSettings);
  681. EXPECT_TRUE(camera_controller->should_show_preview());
  682. controller->StartVideoRecordingImmediatelyForTesting();
  683. EXPECT_TRUE(camera_controller->should_show_preview());
  684. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  685. EXPECT_FALSE(camera_controller->should_show_preview());
  686. }
  687. TEST_F(CaptureModeCameraTest, ManagedByPolicyCameraOptions) {
  688. GetTestDelegate()->set_is_camera_disabled_by_policy(true);
  689. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  690. OpenSettingsView();
  691. // At this moment, there are no camera devices connected. The camera menu
  692. // group should be hidden.
  693. CaptureModeSettingsTestApi test_api;
  694. CaptureModeMenuGroup* camera_menu_group = test_api.GetCameraMenuGroup();
  695. ASSERT_TRUE(camera_menu_group);
  696. EXPECT_FALSE(camera_menu_group->GetVisible());
  697. // Camera addition/removal are still observed even when managed by policy, but
  698. // once a camera is added, the group becomes visible, but shows only a dimmed
  699. // "Off" option.
  700. AddDefaultCamera();
  701. EXPECT_TRUE(camera_menu_group->GetVisible());
  702. EXPECT_TRUE(camera_menu_group->IsOptionChecked(kCameraOff));
  703. EXPECT_FALSE(camera_menu_group->IsOptionEnabled(kCameraOff));
  704. EXPECT_FALSE(test_api.GetCameraOption(kCameraDevicesBegin));
  705. // Selecting a camera will be ignored.
  706. auto* camera_controller = GetCameraController();
  707. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  708. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  709. EXPECT_TRUE(camera_menu_group->IsOptionChecked(kCameraOff));
  710. EXPECT_FALSE(camera_controller->camera_preview_widget());
  711. // Removing the existing camera should hide the camera menu group and remove
  712. // all its options.
  713. RemoveDefaultCamera();
  714. EXPECT_FALSE(camera_menu_group->GetVisible());
  715. EXPECT_FALSE(test_api.GetCameraOption(kCameraOff));
  716. }
  717. // Tests that the options on camera menu are shown and checked correctly when
  718. // adding or removing cameras. Also tests that `selected_camera_` is updated
  719. // correspondently.
  720. TEST_F(CaptureModeCameraTest, CheckCameraOptions) {
  721. auto* camera_controller = GetCameraController();
  722. const std::string device_id_1 = "/dev/video0";
  723. const std::string display_name_1 = "Integrated Webcam";
  724. const std::string device_id_2 = "/dev/video1";
  725. const std::string display_name_2 = "Integrated Webcam 1";
  726. AddFakeCamera(device_id_1, display_name_1, display_name_1);
  727. AddFakeCamera(device_id_2, display_name_2, display_name_2);
  728. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  729. OpenSettingsView();
  730. // Check camera settings is shown. `Off` option is checked. Two camera options
  731. // are not checked.
  732. CaptureModeSettingsTestApi test_api;
  733. CaptureModeMenuGroup* camera_menu_group = test_api.GetCameraMenuGroup();
  734. EXPECT_TRUE(camera_menu_group && camera_menu_group->GetVisible());
  735. EXPECT_TRUE(camera_menu_group->IsOptionChecked(kCameraOff));
  736. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraDevicesBegin));
  737. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraDevicesBegin + 1));
  738. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  739. // Click the option for camera device 1, check its display name matches with
  740. // the camera device 1 display name and it's checked. Also check the selected
  741. // camera is valid now.
  742. ClickOnView(test_api.GetCameraOption(kCameraDevicesBegin),
  743. GetEventGenerator());
  744. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraOff));
  745. EXPECT_EQ(base::UTF16ToUTF8(camera_menu_group->GetOptionLabelForTesting(
  746. kCameraDevicesBegin)),
  747. display_name_1);
  748. EXPECT_TRUE(camera_menu_group->IsOptionChecked(kCameraDevicesBegin));
  749. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  750. // Now disconnect camera device 1.
  751. RemoveFakeCamera(device_id_1);
  752. // Check the camera device 1 is removed from the camera menu. There's only a
  753. // camera option for camera device 2. Selected camera is still valid. `Off`
  754. // option and option for camera device 2 are not checked.
  755. EXPECT_TRUE(test_api.GetCameraOption(kCameraDevicesBegin));
  756. EXPECT_FALSE(test_api.GetCameraOption(kCameraDevicesBegin + 1));
  757. EXPECT_EQ(base::UTF16ToUTF8(camera_menu_group->GetOptionLabelForTesting(
  758. kCameraDevicesBegin)),
  759. display_name_2);
  760. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraOff));
  761. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraDevicesBegin));
  762. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  763. // Now connect the camera device 1 again.
  764. AddFakeCamera(device_id_1, display_name_1, display_name_1);
  765. // Check the camera device 1 is added back to the camera menu and it's checked
  766. // automatically. Check the selected option's label matches with the camera
  767. // device 1's display name.
  768. // Note that `device_id_1` ("/dev/video0") comes before `device_id_2`
  769. // ("/dev/video1") in sort order, so it will be added first in the menu.
  770. EXPECT_TRUE(test_api.GetCameraOption(kCameraDevicesBegin));
  771. EXPECT_TRUE(test_api.GetCameraOption(kCameraDevicesBegin + 1));
  772. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraOff));
  773. EXPECT_TRUE(camera_menu_group->IsOptionChecked(kCameraDevicesBegin));
  774. EXPECT_FALSE(camera_menu_group->IsOptionChecked(kCameraDevicesBegin + 1));
  775. EXPECT_EQ(base::UTF16ToUTF8(camera_menu_group->GetOptionLabelForTesting(
  776. kCameraDevicesBegin)),
  777. display_name_1);
  778. EXPECT_EQ(base::UTF16ToUTF8(camera_menu_group->GetOptionLabelForTesting(
  779. kCameraDevicesBegin + 1)),
  780. display_name_2);
  781. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  782. }
  783. TEST_F(CaptureModeCameraTest, CameraPreviewWidgetStackingInFullscreen) {
  784. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  785. auto* camera_controller = GetCameraController();
  786. AddDefaultCamera();
  787. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  788. const auto* camera_preview_widget =
  789. camera_controller->camera_preview_widget();
  790. EXPECT_TRUE(camera_preview_widget);
  791. auto* preview_window = camera_preview_widget->GetNativeWindow();
  792. const auto* menu_container = preview_window->GetRootWindow()->GetChildById(
  793. kShellWindowId_MenuContainer);
  794. auto* parent = preview_window->parent();
  795. // Parent of the preview should be the MenuContainer when capture mode
  796. // session is active with `kFullscreen` type. And the preview window should
  797. // be the bottom-most child of it.
  798. EXPECT_EQ(parent, menu_container);
  799. EXPECT_EQ(menu_container->children().front(), preview_window);
  800. StartRecordingFromSource(CaptureModeSource::kFullscreen);
  801. // Parent of the preview should be the MenuContainer when video recording
  802. // in progress with `kFullscreen` type. And the preview window should be the
  803. // top-most child of it.
  804. preview_window = camera_preview_widget->GetNativeWindow();
  805. parent = preview_window->parent();
  806. EXPECT_EQ(parent, menu_container);
  807. EXPECT_EQ(menu_container->children().back(), preview_window);
  808. }
  809. TEST_F(CaptureModeCameraTest, CameraPreviewWidgetStackingInRegion) {
  810. auto* controller =
  811. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  812. auto* camera_controller = GetCameraController();
  813. AddDefaultCamera();
  814. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  815. const auto* camera_preview_widget =
  816. camera_controller->camera_preview_widget();
  817. EXPECT_TRUE(camera_preview_widget);
  818. auto* preview_window = camera_preview_widget->GetNativeWindow();
  819. // Parent of the preview should be the UnparentedContainer when the user
  820. // capture region is not set.
  821. EXPECT_TRUE(controller->user_capture_region().IsEmpty());
  822. EXPECT_EQ(preview_window->parent(),
  823. preview_window->GetRootWindow()->GetChildById(
  824. kShellWindowId_UnparentedContainer));
  825. EXPECT_FALSE(camera_preview_widget->IsVisible());
  826. controller->SetUserCaptureRegion(gfx::Rect(10, 20, 80, 60),
  827. /*by_user=*/true);
  828. StartRecordingFromSource(CaptureModeSource::kRegion);
  829. const auto* menu_container = preview_window->GetRootWindow()->GetChildById(
  830. kShellWindowId_MenuContainer);
  831. // Parent of the preview should be the MenuContainer when video recording
  832. // in progress with `kRegion` type. And the preview window should be the
  833. // top-most child of it.
  834. ASSERT_EQ(preview_window->parent(), menu_container);
  835. EXPECT_EQ(menu_container->children().back(), preview_window);
  836. }
  837. // Tests that camera preview widget is shown, hidden and parented correctly
  838. // while moving, dragging and updating the user selection region.
  839. TEST_F(CaptureModeCameraTest, CameraPreviewWhileUpdatingCaptureRegion) {
  840. UpdateDisplay("800x700");
  841. auto* controller =
  842. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  843. auto* camera_controller = GetCameraController();
  844. auto* capture_session = controller->capture_mode_session();
  845. AddDefaultCamera();
  846. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  847. const auto* camera_preview_widget =
  848. camera_controller->camera_preview_widget();
  849. EXPECT_TRUE(camera_preview_widget);
  850. auto* preview_window = camera_preview_widget->GetNativeWindow();
  851. const int min_region_length =
  852. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera;
  853. const gfx::Rect capture_region(10, 20, min_region_length, min_region_length);
  854. controller->SetUserCaptureRegion(capture_region, /*by_user=*/true);
  855. // After user capture region is set, parent of the preview should be the
  856. // MenuContainer.
  857. const auto* menu_container = preview_window->GetRootWindow()->GetChildById(
  858. kShellWindowId_MenuContainer);
  859. ASSERT_EQ(preview_window->parent(), menu_container);
  860. EXPECT_TRUE(camera_preview_widget->IsVisible());
  861. EXPECT_TRUE(preview_window->IsVisible());
  862. // Press the bottom right of selection region. Verify preview is hidden and
  863. // it's still parented to `menu_container`.
  864. auto* event_generator = GetEventGenerator();
  865. event_generator->set_current_screen_location(capture_region.bottom_right());
  866. event_generator->PressLeftButton();
  867. EXPECT_FALSE(camera_preview_widget->IsVisible());
  868. EXPECT_FALSE(preview_window->IsVisible());
  869. ASSERT_EQ(preview_window->parent(), menu_container);
  870. // Move mouse to update the selection region. Verify preview is still
  871. // hidden.
  872. const gfx::Vector2d delta(15, 20);
  873. event_generator->MoveMouseTo(capture_region.bottom_right() + delta);
  874. EXPECT_TRUE(capture_session->is_drag_in_progress());
  875. EXPECT_FALSE(camera_preview_widget->IsVisible());
  876. EXPECT_FALSE(preview_window->IsVisible());
  877. ASSERT_EQ(preview_window->parent(), menu_container);
  878. // Now release the drag to end selection region update. Verify preview is
  879. // shown and parent of the preview should be MenuContainer.
  880. event_generator->ReleaseLeftButton();
  881. EXPECT_FALSE(capture_session->is_drag_in_progress());
  882. EXPECT_TRUE(camera_preview_widget->IsVisible());
  883. EXPECT_TRUE(preview_window->IsVisible());
  884. EXPECT_EQ(preview_window->parent(), menu_container);
  885. // Press in the selection region to move it around. Since in the
  886. // use case, selection region is not updated, preview should not be hidden.
  887. const gfx::Point current_position(capture_region.origin() + delta);
  888. event_generator->set_current_screen_location(current_position);
  889. event_generator->PressLeftButton();
  890. EXPECT_TRUE(camera_preview_widget->IsVisible());
  891. EXPECT_EQ(preview_window->parent(), menu_container);
  892. // Move mouse to move selection region around. Verify preview is shown.
  893. event_generator->MoveMouseTo(current_position + delta);
  894. EXPECT_TRUE(camera_preview_widget->IsVisible());
  895. EXPECT_EQ(preview_window->parent(), menu_container);
  896. // Now release the move to end moving selection region. Verify preview is
  897. // shown.
  898. event_generator->ReleaseLeftButton();
  899. EXPECT_TRUE(camera_preview_widget->IsVisible());
  900. EXPECT_EQ(preview_window->parent(), menu_container);
  901. }
  902. TEST_F(CaptureModeCameraTest, CameraPreviewWidgetStackingInWindow) {
  903. auto* controller =
  904. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  905. auto* camera_controller = GetCameraController();
  906. AddDefaultCamera();
  907. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  908. const auto* camera_preview_widget =
  909. camera_controller->camera_preview_widget();
  910. EXPECT_TRUE(camera_preview_widget);
  911. auto* preview_window = camera_preview_widget->GetNativeWindow();
  912. // The parent of the preview should be the UnparentedContainer when selected
  913. // window is not set.
  914. ASSERT_FALSE(controller->capture_mode_session()->GetSelectedWindow());
  915. EXPECT_EQ(preview_window->parent(),
  916. preview_window->GetRootWindow()->GetChildById(
  917. kShellWindowId_UnparentedContainer));
  918. EXPECT_FALSE(camera_preview_widget->IsVisible());
  919. StartRecordingFromSource(CaptureModeSource::kWindow);
  920. // Parent of the preview widget should be the window being recorded when video
  921. // recording in progress with `kWindow` type. And the preview window should be
  922. // the top-most child of it.
  923. const auto* parent = preview_window->parent();
  924. const auto* window_being_recorded =
  925. controller->video_recording_watcher_for_testing()
  926. ->window_being_recorded();
  927. ASSERT_EQ(parent, window_being_recorded);
  928. EXPECT_EQ(window_being_recorded->children().back(), preview_window);
  929. }
  930. // Tests the visibility of camera menu when there's no camera connected.
  931. TEST_F(CaptureModeCameraTest, CheckCameraMenuVisibility) {
  932. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  933. OpenSettingsView();
  934. // Check camera menu is hidden.
  935. CaptureModeSettingsTestApi test_api;
  936. CaptureModeMenuGroup* camera_menu_group = test_api.GetCameraMenuGroup();
  937. EXPECT_TRUE(camera_menu_group && !camera_menu_group->GetVisible());
  938. // Connect a camera.
  939. AddDefaultCamera();
  940. // Check the camera menu is shown. And there's an `Off` option and an option
  941. // for the connected camera.
  942. camera_menu_group = test_api.GetCameraMenuGroup();
  943. EXPECT_TRUE(camera_menu_group && camera_menu_group->GetVisible());
  944. EXPECT_TRUE(test_api.GetCameraOption(kCameraOff));
  945. EXPECT_TRUE(test_api.GetCameraOption(kCameraDevicesBegin));
  946. // Now disconnect the camera.
  947. RemoveDefaultCamera();
  948. // Check the menu group is hidden again and all options has been removed from
  949. // the menu.
  950. camera_menu_group = test_api.GetCameraMenuGroup();
  951. EXPECT_TRUE(camera_menu_group && !camera_menu_group->GetVisible());
  952. EXPECT_FALSE(test_api.GetCameraOption(kCameraOff));
  953. EXPECT_FALSE(test_api.GetCameraOption(kCameraDevicesBegin));
  954. }
  955. TEST_F(CaptureModeCameraTest, CameraPreviewWidgetBounds) {
  956. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  957. CaptureModeType::kVideo);
  958. auto* camera_controller = GetCameraController();
  959. AddDefaultCamera();
  960. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  961. ASSERT_EQ(CameraPreviewSnapPosition::kBottomRight,
  962. camera_controller->camera_preview_snap_position());
  963. const auto* preview_widget = camera_controller->camera_preview_widget();
  964. EXPECT_TRUE(preview_widget);
  965. // Verifies the camera preview's alignment with `kBottomRight` snap position
  966. // and `kFullscreen` capture source.
  967. const auto* capture_mode_session = controller->capture_mode_session();
  968. const gfx::Rect work_area =
  969. display::Screen::GetScreen()
  970. ->GetDisplayNearestWindow(capture_mode_session->current_root())
  971. .work_area();
  972. VerifyPreviewAlignment(work_area);
  973. // Switching to `kRegion` without capture region set, the preview widget
  974. // should not be shown.
  975. controller->SetSource(CaptureModeSource::kRegion);
  976. EXPECT_TRUE(controller->user_capture_region().IsEmpty());
  977. EXPECT_FALSE(preview_widget->IsVisible());
  978. // Verifies the camera preview's alignment with `kBottomRight` snap position
  979. // and `kRegion` capture source.
  980. const gfx::Rect capture_region(10, 20, 300, 200);
  981. controller->SetUserCaptureRegion(capture_region, /*by_user=*/true);
  982. VerifyPreviewAlignment(capture_region);
  983. // Verifies the camera preview's alignment after switching back to
  984. // `kFullscreen.`
  985. controller->SetSource(CaptureModeSource::kFullscreen);
  986. VerifyPreviewAlignment(work_area);
  987. // Verifies the camera preview's alignment with `kBottomLeft` snap position
  988. // and `kRegion` capture source.
  989. controller->SetSource(CaptureModeSource::kRegion);
  990. camera_controller->SetCameraPreviewSnapPosition(
  991. CameraPreviewSnapPosition::kBottomLeft);
  992. VerifyPreviewAlignment(capture_region);
  993. // Verifies the camera preview's alignment with `kTopLeft` snap position
  994. // and `kRegion` capture source.
  995. camera_controller->SetCameraPreviewSnapPosition(
  996. CameraPreviewSnapPosition::kTopLeft);
  997. VerifyPreviewAlignment(capture_region);
  998. // Verifies the camera preview's alignment with `kTopRight` snap position
  999. // and `kRegion` capture source.
  1000. camera_controller->SetCameraPreviewSnapPosition(
  1001. CameraPreviewSnapPosition::kTopRight);
  1002. VerifyPreviewAlignment(capture_region);
  1003. // Set capture region to empty, the preview should be hidden again.
  1004. controller->SetUserCaptureRegion(gfx::Rect(), /*by_user=*/true);
  1005. EXPECT_FALSE(preview_widget->IsVisible());
  1006. // Verifies the camera preview's alignment with `kTopRight` snap position and
  1007. // `kWindow` capture source.
  1008. StartRecordingFromSource(CaptureModeSource::kWindow);
  1009. const auto* window_being_recorded =
  1010. controller->video_recording_watcher_for_testing()
  1011. ->window_being_recorded();
  1012. DCHECK(window_being_recorded);
  1013. VerifyPreviewAlignment(window_being_recorded->GetBoundsInScreen());
  1014. }
  1015. TEST_F(CaptureModeCameraTest, MultiDisplayCameraPreviewWidgetBounds) {
  1016. UpdateDisplay("800x700,801+0-800x700");
  1017. const gfx::Point point_in_second_display = gfx::Point(1000, 500);
  1018. auto* event_generator = GetEventGenerator();
  1019. MoveMouseToAndUpdateCursorDisplay(point_in_second_display, event_generator);
  1020. // Start the capture session in the second display.
  1021. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  1022. CaptureModeType::kVideo);
  1023. auto* camera_controller = GetCameraController();
  1024. AddDefaultCamera();
  1025. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1026. const gfx::Rect second_display_bounds(801, 0, 800, 700);
  1027. // The camera preview should reside inside the second display when we start
  1028. // capture session in the second display.
  1029. const auto* preview_widget = camera_controller->camera_preview_widget();
  1030. EXPECT_TRUE(second_display_bounds.Contains(
  1031. preview_widget->GetWindowBoundsInScreen()));
  1032. // Move the capture session to the primary display should move the camera
  1033. // preview to the primary display as well.
  1034. MoveMouseToAndUpdateCursorDisplay(gfx::Point(10, 20), event_generator);
  1035. EXPECT_TRUE(gfx::Rect(0, 0, 800, 700)
  1036. .Contains(preview_widget->GetWindowBoundsInScreen()));
  1037. // Move back to the second display, switch to `kRegion` and set the capture
  1038. // region. The camera preview should be moved back to the second display and
  1039. // inside the capture region.
  1040. MoveMouseToAndUpdateCursorDisplay(point_in_second_display, event_generator);
  1041. controller->SetSource(CaptureModeSource::kRegion);
  1042. // The capture region set through `controller` is in root coordinate.
  1043. const gfx::Rect capture_region(100, 0, 400, 550);
  1044. controller->SetUserCaptureRegion(capture_region, /*by_user=*/true);
  1045. const gfx::Rect capture_region_in_screen(901, 0, 400, 550);
  1046. const gfx::Rect preview_bounds = preview_widget->GetWindowBoundsInScreen();
  1047. EXPECT_TRUE(second_display_bounds.Contains(preview_bounds));
  1048. EXPECT_TRUE(capture_region_in_screen.Contains(preview_bounds));
  1049. // Start the window recording inside the second display, the camera preview
  1050. // should be inside the window that is being recorded inside the second
  1051. // display.
  1052. window()->SetBoundsInScreen(
  1053. gfx::Rect(900, 0, 600, 500),
  1054. display::Screen::GetScreen()->GetDisplayNearestWindow(
  1055. Shell::GetAllRootWindows()[1]));
  1056. StartRecordingFromSource(CaptureModeSource::kWindow);
  1057. const auto* window_being_recorded =
  1058. controller->video_recording_watcher_for_testing()
  1059. ->window_being_recorded();
  1060. EXPECT_TRUE(window_being_recorded->GetBoundsInScreen().Contains(
  1061. preview_widget->GetWindowBoundsInScreen()));
  1062. }
  1063. // Tests that switching from `kImage` to `kVideo` with capture source `kWindow`,
  1064. // and capture window is already selected before the switch, the camera preview
  1065. // widget should be positioned and parented correctly.
  1066. TEST_F(CaptureModeCameraTest, CameraPreviewWidgetAfterTypeSwitched) {
  1067. auto* controller =
  1068. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kImage);
  1069. auto* camera_controller = GetCameraController();
  1070. GetEventGenerator()->MoveMouseToCenterOf(window());
  1071. AddDefaultCamera();
  1072. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1073. controller->SetType(CaptureModeType::kVideo);
  1074. const auto* camera_preview_widget =
  1075. camera_controller->camera_preview_widget();
  1076. EXPECT_TRUE(camera_preview_widget);
  1077. auto* camera_preview_window = camera_preview_widget->GetNativeWindow();
  1078. const auto* selected_window =
  1079. controller->capture_mode_session()->GetSelectedWindow();
  1080. ASSERT_EQ(camera_preview_window->parent(), selected_window);
  1081. // Verify that camera preview is at the bottom right corner of the window.
  1082. VerifyPreviewAlignment(selected_window->GetBoundsInScreen());
  1083. // `camera_preview_window` should not have a transient parent.
  1084. EXPECT_FALSE(wm::GetTransientParent(camera_preview_window));
  1085. }
  1086. // Tests that audio and camera menu groups should be hidden from the settings
  1087. // menu when there's a video recording in progress.
  1088. TEST_F(CaptureModeCameraTest,
  1089. AudioAndCameraMenuGroupsAreHiddenWhenVideoRecordingInProgress) {
  1090. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  1091. CaptureModeType::kVideo);
  1092. auto* camera_controller = controller->camera_controller();
  1093. StartVideoRecordingImmediately();
  1094. EXPECT_TRUE(controller->is_recording_in_progress());
  1095. // Verify there's no camera preview created, since we don't select any camera.
  1096. EXPECT_FALSE(camera_controller->camera_preview_widget());
  1097. // Check capture session is shut down after the video recording starts.
  1098. EXPECT_FALSE(controller->IsActive());
  1099. // Start a new session, check the type should be switched automatically to
  1100. // kImage.
  1101. controller->Start(CaptureModeEntryType::kQuickSettings);
  1102. EXPECT_EQ(CaptureModeType::kImage, controller->type());
  1103. // Verify there's no camera preview created after a new session started.
  1104. EXPECT_FALSE(camera_controller->camera_preview_widget());
  1105. OpenSettingsView();
  1106. // Check the audio and camera menu groups are hidden from the settings.
  1107. CaptureModeSettingsTestApi test_api_new;
  1108. EXPECT_FALSE(test_api_new.GetCameraMenuGroup());
  1109. EXPECT_FALSE(test_api_new.GetAudioInputMenuGroup());
  1110. EXPECT_TRUE(test_api_new.GetSaveToMenuGroup());
  1111. }
  1112. // Verify that starting a new capture session and updating capture source won't
  1113. // affect the current camera preview when there's a video recording is progress.
  1114. TEST_F(CaptureModeCameraTest,
  1115. CameraPreviewNotChangeWhenVideoRecordingInProgress) {
  1116. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  1117. CaptureModeType::kVideo);
  1118. auto* camera_controller = controller->camera_controller();
  1119. AddDefaultCamera();
  1120. OpenSettingsView();
  1121. // Select the default camera for video recording.
  1122. CaptureModeSettingsTestApi test_api;
  1123. ClickOnView(test_api.GetCameraOption(kCameraDevicesBegin),
  1124. GetEventGenerator());
  1125. StartVideoRecordingImmediately();
  1126. // Check that the camera preview is created.
  1127. const auto* camera_preview_widget =
  1128. camera_controller->camera_preview_widget();
  1129. EXPECT_TRUE(camera_preview_widget);
  1130. auto* preview_window = camera_preview_widget->GetNativeWindow();
  1131. auto* parent = preview_window->parent();
  1132. // Start a new capture session, and set capture source to `kFullscreen`,
  1133. // verify the camera preview and its parent are not changed.
  1134. controller->Start(CaptureModeEntryType::kQuickSettings);
  1135. controller->SetSource(CaptureModeSource::kFullscreen);
  1136. EXPECT_EQ(preview_window,
  1137. camera_controller->camera_preview_widget()->GetNativeWindow());
  1138. EXPECT_EQ(
  1139. parent,
  1140. camera_controller->camera_preview_widget()->GetNativeWindow()->parent());
  1141. // Update capture source to `kRegion` and set the user capture region, verify
  1142. // the camera preview and its parent are not changed.
  1143. controller->SetSource(CaptureModeSource::kRegion);
  1144. controller->SetUserCaptureRegion({100, 100, 200, 300}, /*by_user=*/true);
  1145. EXPECT_EQ(preview_window,
  1146. camera_controller->camera_preview_widget()->GetNativeWindow());
  1147. EXPECT_EQ(
  1148. parent,
  1149. camera_controller->camera_preview_widget()->GetNativeWindow()->parent());
  1150. // Update capture source to `kWindow` and move mouse on top the `window`,
  1151. // verify that the camera preview and its parent are not changed.
  1152. controller->SetSource(CaptureModeSource::kWindow);
  1153. auto* event_generator = GetEventGenerator();
  1154. event_generator->MoveMouseToCenterOf(window());
  1155. EXPECT_EQ(preview_window,
  1156. camera_controller->camera_preview_widget()->GetNativeWindow());
  1157. EXPECT_EQ(
  1158. parent,
  1159. camera_controller->camera_preview_widget()->GetNativeWindow()->parent());
  1160. }
  1161. // Tests that changing the folder while there's a video recording in progress
  1162. // doesn't change the folder where the video being recorded will be saved to.
  1163. // It will only affect the image to be captured.
  1164. TEST_F(CaptureModeCameraTest, ChangeFolderWhileVideoRecordingInProgress) {
  1165. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  1166. CaptureModeType::kVideo);
  1167. StartVideoRecordingImmediately();
  1168. // While the video recording is in progress, start a new capture session and
  1169. // update the save-to folder to the custom folder.
  1170. controller->Start(CaptureModeEntryType::kQuickSettings);
  1171. controller->SetCustomCaptureFolder(
  1172. CreateCustomFolderInUserDownloadsPath("test"));
  1173. // Perform the image capture. Verify that the image is saved to the custom
  1174. // folder.
  1175. controller->PerformCapture();
  1176. const base::FilePath& saved_image_file = WaitForCaptureFileToBeSaved();
  1177. EXPECT_EQ(controller->GetCustomCaptureFolder(), saved_image_file.DirName());
  1178. // End the video recoring and verify the video is still saved to the default
  1179. // downloads folder.
  1180. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  1181. const base::FilePath& saved_video_file = WaitForCaptureFileToBeSaved();
  1182. EXPECT_EQ(controller->delegate_for_testing()->GetUserDefaultDownloadsFolder(),
  1183. saved_video_file.DirName());
  1184. }
  1185. // Tests multiple scenarios to trigger selected window updates at located
  1186. // position. Camera preview's native window should be added to the ignore
  1187. // windows and no crash should happen in these cases.
  1188. TEST_F(CaptureModeCameraTest,
  1189. UpdateSelectedWindowAtPositionWithCameraPreviewIgnored) {
  1190. auto* controller =
  1191. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  1192. AddDefaultCamera();
  1193. auto* camera_controller = GetCameraController();
  1194. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1195. auto* event_generator = GetEventGenerator();
  1196. event_generator->MoveMouseToCenterOf(window());
  1197. EXPECT_TRUE(camera_controller->camera_preview_widget());
  1198. // No camera preview when it is in `kImage`.
  1199. controller->SetType(CaptureModeType::kImage);
  1200. event_generator->MoveMouseToCenterOf(window());
  1201. EXPECT_FALSE(camera_controller->camera_preview_widget());
  1202. // The native window of camera preview widget should be ignored from the
  1203. // candidates of the selected window. So moving the mouse to be on top of the
  1204. // camera preview should not cause any crash or selected window changes.
  1205. controller->SetType(CaptureModeType::kVideo);
  1206. const auto* camera_preview_widget =
  1207. camera_controller->camera_preview_widget();
  1208. const auto* capture_mode_session = controller->capture_mode_session();
  1209. event_generator->MoveMouseToCenterOf(
  1210. camera_preview_widget->GetNativeWindow());
  1211. EXPECT_EQ(window(), capture_mode_session->GetSelectedWindow());
  1212. EXPECT_TRUE(window()->IsVisible());
  1213. EXPECT_TRUE(camera_preview_widget->IsVisible());
  1214. // Hide `window_` with camera preview on should not cause any crash and
  1215. // selected window should be updated to nullptr.
  1216. window()->Hide();
  1217. EXPECT_FALSE(window()->IsVisible());
  1218. EXPECT_FALSE(camera_preview_widget->IsVisible());
  1219. EXPECT_FALSE(capture_mode_session->GetSelectedWindow());
  1220. // Reshow `window_` without hovering over it should not set the selected
  1221. // window. Camera preview should still be hidden as its parent hasn't been set
  1222. // to `window_` yet.
  1223. const auto* preview_native_window = camera_preview_widget->GetNativeWindow();
  1224. window()->Show();
  1225. EXPECT_TRUE(window()->IsVisible());
  1226. EXPECT_FALSE(camera_preview_widget->IsVisible());
  1227. EXPECT_FALSE(capture_mode_session->GetSelectedWindow());
  1228. EXPECT_EQ(preview_native_window->parent(),
  1229. preview_native_window->GetRootWindow()->GetChildById(
  1230. kShellWindowId_UnparentedContainer));
  1231. // Hovering over `window_` should set it to the selected window, camera
  1232. // preview widget should be reparented to it as well. And the camera preview
  1233. // widget should be visible now.
  1234. event_generator->MoveMouseToCenterOf(window());
  1235. EXPECT_EQ(preview_native_window->parent(),
  1236. capture_mode_session->GetSelectedWindow());
  1237. EXPECT_TRUE(camera_preview_widget->IsVisible());
  1238. EXPECT_EQ(window(), capture_mode_session->GetSelectedWindow());
  1239. }
  1240. // Tests that capture label's opacity changes accordingly when it's overlapped
  1241. // or it's not overlapped with camera preview. Also tests that when located
  1242. // events is or is not on capture label, its opacity is updated accordingly.
  1243. TEST_F(CaptureModeCameraTest,
  1244. CaptureLabelOpacityChangeWhenOverlappingWithCameraPreview) {
  1245. auto* controller =
  1246. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  1247. auto* capture_session = controller->capture_mode_session();
  1248. auto* camera_controller = GetCameraController();
  1249. AddDefaultCamera();
  1250. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1251. const auto* camera_preview_widget =
  1252. camera_controller->camera_preview_widget();
  1253. const auto* capture_label_widget = capture_session->capture_label_widget();
  1254. const ui::Layer* capture_label_layer = capture_label_widget->GetLayer();
  1255. // Set capture region big enough to make capture label not overlapping with
  1256. // camera preview. Verify capture label is fully opaque.
  1257. const gfx::Rect capture_region(100, 100, 700, 700);
  1258. SelectCaptureRegion(capture_region);
  1259. EXPECT_FALSE(capture_label_widget->GetWindowBoundsInScreen().Intersects(
  1260. camera_preview_widget->GetWindowBoundsInScreen()));
  1261. EXPECT_EQ(capture_label_layer->GetTargetOpacity(), 1.f);
  1262. // Update capture region smaller to make capture label overlap with camera
  1263. // preview. Verify capture label is `kOverlapOpacity`.
  1264. // Make sure to resize the region to a value that won't cause the camera to be
  1265. // hidden according to the camera size specs.
  1266. const int delta_x =
  1267. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera -
  1268. capture_region.width();
  1269. const int delta_y =
  1270. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera -
  1271. capture_region.height();
  1272. const gfx::Vector2d delta(delta_x, delta_y);
  1273. auto* event_generator = GetEventGenerator();
  1274. event_generator->set_current_screen_location(capture_region.bottom_right());
  1275. event_generator->PressLeftButton();
  1276. event_generator->MoveMouseTo(capture_region.bottom_right() + delta);
  1277. event_generator->ReleaseLeftButton();
  1278. EXPECT_TRUE(capture_label_widget->GetWindowBoundsInScreen().Intersects(
  1279. camera_preview_widget->GetWindowBoundsInScreen()));
  1280. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  1281. capture_mode::kCaptureUiOverlapOpacity);
  1282. // Move mouse on top of capture label, verify it's updated to fully opaque
  1283. // even it's still overlapped with camera preview.
  1284. const gfx::Rect capture_lable_bounds =
  1285. capture_label_widget->GetWindowBoundsInScreen();
  1286. event_generator->MoveMouseTo(capture_lable_bounds.CenterPoint());
  1287. EXPECT_TRUE(capture_lable_bounds.Intersects(
  1288. camera_preview_widget->GetWindowBoundsInScreen()));
  1289. EXPECT_EQ(capture_label_layer->GetTargetOpacity(), 1.0f);
  1290. // Move mouse to the outside of capture label, verify it's updated to
  1291. // `kOverlapOpacity`.
  1292. const gfx::Vector2d delta1(50, 50);
  1293. event_generator->MoveMouseTo(capture_lable_bounds.bottom_right() + delta1);
  1294. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  1295. capture_mode::kCaptureUiOverlapOpacity);
  1296. // Click on the outside of the capture region to reset it, verify capture
  1297. // label is updated to fully opaque.
  1298. const gfx::Rect current_capture_region = controller->user_capture_region();
  1299. event_generator->MoveMouseTo(current_capture_region.bottom_right() + delta1);
  1300. event_generator->ClickLeftButton();
  1301. EXPECT_EQ(capture_label_layer->GetTargetOpacity(), 1.0f);
  1302. }
  1303. TEST_F(CaptureModeCameraTest,
  1304. CaptureBarOpacityChangeWhenOverlappingWithCameraPreview) {
  1305. // Update display size and update window with customized size to make sure
  1306. // camera preview overlap with capture bar with capture source `kWindow`.
  1307. UpdateDisplay("1366x768");
  1308. window()->SetBounds({0, 195, 903, 492});
  1309. auto* controller =
  1310. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  1311. auto* capture_session = controller->capture_mode_session();
  1312. auto* camera_controller = GetCameraController();
  1313. AddDefaultCamera();
  1314. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1315. const auto* camera_preview_widget =
  1316. camera_controller->camera_preview_widget();
  1317. const auto* capture_bar_widget = capture_session->capture_mode_bar_widget();
  1318. const ui::Layer* capture_bar_layer = capture_bar_widget->GetLayer();
  1319. // Move mouse on top of `window` to set the selected window. Verify capture
  1320. // bar is `kOverlapOpacity`.
  1321. auto* event_generator = GetEventGenerator();
  1322. event_generator->MoveMouseTo(window()->GetBoundsInScreen().CenterPoint());
  1323. EXPECT_EQ(capture_session->GetSelectedWindow(), window());
  1324. EXPECT_TRUE(capture_bar_widget->GetWindowBoundsInScreen().Intersects(
  1325. camera_preview_widget->GetWindowBoundsInScreen()));
  1326. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(),
  1327. capture_mode::kCaptureUiOverlapOpacity);
  1328. // Move mouse on top of capture bar. Verify capture bar is updated to fully
  1329. // opaque.
  1330. event_generator->MoveMouseTo(
  1331. capture_bar_widget->GetWindowBoundsInScreen().CenterPoint());
  1332. EXPECT_TRUE(capture_bar_widget->GetWindowBoundsInScreen().Intersects(
  1333. camera_preview_widget->GetWindowBoundsInScreen()));
  1334. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1335. // Mouse mouse to the outside of capture bar, verify it's updated to
  1336. // `kOverlapOpacity`.
  1337. const gfx::Point capture_bar_origin =
  1338. capture_bar_widget->GetWindowBoundsInScreen().origin();
  1339. event_generator->MoveMouseTo(capture_bar_origin.x() - 10,
  1340. capture_bar_origin.y() - 10);
  1341. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(),
  1342. capture_mode::kCaptureUiOverlapOpacity);
  1343. }
  1344. TEST_F(CaptureModeCameraTest, CaptureBarOpacityChangeOnDisplayRotation) {
  1345. // Update display size and update window with customized size to make sure
  1346. // camera preview overlap with capture bar with capture source `kWindow`.
  1347. UpdateDisplay("1366x768");
  1348. window()->SetBounds({0, 195, 903, 492});
  1349. auto* controller =
  1350. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  1351. auto* capture_session = controller->capture_mode_session();
  1352. auto* camera_controller = GetCameraController();
  1353. AddDefaultCamera();
  1354. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1355. const auto* camera_preview_widget =
  1356. camera_controller->camera_preview_widget();
  1357. const auto* capture_bar_widget = capture_session->capture_mode_bar_widget();
  1358. const ui::Layer* capture_bar_layer = capture_bar_widget->GetLayer();
  1359. // Move mouse on top of `window` to set the selected window. Verify capture
  1360. // bar is `kOverlapOpacity`.
  1361. auto* event_generator = GetEventGenerator();
  1362. event_generator->MoveMouseTo(window()->GetBoundsInScreen().CenterPoint());
  1363. EXPECT_EQ(capture_session->GetSelectedWindow(), window());
  1364. EXPECT_TRUE(capture_bar_widget->GetWindowBoundsInScreen().Intersects(
  1365. camera_preview_widget->GetWindowBoundsInScreen()));
  1366. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(),
  1367. capture_mode::kCaptureUiOverlapOpacity);
  1368. // Rotate the primary display by 90 degrees. Verify that capture bar no longer
  1369. // overlaps with camera preview and it's updated to fully opaque.
  1370. Shell::Get()->display_manager()->SetDisplayRotation(
  1371. WindowTreeHostManager::GetPrimaryDisplayId(), display::Display::ROTATE_90,
  1372. display::Display::RotationSource::USER);
  1373. EXPECT_FALSE(capture_bar_widget->GetWindowBoundsInScreen().Intersects(
  1374. camera_preview_widget->GetWindowBoundsInScreen()));
  1375. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1376. // Rotate the primary display by 180 degrees. Verify that capture bar is
  1377. // overlapped with camera preview and it's updated to `kOverlapOpacity`.
  1378. Shell::Get()->display_manager()->SetDisplayRotation(
  1379. WindowTreeHostManager::GetPrimaryDisplayId(),
  1380. display::Display::ROTATE_180, display::Display::RotationSource::USER);
  1381. EXPECT_TRUE(capture_bar_widget->GetWindowBoundsInScreen().Intersects(
  1382. camera_preview_widget->GetWindowBoundsInScreen()));
  1383. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(),
  1384. capture_mode::kCaptureUiOverlapOpacity);
  1385. }
  1386. TEST_F(CaptureModeCameraTest, CaptureLabelOpacityChangeOnCaptureSourceChange) {
  1387. UpdateDisplay("800x600");
  1388. auto* controller =
  1389. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  1390. auto* capture_session = controller->capture_mode_session();
  1391. auto* camera_controller = GetCameraController();
  1392. AddDefaultCamera();
  1393. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1394. auto* camera_preview_widget = camera_controller->camera_preview_widget();
  1395. auto* capture_label_widget = capture_session->capture_label_widget();
  1396. ui::Layer* capture_label_layer = capture_label_widget->GetLayer();
  1397. // Select capture region to make sure capture label is overlapped with
  1398. // camera preview. Verify capture label is `kOverlapOpacity`.
  1399. const int min_region_length =
  1400. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera;
  1401. SelectCaptureRegion({100, 100, min_region_length, min_region_length});
  1402. EXPECT_TRUE(capture_label_widget->GetWindowBoundsInScreen().Intersects(
  1403. camera_preview_widget->GetWindowBoundsInScreen()));
  1404. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  1405. capture_mode::kCaptureUiOverlapOpacity);
  1406. // Change the capture source from `kRegion` to `kFullscreen`, verify capture
  1407. // label is updated to fully opaque.
  1408. controller->SetSource(CaptureModeSource::kFullscreen);
  1409. EXPECT_EQ(capture_label_layer->GetTargetOpacity(), 1.0f);
  1410. }
  1411. TEST_F(CaptureModeCameraTest,
  1412. CaptureLabelOpacityChangeWhileVideoRecordingInProgress) {
  1413. auto* controller =
  1414. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  1415. auto* camera_controller = GetCameraController();
  1416. AddDefaultCamera();
  1417. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1418. auto* camera_preview_widget = camera_controller->camera_preview_widget();
  1419. const int min_region_length =
  1420. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera;
  1421. controller->SetUserCaptureRegion(
  1422. {100, 100, min_region_length, min_region_length}, /*by_user=*/true);
  1423. StartVideoRecordingImmediately();
  1424. EXPECT_FALSE(controller->IsActive());
  1425. // Start a new capture session, verify even capture label is overlapped with
  1426. // camera preview, it's still fully opaque since camera preview does not
  1427. // belong to the new capture session.
  1428. controller->Start(CaptureModeEntryType::kQuickSettings);
  1429. EXPECT_EQ(CaptureModeSource::kRegion, controller->source());
  1430. auto* capture_session = controller->capture_mode_session();
  1431. const auto* capture_label_widget = capture_session->capture_label_widget();
  1432. EXPECT_TRUE(capture_label_widget->GetWindowBoundsInScreen().Intersects(
  1433. camera_preview_widget->GetWindowBoundsInScreen()));
  1434. EXPECT_EQ(capture_label_widget->GetLayer()->GetTargetOpacity(), 1.0f);
  1435. }
  1436. TEST_F(CaptureModeCameraTest, FocusableCameraPreviewInFullscreen) {
  1437. UpdateDisplay("800x700");
  1438. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  1439. CaptureModeType::kVideo);
  1440. AddDefaultCamera();
  1441. auto* camera_controller = GetCameraController();
  1442. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1443. auto* event_generator = GetEventGenerator();
  1444. using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup;
  1445. CaptureModeSessionTestApi test_api(controller->capture_mode_session());
  1446. // Tests that the camera preview is focusable in fullscreen capture.
  1447. auto* camera_preview_view = camera_controller->camera_preview_view();
  1448. auto* resize_button = GetPreviewResizeButton();
  1449. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/6);
  1450. EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup());
  1451. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1452. EXPECT_TRUE(camera_preview_view->has_focus());
  1453. // Press tab again should advance the focus on the resize button. And the
  1454. // resize button should be invisible before and visible after being focused.
  1455. EXPECT_FALSE(resize_button->GetVisible());
  1456. SendKey(ui::VKEY_TAB, event_generator);
  1457. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1458. EXPECT_TRUE(resize_button->has_focus());
  1459. EXPECT_TRUE(resize_button->GetVisible());
  1460. // Press space when the resize button is focused should collapse the camera
  1461. // preview.
  1462. EXPECT_TRUE(resize_button->has_focus());
  1463. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  1464. SendKey(ui::VKEY_SPACE, event_generator);
  1465. EXPECT_TRUE(camera_controller->is_camera_preview_collapsed());
  1466. // Press space again should expand the camera preview.
  1467. SendKey(ui::VKEY_SPACE, event_generator);
  1468. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  1469. // When the resize button inside the camera preview is focused, press tab
  1470. // should advance to focus on the settings button.
  1471. SendKey(ui::VKEY_TAB, event_generator);
  1472. EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup());
  1473. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1474. // The resize button should fade out and become invisible in
  1475. // `kResizeButtonShowDuration` after removing focus from it.
  1476. base::OneShotTimer* hide_timer =
  1477. camera_preview_view->resize_button_hide_timer_for_test();
  1478. EXPECT_FALSE(resize_button->has_focus());
  1479. EXPECT_TRUE(hide_timer->IsRunning());
  1480. EXPECT_EQ(hide_timer->GetCurrentDelay(),
  1481. capture_mode::kResizeButtonShowDuration);
  1482. {
  1483. ViewVisibilityChangeWaiter waiter(resize_button);
  1484. EXPECT_TRUE(resize_button->GetVisible());
  1485. hide_timer->FireNow();
  1486. waiter.Wait();
  1487. EXPECT_FALSE(resize_button->GetVisible());
  1488. }
  1489. // Shift tab should advance the focus from the settings button back to the
  1490. // resize button inside the camera preview.
  1491. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1492. EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup());
  1493. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1494. EXPECT_TRUE(resize_button->has_focus());
  1495. // The resize button should keep visible when it is focused, even trigger
  1496. // `resize_button_hide_timer_` to refresh its visibility.
  1497. hide_timer = camera_preview_view->resize_button_hide_timer_for_test();
  1498. EXPECT_TRUE(hide_timer->IsRunning());
  1499. EXPECT_TRUE(resize_button->GetVisible());
  1500. hide_timer->FireNow();
  1501. EXPECT_TRUE(resize_button->GetVisible());
  1502. // Continue shift tab should move the focus from the resize button to the
  1503. // camera preview.
  1504. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1505. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1506. EXPECT_TRUE(camera_preview_view->has_focus());
  1507. // The resize button should fade out and become invisible again in
  1508. // `kResizeButtonShowDuration` after removing focus from it.
  1509. hide_timer = camera_preview_view->resize_button_hide_timer_for_test();
  1510. EXPECT_FALSE(resize_button->has_focus());
  1511. EXPECT_TRUE(hide_timer->IsRunning());
  1512. EXPECT_EQ(hide_timer->GetCurrentDelay(),
  1513. capture_mode::kResizeButtonShowDuration);
  1514. {
  1515. ViewVisibilityChangeWaiter waiter(resize_button);
  1516. EXPECT_TRUE(resize_button->GetVisible());
  1517. hide_timer->FireNow();
  1518. waiter.Wait();
  1519. EXPECT_FALSE(resize_button->GetVisible());
  1520. }
  1521. // Tests moving the camera preview through the keyboard when it is focused.
  1522. EXPECT_TRUE(camera_controller->camera_preview_view()->has_focus());
  1523. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  1524. camera_controller->camera_preview_snap_position());
  1525. // Press control+right should not move the camera preview, as it is currently
  1526. // at the right.
  1527. SendKey(ui::VKEY_RIGHT, event_generator, ui::EF_CONTROL_DOWN);
  1528. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  1529. camera_controller->camera_preview_snap_position());
  1530. // Press control+down should not move the camera preview either, as it is
  1531. // currently at the bottom.
  1532. SendKey(ui::VKEY_DOWN, event_generator, ui::EF_CONTROL_DOWN);
  1533. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  1534. camera_controller->camera_preview_snap_position());
  1535. // Press control+left should move the camera preview from bottom right to
  1536. // bottom left.
  1537. SendKey(ui::VKEY_LEFT, event_generator, ui::EF_CONTROL_DOWN);
  1538. EXPECT_EQ(CameraPreviewSnapPosition::kBottomLeft,
  1539. camera_controller->camera_preview_snap_position());
  1540. // Press control+right now should work to move the camera preview from bottom
  1541. // left to bottom right.
  1542. SendKey(ui::VKEY_RIGHT, event_generator, ui::EF_CONTROL_DOWN);
  1543. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  1544. camera_controller->camera_preview_snap_position());
  1545. // Press control+up should move the camera preview from bottom right to top
  1546. // right.
  1547. SendKey(ui::VKEY_UP, event_generator, ui::EF_CONTROL_DOWN);
  1548. EXPECT_EQ(CameraPreviewSnapPosition::kTopRight,
  1549. camera_controller->camera_preview_snap_position());
  1550. // Shift tab again should advance the focus from the camera preview back to
  1551. // the window capture source button.
  1552. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1553. EXPECT_EQ(FocusGroup::kTypeSource, test_api.GetCurrentFocusGroup());
  1554. EXPECT_EQ(4u, test_api.GetCurrentFocusIndex());
  1555. }
  1556. TEST_F(CaptureModeCameraTest, FocusableCameraPreviewInRegion) {
  1557. UpdateDisplay("1366x768");
  1558. auto* controller = CaptureModeController::Get();
  1559. controller->SetUserCaptureRegion(gfx::Rect(10, 10, 800, 700),
  1560. /*by_user=*/true);
  1561. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  1562. AddDefaultCamera();
  1563. auto* camera_controller = GetCameraController();
  1564. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1565. auto* event_generator = GetEventGenerator();
  1566. using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup;
  1567. CaptureModeSessionTestApi test_api(controller->capture_mode_session());
  1568. // Tests that the camera preview is focusable in region capture.
  1569. auto* camera_preview_view = camera_controller->camera_preview_view();
  1570. auto* resize_button = GetPreviewResizeButton();
  1571. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/15);
  1572. EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup());
  1573. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1574. EXPECT_TRUE(camera_preview_view->has_focus());
  1575. SendKey(ui::VKEY_TAB, event_generator);
  1576. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1577. EXPECT_TRUE(resize_button->has_focus());
  1578. // When the resize button inside camera preview is focused, press tab should
  1579. // advance to focus on the capture button.
  1580. SendKey(ui::VKEY_TAB, event_generator);
  1581. EXPECT_EQ(FocusGroup::kCaptureButton, test_api.GetCurrentFocusGroup());
  1582. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1583. // Press tab again to advance focus on the settings button.
  1584. SendKey(ui::VKEY_TAB, event_generator);
  1585. EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup());
  1586. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1587. // Shift tab should advance the focus from the settings button back to the
  1588. // capture button.
  1589. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1590. EXPECT_EQ(FocusGroup::kCaptureButton, test_api.GetCurrentFocusGroup());
  1591. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1592. // Shift tab again should advance the focus from the capture button back to
  1593. // the resize button inside the camera preview.
  1594. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1595. EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup());
  1596. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1597. EXPECT_TRUE(resize_button->has_focus());
  1598. // Continue shift tab should move the focus from the resize button to the
  1599. // camera preview.
  1600. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1601. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1602. EXPECT_TRUE(camera_preview_view->has_focus());
  1603. // Shift tab to advance the focus back to the window capture source button.
  1604. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN, /*count=*/10);
  1605. EXPECT_EQ(FocusGroup::kTypeSource, test_api.GetCurrentFocusGroup());
  1606. EXPECT_EQ(4u, test_api.GetCurrentFocusIndex());
  1607. // Update the capture region to test when the resize button is not focusable.
  1608. controller->SetUserCaptureRegion(gfx::Rect(10, 10, 400, 550),
  1609. /*by_user=*/true);
  1610. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/10);
  1611. EXPECT_EQ(FocusGroup::kCameraPreview, test_api.GetCurrentFocusGroup());
  1612. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1613. EXPECT_TRUE(camera_preview_view->has_focus());
  1614. // Press tab should advance the focus on the capture button instead of the
  1615. // resize button. As the resize button is forced to be hidden, which is not
  1616. // focusable in this case.
  1617. EXPECT_FALSE(camera_preview_view->is_collapsible());
  1618. SendKey(ui::VKEY_TAB, event_generator);
  1619. EXPECT_EQ(FocusGroup::kCaptureButton, test_api.GetCurrentFocusGroup());
  1620. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1621. }
  1622. TEST_F(CaptureModeCameraTest, FocusableCameraPreviewInWindow) {
  1623. UpdateDisplay("1366x768");
  1624. // Create one more window besides `window_`.
  1625. std::unique_ptr<aura::Window> window2(
  1626. CreateTestWindow(gfx::Rect(150, 50, 800, 700)));
  1627. window()->SetBounds(gfx::Rect(30, 40, 800, 700));
  1628. auto* controller =
  1629. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  1630. AddDefaultCamera();
  1631. auto* camera_controller = GetCameraController();
  1632. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1633. auto* event_generator = GetEventGenerator();
  1634. using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup;
  1635. auto* capture_mode_session = controller->capture_mode_session();
  1636. CaptureModeSessionTestApi test_api(capture_mode_session);
  1637. const auto* preview_window =
  1638. camera_controller->camera_preview_widget()->GetNativeWindow();
  1639. // Tab to focus on `window2`, which is the most recently used window. It
  1640. // should be set to the current selected window, and the camera preview should
  1641. // be shown inside it.
  1642. auto* camera_preview_view = camera_controller->camera_preview_view();
  1643. auto* resize_button = GetPreviewResizeButton();
  1644. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/6);
  1645. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1646. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1647. EXPECT_TRUE(test_api.GetHighlightableWindow(window2.get())->has_focus());
  1648. EXPECT_EQ(window2.get(), capture_mode_session->GetSelectedWindow());
  1649. EXPECT_EQ(window2.get(), preview_window->parent());
  1650. // Press tab should advance to focus on the camera preview inside. But the
  1651. // FocusGroup should not change, as the camera preview is treated as part of
  1652. // the selected window in this case.
  1653. SendKey(ui::VKEY_TAB, event_generator);
  1654. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1655. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1656. EXPECT_TRUE(camera_preview_view->has_focus());
  1657. // Press tab should focus on the resize button inside the camera preview.
  1658. SendKey(ui::VKEY_TAB, event_generator);
  1659. EXPECT_EQ(2u, test_api.GetCurrentFocusIndex());
  1660. EXPECT_TRUE(resize_button->has_focus());
  1661. EXPECT_FALSE(camera_controller->camera_preview_view()->has_focus());
  1662. // Press tab again should advance focus and set another window `window_` to be
  1663. // the current selected window. The camera preview should be shown inside it
  1664. // now.
  1665. SendKey(ui::VKEY_TAB, event_generator);
  1666. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1667. EXPECT_EQ(3u, test_api.GetCurrentFocusIndex());
  1668. EXPECT_TRUE(test_api.GetHighlightableWindow(window())->has_focus());
  1669. EXPECT_EQ(window(), capture_mode_session->GetSelectedWindow());
  1670. EXPECT_EQ(window(), preview_window->parent());
  1671. // Press tab should advance to focus on the camera preview that inside
  1672. // `window_` now.
  1673. SendKey(ui::VKEY_TAB, event_generator);
  1674. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1675. EXPECT_EQ(4u, test_api.GetCurrentFocusIndex());
  1676. EXPECT_TRUE(camera_preview_view->has_focus());
  1677. // Press tab to advance the focus on the resize button inside the camera
  1678. // preview.
  1679. SendKey(ui::VKEY_TAB, event_generator);
  1680. EXPECT_EQ(5u, test_api.GetCurrentFocusIndex());
  1681. EXPECT_TRUE(resize_button->has_focus());
  1682. EXPECT_FALSE(camera_preview_view->has_focus());
  1683. // Press tab again should advance to focus on the settings button.
  1684. SendKey(ui::VKEY_TAB, event_generator);
  1685. EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup());
  1686. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1687. EXPECT_FALSE(resize_button->has_focus());
  1688. EXPECT_FALSE(camera_preview_view->has_focus());
  1689. // Shift tab when the settings button is focused should advance back to focus
  1690. // on the resize button inside the camera preview. And the camera preview
  1691. // should now be shown inside `window_`, which is the current selected window.
  1692. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1693. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1694. EXPECT_EQ(5u, test_api.GetCurrentFocusIndex());
  1695. EXPECT_TRUE(resize_button->has_focus());
  1696. EXPECT_FALSE(camera_preview_view->has_focus());
  1697. EXPECT_EQ(window(), capture_mode_session->GetSelectedWindow());
  1698. EXPECT_EQ(window(), preview_window->parent());
  1699. // Shift tab again should move the focus from the resize button to the camera
  1700. // preview.
  1701. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1702. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1703. EXPECT_EQ(4u, test_api.GetCurrentFocusIndex());
  1704. EXPECT_FALSE(resize_button->has_focus());
  1705. EXPECT_TRUE(camera_preview_view->has_focus());
  1706. // Shift tab again should focus on the `window_`
  1707. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1708. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1709. EXPECT_EQ(3u, test_api.GetCurrentFocusIndex());
  1710. EXPECT_TRUE(test_api.GetHighlightableWindow(window())->has_focus());
  1711. EXPECT_FALSE(resize_button->has_focus());
  1712. EXPECT_FALSE(camera_preview_view->has_focus());
  1713. EXPECT_EQ(window(), capture_mode_session->GetSelectedWindow());
  1714. // Continue shift tab should advance back to focus on the resize button inside
  1715. // the camera preview. And the camera preview should now inside `window2`,
  1716. // which is the current selected window.
  1717. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1718. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1719. EXPECT_EQ(2u, test_api.GetCurrentFocusIndex());
  1720. EXPECT_TRUE(resize_button->has_focus());
  1721. EXPECT_FALSE(camera_preview_view->has_focus());
  1722. EXPECT_EQ(window2.get(), capture_mode_session->GetSelectedWindow());
  1723. EXPECT_EQ(window2.get(), preview_window->parent());
  1724. // Continue shift tab should move the focus from the resize button to the
  1725. // camera preview.
  1726. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1727. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1728. EXPECT_FALSE(resize_button->has_focus());
  1729. EXPECT_TRUE(camera_preview_view->has_focus());
  1730. // Continue shift tab should focus on the `window2`.
  1731. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1732. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1733. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1734. EXPECT_TRUE(test_api.GetHighlightableWindow(window2.get())->has_focus());
  1735. EXPECT_FALSE(resize_button->has_focus());
  1736. EXPECT_FALSE(camera_preview_view->has_focus());
  1737. EXPECT_EQ(window2.get(), capture_mode_session->GetSelectedWindow());
  1738. // Continue shift tab should advance back to the window capture source button.
  1739. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1740. EXPECT_EQ(FocusGroup::kTypeSource, test_api.GetCurrentFocusGroup());
  1741. EXPECT_EQ(4u, test_api.GetCurrentFocusIndex());
  1742. // Destroy a window and test that the destroyed window will not be included in
  1743. // the keyboard focus navigation.
  1744. window2.reset();
  1745. SendKey(ui::VKEY_TAB, event_generator);
  1746. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1747. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1748. EXPECT_TRUE(test_api.GetHighlightableWindow(window())->has_focus());
  1749. SendKey(ui::VKEY_TAB, event_generator);
  1750. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1751. EXPECT_EQ(1u, test_api.GetCurrentFocusIndex());
  1752. EXPECT_TRUE(camera_preview_view->has_focus());
  1753. SendKey(ui::VKEY_TAB, event_generator);
  1754. EXPECT_EQ(2u, test_api.GetCurrentFocusIndex());
  1755. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1756. EXPECT_TRUE(resize_button->has_focus());
  1757. // Continue tab after focusing on the resize button should advance the focus
  1758. // to settings close button.
  1759. SendKey(ui::VKEY_TAB, event_generator);
  1760. EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup());
  1761. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1762. }
  1763. TEST_F(CaptureModeCameraTest,
  1764. FocusableCameraPreviewInVideoRecordingWithFullscreenCapture) {
  1765. UpdateDisplay("800x700");
  1766. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  1767. AddDefaultCamera();
  1768. auto* camera_controller = GetCameraController();
  1769. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1770. auto* event_generator = GetEventGenerator();
  1771. auto* camera_preview_view = camera_controller->camera_preview_view();
  1772. auto* resize_button = GetPreviewResizeButton();
  1773. StartVideoRecordingImmediately();
  1774. EXPECT_TRUE(camera_preview_view->is_collapsible());
  1775. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  1776. // Press shortcut "Search+Alt+S" should focus the camera preview.
  1777. SendKey(ui::VKEY_S, event_generator, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN);
  1778. EXPECT_TRUE(camera_preview_view->has_focus());
  1779. EXPECT_FALSE(resize_button->has_focus());
  1780. EXPECT_FALSE(resize_button->GetVisible());
  1781. // Press tab should fade in the resize button and advance the focus on it.
  1782. SendKey(ui::VKEY_TAB, event_generator);
  1783. EXPECT_FALSE(camera_preview_view->has_focus());
  1784. EXPECT_TRUE(resize_button->has_focus());
  1785. EXPECT_TRUE(resize_button->GetVisible());
  1786. // Shift tab should advance the focus back to the camera preview view. But the
  1787. // resize button will be kept as visible as it will be fade out in a few
  1788. // seconds.
  1789. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1790. EXPECT_TRUE(camera_preview_view->has_focus());
  1791. EXPECT_FALSE(resize_button->has_focus());
  1792. EXPECT_TRUE(resize_button->GetVisible());
  1793. // Press tab again to focus on the resize button.
  1794. SendKey(ui::VKEY_TAB, event_generator);
  1795. EXPECT_FALSE(camera_preview_view->has_focus());
  1796. EXPECT_TRUE(resize_button->has_focus());
  1797. EXPECT_TRUE(resize_button->GetVisible());
  1798. // Press space key when the resize button is focused should be able to expand
  1799. // or collapse the camera preview.
  1800. SendKey(ui::VKEY_SPACE, event_generator);
  1801. EXPECT_TRUE(camera_controller->is_camera_preview_collapsed());
  1802. EXPECT_TRUE(resize_button->has_focus());
  1803. SendKey(ui::VKEY_SPACE, event_generator);
  1804. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  1805. EXPECT_TRUE(resize_button->has_focus());
  1806. // Press escape key should remove the focus from the camera preview, either
  1807. // the camera preview view or the resize button.
  1808. SendKey(ui::VKEY_ESCAPE, event_generator);
  1809. EXPECT_FALSE(camera_preview_view->has_focus());
  1810. EXPECT_FALSE(resize_button->has_focus());
  1811. // Press shortcut "Search+Alt+S" should not focus the camera preview when
  1812. // capture session is active even though video recording is in progress.
  1813. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  1814. CaptureModeType::kImage);
  1815. EXPECT_TRUE(controller->IsActive());
  1816. EXPECT_TRUE(controller->is_recording_in_progress());
  1817. SendKey(ui::VKEY_S, event_generator, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN);
  1818. EXPECT_FALSE(camera_preview_view->has_focus());
  1819. // Press tab should still able to focus the camera preview view and the resize
  1820. // button.
  1821. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/5);
  1822. EXPECT_TRUE(camera_preview_view->has_focus());
  1823. EXPECT_FALSE(resize_button->has_focus());
  1824. SendKey(ui::VKEY_TAB, event_generator);
  1825. EXPECT_FALSE(camera_preview_view->has_focus());
  1826. EXPECT_TRUE(resize_button->has_focus());
  1827. // Continue tab should be able to advance the focus on the settings button.
  1828. SendKey(ui::VKEY_TAB, event_generator);
  1829. EXPECT_FALSE(camera_preview_view->has_focus());
  1830. EXPECT_FALSE(resize_button->has_focus());
  1831. EXPECT_TRUE(CaptureModeSessionTestApi(controller->capture_mode_session())
  1832. .GetCaptureModeBarView()
  1833. ->settings_button()
  1834. ->has_focus());
  1835. }
  1836. TEST_F(CaptureModeCameraTest,
  1837. FocusableCameraPreviewInVideoRecordingWithRegionCapture) {
  1838. auto* controller = CaptureModeController::Get();
  1839. controller->SetUserCaptureRegion(gfx::Rect(10, 10, 400, 550),
  1840. /*by_user=*/true);
  1841. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  1842. AddDefaultCamera();
  1843. auto* camera_controller = GetCameraController();
  1844. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1845. auto* event_generator = GetEventGenerator();
  1846. auto* camera_preview_view = camera_controller->camera_preview_view();
  1847. auto* resize_button = GetPreviewResizeButton();
  1848. StartVideoRecordingImmediately();
  1849. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  1850. EXPECT_FALSE(camera_preview_view->is_collapsible());
  1851. // Press shortcut "Search+Alt+S" should focus the camera preview.
  1852. SendKey(ui::VKEY_S, event_generator, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN);
  1853. EXPECT_TRUE(camera_preview_view->has_focus());
  1854. EXPECT_FALSE(resize_button->has_focus());
  1855. EXPECT_FALSE(resize_button->GetVisible());
  1856. // Press tab nothing will happen. As the camera preview is not collapsible,
  1857. // which means the camera preview is the only focusable item. Focus will not
  1858. // be moved to the resize button and it will continue to be hidden.
  1859. SendKey(ui::VKEY_TAB, event_generator);
  1860. EXPECT_TRUE(camera_preview_view->has_focus());
  1861. EXPECT_FALSE(resize_button->has_focus());
  1862. EXPECT_FALSE(resize_button->GetVisible());
  1863. // Mouse pressing outside of the camera preview should remove the focus from
  1864. // the camera preview.
  1865. const gfx::Point origin = camera_preview_view->GetBoundsInScreen().origin();
  1866. const gfx::Vector2d delta(-50, -50);
  1867. event_generator->MoveMouseTo(origin + delta);
  1868. event_generator->ClickLeftButton();
  1869. EXPECT_FALSE(camera_preview_view->has_focus());
  1870. EXPECT_FALSE(resize_button->has_focus());
  1871. }
  1872. TEST_F(CaptureModeCameraTest,
  1873. FocusableCameraPreviewInVideoRecordingWithWindowCapture) {
  1874. UpdateDisplay("1366x768");
  1875. window()->SetBounds(gfx::Rect(30, 40, 800, 700));
  1876. auto* controller =
  1877. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  1878. AddDefaultCamera();
  1879. auto* camera_controller = GetCameraController();
  1880. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1881. auto* event_generator = GetEventGenerator();
  1882. auto* camera_preview_view = camera_controller->camera_preview_view();
  1883. auto* resize_button = GetPreviewResizeButton();
  1884. event_generator->MoveMouseTo(window()->GetBoundsInScreen().origin());
  1885. EXPECT_EQ(controller->capture_mode_session()->GetSelectedWindow(), window());
  1886. StartVideoRecordingImmediately();
  1887. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  1888. EXPECT_TRUE(camera_preview_view->is_collapsible());
  1889. // Press shortcut "Search+Alt+S" should focus the camera preview.
  1890. SendKey(ui::VKEY_S, event_generator, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN);
  1891. EXPECT_TRUE(camera_preview_view->has_focus());
  1892. EXPECT_FALSE(resize_button->has_focus());
  1893. // Press tab should fade in the resize button and advance the focus on it.
  1894. SendKey(ui::VKEY_TAB, event_generator);
  1895. EXPECT_FALSE(camera_preview_view->has_focus());
  1896. EXPECT_TRUE(resize_button->has_focus());
  1897. EXPECT_TRUE(resize_button->GetVisible());
  1898. // Shift tab should advance the focus back to the camera preview view. But the
  1899. // resize button will be kept as visible as it will be fade out in a few
  1900. // seconds.
  1901. SendKey(ui::VKEY_TAB, event_generator, ui::EF_SHIFT_DOWN);
  1902. EXPECT_TRUE(camera_preview_view->has_focus());
  1903. EXPECT_FALSE(resize_button->has_focus());
  1904. }
  1905. TEST_F(CaptureModeCameraTest, CaptureBarOpacityChangeOnKeyboardNavigation) {
  1906. using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup;
  1907. // Update display size and update window with customized size to make sure
  1908. // camera preview overlap with capture bar with capture source `kWindow`.
  1909. UpdateDisplay("1366x768");
  1910. window()->SetBounds({0, 0, 903, 700});
  1911. auto* controller =
  1912. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  1913. CaptureModeSessionTestApi test_api(controller->capture_mode_session());
  1914. auto* capture_session = controller->capture_mode_session();
  1915. auto* camera_controller = GetCameraController();
  1916. AddDefaultCamera();
  1917. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1918. const auto* camera_preview_widget =
  1919. camera_controller->camera_preview_widget();
  1920. const auto* capture_bar_widget = capture_session->capture_mode_bar_widget();
  1921. const ui::Layer* capture_bar_layer = capture_bar_widget->GetLayer();
  1922. // Move mouse on top of `window` to set the selected window. Verify capture
  1923. // bar is `kOverlapOpacity`.
  1924. auto* event_generator = GetEventGenerator();
  1925. event_generator->MoveMouseTo(window()->GetBoundsInScreen().CenterPoint());
  1926. EXPECT_EQ(capture_session->GetSelectedWindow(), window());
  1927. EXPECT_TRUE(capture_bar_widget->GetWindowBoundsInScreen().Intersects(
  1928. camera_preview_widget->GetWindowBoundsInScreen()));
  1929. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(),
  1930. capture_mode::kCaptureUiOverlapOpacity);
  1931. // Now tab through the capture bar, verify that as long as the focus is on
  1932. // capture bar or capture settings menu, capture bar is updated to full
  1933. // opaque.
  1934. SendKey(ui::VKEY_TAB, event_generator);
  1935. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1936. // Tab four times to focus the last source button (window mode button). Verify
  1937. // capture bar is still fully opaque.
  1938. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/4);
  1939. EXPECT_EQ(FocusGroup::kTypeSource, test_api.GetCurrentFocusGroup());
  1940. EXPECT_EQ(4u, test_api.GetCurrentFocusIndex());
  1941. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1942. // Tab once to focus on the window to be captured, verify that capture bar is
  1943. // `kOverlapOpacity` since the focus is removed from capture bar.
  1944. SendKey(ui::VKEY_TAB, event_generator);
  1945. EXPECT_EQ(FocusGroup::kCaptureWindow, test_api.GetCurrentFocusGroup());
  1946. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(),
  1947. capture_mode::kCaptureUiOverlapOpacity);
  1948. // Tab three times to focus on the settings button, verify capture bar is
  1949. // updated to fully opaque again.
  1950. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/3);
  1951. EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup());
  1952. EXPECT_EQ(0u, test_api.GetCurrentFocusIndex());
  1953. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1954. // Now enter space to open the settings menu. Verify capture bar is still full
  1955. // opaque.
  1956. SendKey(ui::VKEY_SPACE, event_generator);
  1957. EXPECT_EQ(FocusGroup::kPendingSettings, test_api.GetCurrentFocusGroup());
  1958. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1959. // Tab once to focus on the settings menu. Verify capture bar is still full
  1960. // opaque.
  1961. SendKey(ui::VKEY_TAB, event_generator);
  1962. EXPECT_EQ(FocusGroup::kSettingsMenu, test_api.GetCurrentFocusGroup());
  1963. EXPECT_EQ(capture_bar_layer->GetTargetOpacity(), 1.0f);
  1964. }
  1965. TEST_F(CaptureModeCameraTest, CaptureLabelOpacityChangeOnKeyboardNavigation) {
  1966. UpdateDisplay("800x600");
  1967. using FocusGroup = CaptureModeSessionFocusCycler::FocusGroup;
  1968. auto* controller =
  1969. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  1970. CaptureModeSessionTestApi test_api(controller->capture_mode_session());
  1971. auto* capture_session = controller->capture_mode_session();
  1972. auto* camera_controller = GetCameraController();
  1973. AddDefaultCamera();
  1974. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  1975. auto* camera_preview_widget = camera_controller->camera_preview_widget();
  1976. auto* capture_label_widget = capture_session->capture_label_widget();
  1977. ui::Layer* capture_label_layer = capture_label_widget->GetLayer();
  1978. // Select capture region to make sure capture label is overlapped with
  1979. // camera preview. Verify capture label is `kOverlapOpacity`.
  1980. const int min_region_length =
  1981. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera;
  1982. SelectCaptureRegion({100, 100, min_region_length, min_region_length});
  1983. EXPECT_TRUE(capture_label_widget->GetWindowBoundsInScreen().Intersects(
  1984. camera_preview_widget->GetWindowBoundsInScreen()));
  1985. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  1986. capture_mode::kCaptureUiOverlapOpacity);
  1987. auto* event_generator = GetEventGenerator();
  1988. // Tab four times to focus on the region capture source, verify capture label
  1989. // is still `kOverlapOpacity`.
  1990. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/4);
  1991. EXPECT_EQ(FocusGroup::kTypeSource, test_api.GetCurrentFocusGroup());
  1992. EXPECT_EQ(3u, test_api.GetCurrentFocusIndex());
  1993. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  1994. capture_mode::kCaptureUiOverlapOpacity);
  1995. // Tab twice to focus on `kSelection`, verify capture label is still
  1996. // `kOverlapOpacity`.
  1997. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/2);
  1998. EXPECT_EQ(FocusGroup::kSelection, test_api.GetCurrentFocusGroup());
  1999. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  2000. capture_mode::kCaptureUiOverlapOpacity);
  2001. // Tab eleven times to focus on cpature label, verify capture label is updated
  2002. // to fully opaque.
  2003. EXPECT_FALSE(camera_controller->camera_preview_view()->is_collapsible());
  2004. SendKey(ui::VKEY_TAB, event_generator, ui::EF_NONE, /*count=*/10);
  2005. EXPECT_EQ(FocusGroup::kCaptureButton, test_api.GetCurrentFocusGroup());
  2006. EXPECT_EQ(capture_label_layer->GetTargetOpacity(), 1.0f);
  2007. // Tab once to focus on the setting button on capture bar, verify capture
  2008. // lable's opacity is updated to `kOverlapOpacity`.
  2009. SendKey(ui::VKEY_TAB, event_generator);
  2010. EXPECT_EQ(FocusGroup::kSettingsClose, test_api.GetCurrentFocusGroup());
  2011. EXPECT_EQ(capture_label_layer->GetTargetOpacity(),
  2012. capture_mode::kCaptureUiOverlapOpacity);
  2013. }
  2014. // Tests that when switching capture source from `kRegion` to `kFullscreen`,
  2015. // camera preview should be shown.
  2016. // Regression test for https://crbug.com/1316911.
  2017. TEST_F(CaptureModeCameraTest, CameraPreviewVisibilityOnCaptureSourceChanged) {
  2018. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  2019. AddDefaultCamera();
  2020. CaptureModeTestApi().SelectCameraAtIndex(0);
  2021. auto* camera_preview_widget = GetCameraController()->camera_preview_widget();
  2022. auto* preview_window = camera_preview_widget->GetNativeWindow();
  2023. // Verify that camera preview is visible.
  2024. EXPECT_EQ(preview_window->parent(),
  2025. preview_window->GetRootWindow()->GetChildById(
  2026. kShellWindowId_MenuContainer));
  2027. EXPECT_TRUE(camera_preview_widget->IsVisible());
  2028. EXPECT_TRUE(preview_window->TargetVisibility());
  2029. // Click on the region source button, verify that camera preview is parented
  2030. // to UnparentedContainer and becomes invisible.
  2031. auto* event_generator = GetEventGenerator();
  2032. ClickOnView(GetRegionToggleButton(), event_generator);
  2033. EXPECT_EQ(preview_window->parent(),
  2034. preview_window->GetRootWindow()->GetChildById(
  2035. kShellWindowId_UnparentedContainer));
  2036. EXPECT_FALSE(camera_preview_widget->IsVisible());
  2037. // Now switch capture source to `kFullscreen`, verify that camera preview is
  2038. // parented to MenuContainer and becomes visible again.
  2039. ClickOnView(GetFullscreenToggleButton(), event_generator);
  2040. EXPECT_EQ(preview_window->parent(),
  2041. preview_window->GetRootWindow()->GetChildById(
  2042. kShellWindowId_MenuContainer));
  2043. EXPECT_TRUE(preview_window->TargetVisibility());
  2044. EXPECT_TRUE(camera_preview_widget->IsVisible());
  2045. }
  2046. // Tests that the recording starts with camera metrics are recorded correctly
  2047. // both in clamshell and tablet mode.
  2048. TEST_F(CaptureModeCameraTest, RecordingStartsWithCameraHistogramTest) {
  2049. base::HistogramTester histogram_tester;
  2050. constexpr char kHistogramNameBase[] =
  2051. "Ash.CaptureModeController.RecordingStartsWithCamera";
  2052. AddDefaultCamera();
  2053. struct {
  2054. bool tablet_enabled;
  2055. bool camera_on;
  2056. } kTestCases[] = {
  2057. {false, false},
  2058. {false, true},
  2059. {true, false},
  2060. {true, true},
  2061. };
  2062. for (const auto test_case : kTestCases) {
  2063. if (test_case.tablet_enabled) {
  2064. SwitchToTabletMode();
  2065. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  2066. } else {
  2067. EXPECT_FALSE(Shell::Get()->IsInTabletMode());
  2068. }
  2069. histogram_tester.ExpectBucketCount(
  2070. GetCaptureModeHistogramName(kHistogramNameBase), test_case.camera_on,
  2071. 0);
  2072. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  2073. CaptureModeType::kVideo);
  2074. auto* camera_controller = GetCameraController();
  2075. camera_controller->SetSelectedCamera(
  2076. test_case.camera_on ? CameraId(kDefaultCameraModelId, 1) : CameraId());
  2077. StartVideoRecordingImmediately();
  2078. EXPECT_TRUE(controller->is_recording_in_progress());
  2079. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  2080. WaitForCaptureFileToBeSaved();
  2081. histogram_tester.ExpectBucketCount(
  2082. GetCaptureModeHistogramName(kHistogramNameBase), test_case.camera_on,
  2083. 1);
  2084. }
  2085. }
  2086. // Tests that the number of camera disconnections happens during recording is
  2087. // recorded correctly both in clamshell and tablet mode.
  2088. TEST_F(CaptureModeCameraTest,
  2089. RecordCameraDisconnectionsDuringRecordingsHistogramTest) {
  2090. constexpr char kHistogramNameBase[] =
  2091. "Ash.CaptureModeController.CameraDisconnectionsDuringRecordings";
  2092. base::HistogramTester histogram_tester;
  2093. auto* camera_controller = GetCameraController();
  2094. auto disconnect_and_reconnect_camera_n_times = [&](int n) {
  2095. for (int i = 0; i < n; i++) {
  2096. AddAndRemoveCameraAndTriggerGracePeriod();
  2097. camera_controller->camera_reconnect_timer_for_test()->FireNow();
  2098. }
  2099. };
  2100. for (const bool tablet_enabled : {false, true}) {
  2101. if (tablet_enabled) {
  2102. SwitchToTabletMode();
  2103. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  2104. } else {
  2105. EXPECT_FALSE(Shell::Get()->IsInTabletMode());
  2106. }
  2107. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  2108. CaptureModeType::kVideo);
  2109. controller->StartVideoRecordingImmediatelyForTesting();
  2110. // Disconnect the camera, exhaust the timer and reconnect three times. The
  2111. // metric should record accordingly.
  2112. disconnect_and_reconnect_camera_n_times(3);
  2113. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  2114. WaitForCaptureFileToBeSaved();
  2115. histogram_tester.ExpectBucketCount(
  2116. GetCaptureModeHistogramName(kHistogramNameBase), 3, 1);
  2117. }
  2118. }
  2119. // Tests that the number of connected cameras to the device is recorded whenever
  2120. // the number changes.
  2121. TEST_F(CaptureModeCameraTest, RecordNumberOfConnectedCamerasHistogramTest) {
  2122. constexpr char kHistogramNameBase[] =
  2123. "Ash.CaptureModeController.NumberOfConnectedCameras";
  2124. base::HistogramTester histogram_tester;
  2125. // Make sure the device change alert triggered by the SystemMonitor is handled
  2126. // before we connect a camera device.
  2127. {
  2128. base::RunLoop loop;
  2129. GetCameraController()->SetOnCameraListReceivedForTesting(
  2130. loop.QuitClosure());
  2131. base::SystemMonitor::Get()->ProcessDevicesChanged(
  2132. base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
  2133. loop.Run();
  2134. }
  2135. // Verify that before we connect any camera device, there's 0 cameras and it
  2136. // has been recorded.
  2137. histogram_tester.ExpectBucketCount(kHistogramNameBase, 0, 1);
  2138. // Connect one camera, verify that the number of one camera device has been
  2139. // recorded once.
  2140. AddFakeCamera("/dev/video", "fake cam ", "model 1");
  2141. histogram_tester.ExpectBucketCount(kHistogramNameBase, 1, 1);
  2142. // Connect the second camera, verify that the number of two camera devices has
  2143. // been recorded once.
  2144. AddFakeCamera("/dev/video1", "fake cam 2", "model 2");
  2145. histogram_tester.ExpectBucketCount(kHistogramNameBase, 2, 1);
  2146. // Disconnect the second camera, now the number of connected cameres drops
  2147. // back to one, verify that the number of one camera device has been recorded
  2148. // twice.
  2149. RemoveFakeCamera("/dev/video1");
  2150. histogram_tester.ExpectBucketCount(kHistogramNameBase, 1, 2);
  2151. // Connect the third camera, now the number of connected cameras is two again,
  2152. // verify that the number of two camera devices has been recorded twice.
  2153. AddFakeCamera("/dev/video2", "fake cam 3", "model 3");
  2154. histogram_tester.ExpectBucketCount(kHistogramNameBase, 2, 2);
  2155. }
  2156. // Tests that the duration for disconnected camera to become available again is
  2157. // recorded correctly both in clamshell and tablet mode.
  2158. TEST_F(CaptureModeCameraTest, RecordCameraReconnectDurationHistogramTest) {
  2159. constexpr char kHistogramNameBase[] =
  2160. "Ash.CaptureModeController.CameraReconnectDuration";
  2161. base::HistogramTester histogram_tester;
  2162. for (const bool tablet_enabled : {false, true}) {
  2163. if (tablet_enabled) {
  2164. SwitchToTabletMode();
  2165. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  2166. } else {
  2167. EXPECT_FALSE(Shell::Get()->IsInTabletMode());
  2168. }
  2169. AddAndRemoveCameraAndTriggerGracePeriod();
  2170. WaitForSeconds(1);
  2171. AddDefaultCamera();
  2172. histogram_tester.ExpectBucketCount(
  2173. GetCaptureModeHistogramName(kHistogramNameBase), 1, 1);
  2174. RemoveDefaultCamera();
  2175. }
  2176. }
  2177. // Tests that the camera size on start is recorded correctly in the metrics both
  2178. // in clamshell and tablet mode.
  2179. TEST_F(CaptureModeCameraTest, RecordingCameraSizeOnStartHistogramTest) {
  2180. UpdateDisplay("1366x768");
  2181. constexpr char kHistogramNameBase[] =
  2182. "Ash.CaptureModeController.RecordingCameraSizeOnStart";
  2183. base::HistogramTester histogram_tester;
  2184. auto* camera_controller = GetCameraController();
  2185. AddDefaultCamera();
  2186. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2187. for (const bool tablet_enabled : {false, true}) {
  2188. if (tablet_enabled) {
  2189. SwitchToTabletMode();
  2190. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  2191. } else {
  2192. EXPECT_FALSE(Shell::Get()->IsInTabletMode());
  2193. }
  2194. for (const bool collapsed : {false, true}) {
  2195. const auto sample = collapsed ? CaptureModeCameraSize::kCollapsed
  2196. : CaptureModeCameraSize::kExpanded;
  2197. histogram_tester.ExpectBucketCount(
  2198. GetCaptureModeHistogramName(kHistogramNameBase), sample, 0);
  2199. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  2200. CaptureModeType::kVideo);
  2201. auto* event_generator = GetEventGenerator();
  2202. // Resize button is hidden by default, click/tap on the preview to make
  2203. // it visible.
  2204. ClickOrTapView(camera_controller->camera_preview_view(), tablet_enabled,
  2205. event_generator);
  2206. auto* resize_button = GetPreviewResizeButton();
  2207. DCHECK(resize_button);
  2208. if (collapsed) {
  2209. if (!camera_controller->is_camera_preview_collapsed())
  2210. ClickOrTapView(resize_button, tablet_enabled, event_generator);
  2211. EXPECT_TRUE(camera_controller->is_camera_preview_collapsed());
  2212. } else {
  2213. if (camera_controller->is_camera_preview_collapsed())
  2214. ClickOrTapView(resize_button, tablet_enabled, event_generator);
  2215. EXPECT_FALSE(camera_controller->is_camera_preview_collapsed());
  2216. }
  2217. StartVideoRecordingImmediately();
  2218. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  2219. WaitForCaptureFileToBeSaved();
  2220. histogram_tester.ExpectBucketCount(
  2221. GetCaptureModeHistogramName(kHistogramNameBase), sample, 1);
  2222. }
  2223. }
  2224. }
  2225. // Tests that the camera position on start is recorded correctly in the metrics
  2226. // both in clamshell and tablet mode.
  2227. TEST_F(CaptureModeCameraTest, RecordingCameraPositionOnStartHistogramTest) {
  2228. constexpr char kHistogramName[] =
  2229. "Ash.CaptureModeController.RecordingCameraPositionOnStart";
  2230. base::HistogramTester histogram_tester;
  2231. StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
  2232. AddDefaultCamera();
  2233. auto* camera_controller = GetCameraController();
  2234. const CameraId camera_id(kDefaultCameraModelId, 1);
  2235. camera_controller->SetSelectedCamera(camera_id);
  2236. const CameraPreviewSnapPosition kCameraPositionTestCases[]{
  2237. CameraPreviewSnapPosition::kTopLeft,
  2238. CameraPreviewSnapPosition::kBottomLeft,
  2239. CameraPreviewSnapPosition::kTopRight,
  2240. CameraPreviewSnapPosition::kBottomRight};
  2241. for (const bool tablet_enabled : {false, true}) {
  2242. if (tablet_enabled) {
  2243. SwitchToTabletMode();
  2244. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  2245. } else {
  2246. EXPECT_FALSE(Shell::Get()->IsInTabletMode());
  2247. }
  2248. for (const auto camera_position : kCameraPositionTestCases) {
  2249. histogram_tester.ExpectBucketCount(
  2250. GetCaptureModeHistogramName(kHistogramName), camera_position, 0);
  2251. auto* controller = StartCaptureSession(CaptureModeSource::kFullscreen,
  2252. CaptureModeType::kVideo);
  2253. DCHECK(camera_controller->camera_preview_widget());
  2254. camera_controller->SetCameraPreviewSnapPosition(camera_position);
  2255. StartVideoRecordingImmediately();
  2256. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  2257. WaitForCaptureFileToBeSaved();
  2258. histogram_tester.ExpectBucketCount(
  2259. GetCaptureModeHistogramName(kHistogramName), camera_position, 1);
  2260. }
  2261. }
  2262. }
  2263. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnCaptureRegionUpdated) {
  2264. UpdateDisplay("800x600");
  2265. auto* controller =
  2266. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2267. auto* capture_session = controller->capture_mode_session();
  2268. auto* camera_controller = GetCameraController();
  2269. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2270. AddDefaultCamera();
  2271. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2272. // Set capture region big enough to fit the camera preview. Verify the
  2273. // current capture toast is `kUserNudge`.
  2274. const gfx::Rect capture_region(100, 100, 300, 300);
  2275. SelectCaptureRegion(capture_region);
  2276. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2277. EXPECT_TRUE(capture_toast_widget);
  2278. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2279. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2280. CaptureToastType::kUserNudge);
  2281. // Update capture region small enough to not fit the camera preview. Verify
  2282. // that the capture toast is updated to `kCameraPreview` and the user nudge is
  2283. // dismissed forever.
  2284. const int delta_x =
  2285. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera - 30 -
  2286. capture_region.width();
  2287. const int delta_y =
  2288. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera - 30 -
  2289. capture_region.height();
  2290. const gfx::Vector2d delta(delta_x, delta_y);
  2291. auto* event_generator = GetEventGenerator();
  2292. event_generator->set_current_screen_location(capture_region.bottom_right());
  2293. event_generator->PressLeftButton();
  2294. // Verify that when drag starts, the capture toast is hidden.
  2295. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2296. event_generator->MoveMouseTo(capture_region.bottom_right() + delta);
  2297. event_generator->ReleaseLeftButton();
  2298. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2299. CaptureToastType::kCameraPreview);
  2300. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2301. EXPECT_FALSE(GetUserNudgeController());
  2302. // Start dragging the capture region again to update it, but make it still
  2303. // small enough to not fit the camera preview. Verify at the beginning of the
  2304. // drag, preview toast is hidden. After the drag is released, preview toast is
  2305. // shown again.
  2306. const gfx::Vector2d delta1(delta_x + 10, delta_y + 10);
  2307. event_generator->set_current_screen_location(capture_region.bottom_right());
  2308. event_generator->PressLeftButton();
  2309. // Verify that when drag starts, the capture toast is hidden.
  2310. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2311. event_generator->MoveMouseTo(capture_region.bottom_right() + delta1);
  2312. event_generator->ReleaseLeftButton();
  2313. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2314. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2315. CaptureToastType::kCameraPreview);
  2316. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2317. // Update capture region big enough to show the camera preview. Verify the
  2318. // preview toast is hidden.
  2319. event_generator->set_current_screen_location(capture_region.origin());
  2320. event_generator->PressLeftButton();
  2321. // Verify that when drag starts, the capture toast is hidden.
  2322. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2323. event_generator->MoveMouseTo(capture_region.bottom_right());
  2324. event_generator->ReleaseLeftButton();
  2325. // Verify that since the capture toast is dismissed, current toast type is
  2326. // reset.
  2327. EXPECT_FALSE(capture_toast_controller->current_toast_type());
  2328. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2329. }
  2330. // Tests that the capture toast will be faded out on time out when there are no
  2331. // actions taken.
  2332. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnTimeOut) {
  2333. UpdateDisplay("800x600");
  2334. auto* controller =
  2335. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2336. auto* capture_session = controller->capture_mode_session();
  2337. auto* camera_controller = GetCameraController();
  2338. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2339. AddDefaultCamera();
  2340. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2341. // Set capture region small enough to not fit the camera preview. Verify the
  2342. // current capture toast is `kCameraPreview`.
  2343. const gfx::Rect capture_region = GetTooSmallToFitCameraRegion();
  2344. SelectCaptureRegion(capture_region);
  2345. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2346. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2347. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2348. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2349. CaptureToastType::kCameraPreview);
  2350. // Verify the timer is running after the toast is shown and when the timer is
  2351. // fired, the capture toast is hidden.
  2352. base::OneShotTimer* timer =
  2353. capture_toast_controller->capture_toast_dismiss_timer_for_test();
  2354. EXPECT_TRUE(timer->IsRunning());
  2355. timer->FireNow();
  2356. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2357. }
  2358. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnSettingsMenuOpen) {
  2359. UpdateDisplay("800x600");
  2360. auto* controller =
  2361. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2362. auto* capture_session = controller->capture_mode_session();
  2363. auto* camera_controller = GetCameraController();
  2364. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2365. AddDefaultCamera();
  2366. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2367. // Set capture region small enough to not fit the camera preview. Verify the
  2368. // current capture toast is `kCameraPreview`.
  2369. const gfx::Rect capture_region = GetTooSmallToFitCameraRegion();
  2370. SelectCaptureRegion(capture_region);
  2371. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2372. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2373. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2374. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2375. CaptureToastType::kCameraPreview);
  2376. // Now open settings menu, verify that preview toast is dismissed immediately
  2377. // on settings menu open.
  2378. OpenSettingsView();
  2379. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2380. }
  2381. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnCaptureRegionMoved) {
  2382. UpdateDisplay("800x600");
  2383. auto* controller =
  2384. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2385. auto* capture_session = controller->capture_mode_session();
  2386. auto* camera_controller = GetCameraController();
  2387. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2388. AddDefaultCamera();
  2389. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2390. // Set capture region small enough to not fit the camera preview. Verify the
  2391. // current capture toast is `kCameraPreview`.
  2392. const gfx::Rect capture_region = GetTooSmallToFitCameraRegion();
  2393. SelectCaptureRegion(capture_region);
  2394. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2395. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2396. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2397. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2398. CaptureToastType::kCameraPreview);
  2399. // Start moving the capture region, verify the preview toast is hidden at the
  2400. // beginning of the move and is shown once the move is done.
  2401. const gfx::Vector2d delta(20, 20);
  2402. auto* event_generator = GetEventGenerator();
  2403. event_generator->MoveMouseTo(capture_region.origin() + delta);
  2404. event_generator->PressLeftButton();
  2405. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2406. event_generator->MoveMouseTo(capture_region.CenterPoint());
  2407. event_generator->ReleaseLeftButton();
  2408. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2409. }
  2410. // Tests that the preview toast shows correctly when capture mode is turned on
  2411. // through quick settings which keeps the configurations) from the previous
  2412. // session.
  2413. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnCaptureModeTurnedOn) {
  2414. UpdateDisplay("800x600");
  2415. auto* controller =
  2416. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2417. auto* capture_session = controller->capture_mode_session();
  2418. auto* camera_controller = GetCameraController();
  2419. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2420. AddDefaultCamera();
  2421. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2422. // Set capture region small enough to not fit the camera preview. Verify the
  2423. // current capture toast is `kCameraPreview`.
  2424. const gfx::Rect capture_region = GetTooSmallToFitCameraRegion();
  2425. SelectCaptureRegion(capture_region);
  2426. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2427. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2428. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2429. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2430. CaptureToastType::kCameraPreview);
  2431. // Close capture mode.
  2432. controller->Stop();
  2433. // Turn on capture mode again through the quick settings, verify that toast
  2434. // preview is visible.
  2435. controller->Start(CaptureModeEntryType::kQuickSettings);
  2436. capture_session = controller->capture_mode_session();
  2437. capture_toast_controller = capture_session->capture_toast_controller();
  2438. EXPECT_TRUE(capture_toast_controller->capture_toast_widget()->IsVisible());
  2439. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2440. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2441. CaptureToastType::kCameraPreview);
  2442. }
  2443. TEST_F(CaptureModeCameraTest, ToastStackingOrderChangeOnCaptureModeTurnedOn) {
  2444. auto* controller =
  2445. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2446. auto* camera_controller = GetCameraController();
  2447. AddDefaultCamera();
  2448. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2449. // Set capture region small enough to make capture toast shown.
  2450. const gfx::Rect capture_region = GetTooSmallToFitCameraRegion();
  2451. SelectCaptureRegion(capture_region);
  2452. // Close capture mode.
  2453. controller->Stop();
  2454. // Turn on capture mode again through the quick settings, verify that the
  2455. // stacking order for capture toast relative to other capture UIs is correct.
  2456. controller->Start(CaptureModeEntryType::kQuickSettings);
  2457. auto* capture_session = controller->capture_mode_session();
  2458. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2459. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2460. auto* capture_toast_window = capture_toast_widget->GetNativeWindow();
  2461. auto* capture_label_window =
  2462. capture_session->capture_label_widget()->GetNativeWindow();
  2463. auto* capture_bar_window =
  2464. capture_session->capture_mode_bar_widget()->GetNativeWindow();
  2465. auto* camera_preview_window =
  2466. camera_controller->camera_preview_widget()->GetNativeWindow();
  2467. EXPECT_TRUE(
  2468. IsWindowStackedRightBelow(capture_label_window, capture_bar_window));
  2469. EXPECT_TRUE(
  2470. IsWindowStackedRightBelow(capture_toast_window, capture_label_window));
  2471. EXPECT_TRUE(
  2472. IsWindowStackedRightBelow(camera_preview_window, capture_toast_window));
  2473. EXPECT_TRUE(IsLayerStackedRightBelow(capture_session->layer(),
  2474. camera_preview_window->layer()));
  2475. }
  2476. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnPerformingCapture) {
  2477. UpdateDisplay("800x600");
  2478. auto* controller =
  2479. StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kVideo);
  2480. auto* capture_session = controller->capture_mode_session();
  2481. auto* camera_controller = GetCameraController();
  2482. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2483. AddDefaultCamera();
  2484. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2485. // Set capture region small enough to not fit the camera preview. Verify the
  2486. // current capture toast is `kCameraPreview`.
  2487. const gfx::Rect capture_region = GetTooSmallToFitCameraRegion();
  2488. SelectCaptureRegion(capture_region);
  2489. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2490. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2491. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2492. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2493. CaptureToastType::kCameraPreview);
  2494. // Perform the screen recording, verify that the capture toast is going to be
  2495. // faded out.
  2496. controller->PerformCapture();
  2497. EXPECT_EQ(capture_toast_widget->GetLayer()->GetTargetOpacity(), 0.f);
  2498. }
  2499. TEST_F(CaptureModeCameraTest, ToastVisibilityChangeOnMultiDisplays) {
  2500. UpdateDisplay("800x700,801+0-800x700");
  2501. const gfx::Rect first_display_bounds(0, 0, 800, 700);
  2502. const gfx::Rect second_display_bounds(801, 0, 800, 700);
  2503. // Set the window's bounds small enough to not fit the camera preview.
  2504. window()->SetBoundsInScreen(
  2505. gfx::Rect(600, 500, 100, 100),
  2506. display::Screen::GetScreen()->GetDisplayNearestWindow(
  2507. Shell::GetAllRootWindows()[0]));
  2508. // Create a window in the second display and set its bounds small enough to
  2509. // not fit the camera preview.
  2510. std::unique_ptr<aura::Window> window1(CreateTestWindow());
  2511. window1->SetBoundsInScreen(
  2512. gfx::Rect(1400, 500, 100, 100),
  2513. display::Screen::GetScreen()->GetDisplayNearestWindow(
  2514. Shell::GetAllRootWindows()[1]));
  2515. // Start the capture session.
  2516. auto* controller =
  2517. StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
  2518. auto* camera_controller = GetCameraController();
  2519. auto* capture_session = controller->capture_mode_session();
  2520. auto* capture_toast_controller = capture_session->capture_toast_controller();
  2521. AddDefaultCamera();
  2522. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2523. // Move the mouse on top of `window` to select it, since it's too small to fit
  2524. // the camera preview, verify the preview toast shows and it's on the first
  2525. // display.
  2526. auto* event_generator = GetEventGenerator();
  2527. event_generator->MoveMouseTo(window()->GetBoundsInScreen().CenterPoint());
  2528. EXPECT_EQ(capture_session->GetSelectedWindow(), window());
  2529. auto* capture_toast_widget = capture_toast_controller->capture_toast_widget();
  2530. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2531. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2532. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2533. CaptureToastType::kCameraPreview);
  2534. first_display_bounds.Contains(
  2535. capture_toast_widget->GetWindowBoundsInScreen());
  2536. // Now move the mouse to the top of `window1`, since it's also too small to
  2537. // fit the camera preview, verify the preview toast still shows. Since
  2538. // `window1` is on the second display, verify the preview toast also shows up
  2539. // on the second display.
  2540. event_generator->MoveMouseTo(window1->GetBoundsInScreen().CenterPoint());
  2541. EXPECT_EQ(capture_session->GetSelectedWindow(), window1.get());
  2542. EXPECT_TRUE(capture_toast_widget->IsVisible());
  2543. ASSERT_TRUE(capture_toast_controller->current_toast_type());
  2544. EXPECT_EQ(*(capture_toast_controller->current_toast_type()),
  2545. CaptureToastType::kCameraPreview);
  2546. second_display_bounds.Contains(
  2547. capture_toast_widget->GetWindowBoundsInScreen());
  2548. // Move mouse to the outside of `window1`, verify that preview toast is
  2549. // dismissed since there's no window selected for now.
  2550. event_generator->MoveMouseTo({1300, 500});
  2551. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2552. // Update the bounds of `window` big enough to fit the camera preview.
  2553. window()->SetBoundsInScreen(
  2554. gfx::Rect(100, 200, 300, 300),
  2555. display::Screen::GetScreen()->GetDisplayNearestWindow(
  2556. Shell::GetAllRootWindows()[0]));
  2557. // Now move the mouse to the top of `window` again, verify that preview toast
  2558. // is not shown, since the window is big enough to show the camera preview.
  2559. event_generator->MoveMouseTo(window()->GetBoundsInScreen().CenterPoint());
  2560. EXPECT_EQ(capture_session->GetSelectedWindow(), window());
  2561. EXPECT_FALSE(capture_toast_widget->IsVisible());
  2562. }
  2563. class CaptureModeCameraPreviewTest
  2564. : public CaptureModeCameraTest,
  2565. public testing::WithParamInterface<CaptureModeSource> {
  2566. public:
  2567. enum class CameraPreviewState {
  2568. // The camera preview is shown inside an area that makes its expanded size
  2569. // big enough so it can collapse to a smaller size.
  2570. kCollapsible,
  2571. // The camera preview is shown inside an area that is small enough to
  2572. // disable its collapsability without causing it to hide.
  2573. kNotCollapsible,
  2574. // The camera preview is shown inside an area that is too small for it to
  2575. // show at all.
  2576. kHidden,
  2577. };
  2578. CaptureModeCameraPreviewTest() = default;
  2579. CaptureModeCameraPreviewTest(const CaptureModeCameraPreviewTest&) = delete;
  2580. CaptureModeCameraPreviewTest& operator=(const CaptureModeCameraPreviewTest&) =
  2581. delete;
  2582. ~CaptureModeCameraPreviewTest() override = default;
  2583. void StartCaptureSessionWithParam() {
  2584. auto* controller = CaptureModeController::Get();
  2585. const gfx::Rect capture_region(10, 20, 1300, 750);
  2586. controller->SetUserCaptureRegion(capture_region, /*by_user=*/true);
  2587. // Set the window's bounds big enough here to make sure after display
  2588. // rotation, the event is located on top of `window_`.
  2589. // TODO(conniekxu): investigate why the position of the event received is
  2590. // different than the position we pass.
  2591. window()->SetBounds({30, 40, 1300, 750});
  2592. StartCaptureSession(GetParam(), CaptureModeType::kVideo);
  2593. if (GetParam() == CaptureModeSource::kWindow)
  2594. GetEventGenerator()->MoveMouseToCenterOf(window());
  2595. }
  2596. gfx::Size GetMinSurfaceSizeForCollapsibleCamera() const {
  2597. const int min_length = capture_mode::kMinCollapsibleCameraPreviewDiameter *
  2598. capture_mode::kCaptureSurfaceShortSideDivider;
  2599. return gfx::Size(min_length, min_length);
  2600. }
  2601. gfx::Size GetMinSurfaceSizeSoCameraBecomes(
  2602. CameraPreviewState preview_state) const {
  2603. gfx::Size min_size = GetMinSurfaceSizeForCollapsibleCamera();
  2604. switch (preview_state) {
  2605. case CameraPreviewState::kCollapsible:
  2606. min_size.Enlarge(10, 20);
  2607. break;
  2608. case CameraPreviewState::kNotCollapsible:
  2609. min_size.Enlarge(-10, -20);
  2610. break;
  2611. case CameraPreviewState::kHidden:
  2612. const int length_for_hidden =
  2613. capture_mode::kMinCaptureSurfaceShortSideLengthForVisibleCamera - 5;
  2614. min_size.SetSize(length_for_hidden, length_for_hidden - 5);
  2615. break;
  2616. }
  2617. return min_size;
  2618. }
  2619. void ResizeDisplaySoCameraPreviewBecomes(CameraPreviewState preview_state) {
  2620. gfx::Size min_size = GetMinSurfaceSizeSoCameraBecomes(preview_state);
  2621. const int shelf_size = ShelfConfig::Get()->shelf_size();
  2622. min_size.Enlarge(shelf_size, shelf_size);
  2623. UpdateDisplay(min_size.ToString());
  2624. }
  2625. void ResizeRegionSoCameraPreviewBecomes(CameraPreviewState preview_state) {
  2626. CaptureModeController::Get()->SetUserCaptureRegion(
  2627. gfx::Rect(GetMinSurfaceSizeSoCameraBecomes(preview_state)),
  2628. /*by_user=*/true);
  2629. }
  2630. void ResizeWindowSoCameraPreviewBecomes(CameraPreviewState preview_state) {
  2631. window()->SetBounds(
  2632. gfx::Rect(GetMinSurfaceSizeSoCameraBecomes(preview_state)));
  2633. }
  2634. void ResizeSurfaceSoCameraPreviewBecomes(CameraPreviewState preview_state) {
  2635. switch (GetParam()) {
  2636. case CaptureModeSource::kFullscreen:
  2637. ResizeDisplaySoCameraPreviewBecomes(preview_state);
  2638. break;
  2639. case CaptureModeSource::kRegion:
  2640. ResizeRegionSoCameraPreviewBecomes(preview_state);
  2641. break;
  2642. case CaptureModeSource::kWindow:
  2643. ResizeWindowSoCameraPreviewBecomes(preview_state);
  2644. break;
  2645. }
  2646. }
  2647. // Based on the `CaptureModeSource`, it returns the current capture region's
  2648. // bounds in screen.
  2649. gfx::Rect GetCaptureBoundsInScreen() const {
  2650. auto* controller = CaptureModeController::Get();
  2651. auto* root = GetCurrentRoot();
  2652. switch (GetParam()) {
  2653. case CaptureModeSource::kFullscreen:
  2654. return display::Screen::GetScreen()
  2655. ->GetDisplayNearestWindow(root)
  2656. .work_area();
  2657. case CaptureModeSource::kRegion: {
  2658. auto* recording_watcher =
  2659. controller->video_recording_watcher_for_testing();
  2660. gfx::Rect capture_region =
  2661. controller->is_recording_in_progress()
  2662. ? recording_watcher->GetEffectivePartialRegionBounds()
  2663. : controller->user_capture_region();
  2664. wm::ConvertRectToScreen(root, &capture_region);
  2665. return capture_region;
  2666. }
  2667. case CaptureModeSource::kWindow:
  2668. return window()->GetBoundsInScreen();
  2669. }
  2670. }
  2671. gfx::Size GetExpectedPreviewSize(bool collapsed) const {
  2672. return capture_mode_util::CalculateCameraPreviewSizeSpecs(
  2673. GetCaptureBoundsInScreen().size(), collapsed)
  2674. .size;
  2675. }
  2676. // Returns the cursor type when cursor is on top of the current capture
  2677. // surface.
  2678. ui::mojom::CursorType GetCursorTypeOnCaptureSurface() const {
  2679. DCHECK(CaptureModeController::Get()->IsActive());
  2680. switch (GetParam()) {
  2681. case CaptureModeSource::kFullscreen:
  2682. case CaptureModeSource::kWindow:
  2683. return ui::mojom::CursorType::kCustom;
  2684. case CaptureModeSource::kRegion:
  2685. return ui::mojom::CursorType::kMove;
  2686. }
  2687. }
  2688. };
  2689. TEST_P(CaptureModeCameraPreviewTest, PreviewVisibilityWhileFolderSelection) {
  2690. AddDefaultCamera();
  2691. StartCaptureSessionWithParam();
  2692. CaptureModeTestApi().SelectCameraAtIndex(0);
  2693. // The camera preview should be initially visible.
  2694. auto* controller = CaptureModeController::Get();
  2695. ASSERT_TRUE(controller->IsActive());
  2696. auto* preview_widget = GetCameraController()->camera_preview_widget();
  2697. ASSERT_TRUE(preview_widget);
  2698. EXPECT_TRUE(preview_widget->IsVisible());
  2699. // Click on the settings button, the settings menu should open, and the camera
  2700. // preview should remain visible.
  2701. CaptureModeSessionTestApi session_test_api(
  2702. controller->capture_mode_session());
  2703. auto* settings_button =
  2704. session_test_api.GetCaptureModeBarView()->settings_button();
  2705. auto* event_generator = GetEventGenerator();
  2706. ClickOnView(settings_button, event_generator);
  2707. ASSERT_TRUE(session_test_api.GetCaptureModeSettingsWidget());
  2708. EXPECT_TRUE(preview_widget->IsVisible());
  2709. // Click on the "Select folder ..." option, the folder selection dialog should
  2710. // open, all capture UIs should hide, including the camera preview.
  2711. CaptureModeSettingsTestApi settings_test_api;
  2712. ClickOnView(settings_test_api.GetSelectFolderMenuItem(), event_generator);
  2713. EXPECT_TRUE(session_test_api.IsFolderSelectionDialogShown());
  2714. EXPECT_FALSE(session_test_api.IsAllUisVisible());
  2715. EXPECT_FALSE(preview_widget->IsVisible());
  2716. // Dismiss the folder selection dialog, all capture UIs should show again,
  2717. // including the camera preview.
  2718. FakeFolderSelectionDialogFactory::Get()->CancelDialog();
  2719. EXPECT_FALSE(session_test_api.IsFolderSelectionDialogShown());
  2720. EXPECT_TRUE(session_test_api.IsAllUisVisible());
  2721. EXPECT_TRUE(preview_widget->IsVisible());
  2722. }
  2723. // Tests that camera preview's bounds is updated after display rotations with
  2724. // two use cases, when capture session is active and when there's a video
  2725. // recording in progress.
  2726. TEST_P(CaptureModeCameraPreviewTest, DisplayRotation) {
  2727. StartCaptureSessionWithParam();
  2728. auto* camera_controller = GetCameraController();
  2729. AddDefaultCamera();
  2730. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2731. // Verify that the camera preview should be at the bottom right corner of
  2732. // capture bounds.
  2733. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2734. // Rotate the primary display by 90 degrees. Verify that the camera preview
  2735. // is still at the bottom right corner of capture bounds.
  2736. Shell::Get()->display_manager()->SetDisplayRotation(
  2737. WindowTreeHostManager::GetPrimaryDisplayId(), display::Display::ROTATE_90,
  2738. display::Display::RotationSource::USER);
  2739. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2740. // Start video recording, verify camera preview's bounds is updated after
  2741. // display rotations when there's a video recording in progress.
  2742. StartVideoRecordingImmediately();
  2743. EXPECT_FALSE(CaptureModeController::Get()->IsActive());
  2744. // Rotate the primary display by 180 degrees. Verify that the camera preview
  2745. // is still at the bottom right corner of capture bounds.
  2746. Shell::Get()->display_manager()->SetDisplayRotation(
  2747. WindowTreeHostManager::GetPrimaryDisplayId(),
  2748. display::Display::ROTATE_180, display::Display::RotationSource::USER);
  2749. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2750. // Rotate the primary display by 270 degrees. Verify that the camera preview
  2751. // is still at the bottom right corner of capture bounds.
  2752. Shell::Get()->display_manager()->SetDisplayRotation(
  2753. WindowTreeHostManager::GetPrimaryDisplayId(),
  2754. display::Display::ROTATE_270, display::Display::RotationSource::USER);
  2755. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2756. }
  2757. // Tests that when camera preview is being dragged, at the end of the drag, it
  2758. // should be snapped to the correct snap position. It tests two use cases,
  2759. // when capture session is active and when there's a video recording in
  2760. // progress including drag to snap by mouse and by touch.
  2761. TEST_P(CaptureModeCameraPreviewTest, CameraPreviewDragToSnap) {
  2762. UpdateDisplay("1600x800");
  2763. StartCaptureSessionWithParam();
  2764. auto* camera_controller = GetCameraController();
  2765. AddDefaultCamera();
  2766. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2767. auto* preview_widget = camera_controller->camera_preview_widget();
  2768. const gfx::Point capture_bounds_center_point =
  2769. GetCaptureBoundsInScreen().CenterPoint();
  2770. // Verify that by default the snap position should be `kBottomRight` and
  2771. // camera preview is placed at the correct position.
  2772. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  2773. camera_controller->camera_preview_snap_position());
  2774. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2775. // Drag the camera preview for a small distance. Tests that even though the
  2776. // snap position does not change, the preview should be snapped back to its
  2777. // previous position.
  2778. DragPreviewToPoint(preview_widget, {capture_bounds_center_point.x() + 20,
  2779. capture_bounds_center_point.y() + 20});
  2780. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  2781. camera_controller->camera_preview_snap_position());
  2782. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2783. // Drag and drop camera preview by mouse to the top right of the
  2784. // `capture_bounds_center_point`, verify that camera preview is snapped to
  2785. // the top right with correct position.
  2786. DragPreviewToPoint(preview_widget, {capture_bounds_center_point.x() + 20,
  2787. capture_bounds_center_point.y() - 20});
  2788. EXPECT_EQ(CameraPreviewSnapPosition::kTopRight,
  2789. camera_controller->camera_preview_snap_position());
  2790. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2791. // Now drag and drop camera preview by touch to the top left of the center
  2792. // point, verify that camera preview is snapped to the top left with correct
  2793. // position.
  2794. DragPreviewToPoint(preview_widget,
  2795. {capture_bounds_center_point.x() - 20,
  2796. capture_bounds_center_point.y() - 20},
  2797. /*by_touch_gestures=*/true);
  2798. EXPECT_EQ(CameraPreviewSnapPosition::kTopLeft,
  2799. camera_controller->camera_preview_snap_position());
  2800. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2801. // Start video recording, verify camera preview is snapped to the correct
  2802. // snap position at the end of drag when there's a video recording in
  2803. // progress.
  2804. StartVideoRecordingImmediately();
  2805. EXPECT_FALSE(CaptureModeController::Get()->IsActive());
  2806. // Drag and drop camera preview by mouse to the bottom left of the center
  2807. // point, verify that camera preview is snapped to the bottom left with
  2808. // correct position.
  2809. DragPreviewToPoint(preview_widget, {capture_bounds_center_point.x() - 20,
  2810. capture_bounds_center_point.y() + 20});
  2811. EXPECT_EQ(CameraPreviewSnapPosition::kBottomLeft,
  2812. camera_controller->camera_preview_snap_position());
  2813. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2814. // Now drag and drop camera preview by touch to the bottom right of the
  2815. // center point, verify that camera preview is snapped to the bottom right
  2816. // with correct position.
  2817. DragPreviewToPoint(preview_widget,
  2818. {capture_bounds_center_point.x() + 20,
  2819. capture_bounds_center_point.y() + 20},
  2820. /*by_touch_gestures=*/true);
  2821. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  2822. camera_controller->camera_preview_snap_position());
  2823. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2824. }
  2825. // Tests the use case after pressing on the resize button on camera preview and
  2826. // releasing the press outside of camera preview, camera preview is still
  2827. // draggable. Regression test for https://crbug.com/1308885.
  2828. TEST_P(CaptureModeCameraPreviewTest,
  2829. CameraPreviewDragToSnapAfterPressOnResizeButton) {
  2830. StartCaptureSessionWithParam();
  2831. auto* camera_controller = GetCameraController();
  2832. AddDefaultCamera();
  2833. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2834. auto* preview_widget = camera_controller->camera_preview_widget();
  2835. auto* resize_button = GetPreviewResizeButton();
  2836. const int camera_previw_width =
  2837. preview_widget->GetWindowBoundsInScreen().width();
  2838. const gfx::Point capture_bounds_center_point =
  2839. GetCaptureBoundsInScreen().CenterPoint();
  2840. const gfx::Point center_point_of_resize_button =
  2841. resize_button->GetBoundsInScreen().CenterPoint();
  2842. // By default the snap position of preview widget should be `kBottomRight`.
  2843. EXPECT_EQ(CameraPreviewSnapPosition::kBottomRight,
  2844. camera_controller->camera_preview_snap_position());
  2845. auto* event_generator = GetEventGenerator();
  2846. event_generator->set_current_screen_location(center_point_of_resize_button);
  2847. event_generator->PressLeftButton();
  2848. const gfx::Vector2d delta(-camera_previw_width, -camera_previw_width);
  2849. // Now move mouse to the outside of the camera preview and then release.
  2850. event_generator->MoveMouseTo(center_point_of_resize_button + delta);
  2851. event_generator->ReleaseLeftButton();
  2852. // Now try to drag the camera preview to the top left, after camera preview is
  2853. // snapped, the current snap position should be `kTopLeft`.
  2854. DragPreviewToPoint(preview_widget, capture_bounds_center_point + delta);
  2855. EXPECT_EQ(CameraPreviewSnapPosition::kTopLeft,
  2856. camera_controller->camera_preview_snap_position());
  2857. }
  2858. TEST_P(CaptureModeCameraPreviewTest, CaptureUisVisibilityChangeOnDragAndDrop) {
  2859. StartCaptureSessionWithParam();
  2860. auto* camera_controller = GetCameraController();
  2861. auto* capture_session = CaptureModeController::Get()->capture_mode_session();
  2862. AddDefaultCamera();
  2863. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2864. auto* preview_widget = camera_controller->camera_preview_widget();
  2865. const gfx::Point center_point_of_preview_widget =
  2866. preview_widget->GetWindowBoundsInScreen().CenterPoint();
  2867. const auto* capture_bar_widget = capture_session->capture_mode_bar_widget();
  2868. const auto* capture_label_widget = capture_session->capture_label_widget();
  2869. // Press on top of the preview widget. Verify capture bar and capture label
  2870. // are hidden.
  2871. auto* event_generator = GetEventGenerator();
  2872. event_generator->set_current_screen_location(center_point_of_preview_widget);
  2873. event_generator->PressLeftButton();
  2874. EXPECT_FALSE(capture_bar_widget->IsVisible());
  2875. EXPECT_FALSE(capture_label_widget->IsVisible());
  2876. // Now drag and move the preview widget. Verify capture bar and capture
  2877. // label are still hidden.
  2878. const gfx::Vector2d delta(-50, -60);
  2879. event_generator->MoveMouseTo(center_point_of_preview_widget + delta);
  2880. EXPECT_FALSE(capture_bar_widget->IsVisible());
  2881. EXPECT_FALSE(capture_label_widget->IsVisible());
  2882. // Release the drag. Verify capture bar and capture label are shown again.
  2883. event_generator->ReleaseLeftButton();
  2884. EXPECT_TRUE(capture_bar_widget->IsVisible());
  2885. EXPECT_TRUE(capture_label_widget->IsVisible());
  2886. }
  2887. TEST_P(CaptureModeCameraPreviewTest, CameraPreviewDragToSnapOnMultipleDisplay) {
  2888. UpdateDisplay("800x700,801+0-800x700");
  2889. const gfx::Point point_in_second_display = gfx::Point(1000, 500);
  2890. auto* event_generator = GetEventGenerator();
  2891. MoveMouseToAndUpdateCursorDisplay(point_in_second_display, event_generator);
  2892. // Start capture mode on the second display.
  2893. StartCaptureSessionWithParam();
  2894. auto* camera_controller = GetCameraController();
  2895. AddDefaultCamera();
  2896. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2897. auto* preview_widget = camera_controller->camera_preview_widget();
  2898. const gfx::Point capture_bounds_center_point =
  2899. GetCaptureBoundsInScreen().CenterPoint();
  2900. // Drag and drop camera preview by mouse to the top right of the
  2901. // `capture_bounds_center_point`, verify that camera preview is snapped to
  2902. // the top right with correct position.
  2903. DragPreviewToPoint(preview_widget, {capture_bounds_center_point.x() + 20,
  2904. capture_bounds_center_point.y() - 20});
  2905. EXPECT_EQ(CameraPreviewSnapPosition::kTopRight,
  2906. camera_controller->camera_preview_snap_position());
  2907. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  2908. }
  2909. // Tests that when there's a video recording is in progress, start a new
  2910. // capture session will make camera preview not draggable.
  2911. TEST_P(CaptureModeCameraPreviewTest,
  2912. DragPreviewInNewCaptureSessionWhileVideoRecordingInProgress) {
  2913. StartCaptureSessionWithParam();
  2914. auto* camera_controller = GetCameraController();
  2915. AddDefaultCamera();
  2916. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2917. auto* preview_widget = camera_controller->camera_preview_widget();
  2918. const gfx::Point capture_bounds_center_point =
  2919. GetCaptureBoundsInScreen().CenterPoint();
  2920. StartVideoRecordingImmediately();
  2921. EXPECT_FALSE(CaptureModeController::Get()->IsActive());
  2922. // Start a new capture session while a video recording is in progress.
  2923. auto* controller = CaptureModeController::Get();
  2924. controller->Start(CaptureModeEntryType::kQuickSettings);
  2925. const gfx::Rect preview_bounds_in_screen_before_drag =
  2926. preview_widget->GetWindowBoundsInScreen();
  2927. const auto snap_position_before_drag =
  2928. camera_controller->camera_preview_snap_position();
  2929. // Verify by default snap position is `kBottomRight`.
  2930. EXPECT_EQ(snap_position_before_drag, CameraPreviewSnapPosition::kBottomRight);
  2931. // Try to drag camera preview by mouse without dropping it, verify camera
  2932. // preview is not draggable and its position is not changed.
  2933. DragPreviewToPoint(preview_widget,
  2934. {preview_bounds_in_screen_before_drag.x() + 20,
  2935. preview_bounds_in_screen_before_drag.y() + 20},
  2936. /*by_touch_gestures=*/false,
  2937. /*drop=*/false);
  2938. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen(),
  2939. preview_bounds_in_screen_before_drag);
  2940. // Try to drag and drop camera preview by touch to the top left of the
  2941. // current capture bounds' center point, verity it's not moved. Also verify
  2942. // the snap position is not updated.
  2943. DragPreviewToPoint(preview_widget,
  2944. {capture_bounds_center_point.x() - 20,
  2945. capture_bounds_center_point.y() - 20},
  2946. /*by_touch_gestures=*/true);
  2947. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen(),
  2948. preview_bounds_in_screen_before_drag);
  2949. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  2950. snap_position_before_drag);
  2951. }
  2952. // Tests that dragging camera preview outside of the preview circle shouldn't
  2953. // work even if the drag events are contained in the preview bounds.
  2954. TEST_P(CaptureModeCameraPreviewTest, DragPreviewOutsidePreviewCircle) {
  2955. StartCaptureSessionWithParam();
  2956. auto* camera_controller = GetCameraController();
  2957. AddDefaultCamera();
  2958. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2959. auto* preview_widget = camera_controller->camera_preview_widget();
  2960. const gfx::Point capture_bounds_center_point =
  2961. GetCaptureBoundsInScreen().CenterPoint();
  2962. const gfx::Rect preview_bounds_in_screen_before_drag =
  2963. preview_widget->GetWindowBoundsInScreen();
  2964. // Try to drag camera preview at its origin point, verify camera
  2965. // preview is not draggable and its position is not changed.
  2966. auto* event_generator = GetEventGenerator();
  2967. event_generator->MoveMouseTo(preview_bounds_in_screen_before_drag.origin());
  2968. event_generator->PressLeftButton();
  2969. event_generator->MoveMouseTo(capture_bounds_center_point);
  2970. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen(),
  2971. preview_bounds_in_screen_before_drag);
  2972. }
  2973. // Tests that dragging camera preview outside of the preview circle doesn't
  2974. // work when video recording is in progress.
  2975. TEST_P(CaptureModeCameraPreviewTest,
  2976. DragPreviewOutsidePreviewCircleWhileVideoRecordingInProgress) {
  2977. StartCaptureSessionWithParam();
  2978. auto* camera_controller = GetCameraController();
  2979. AddDefaultCamera();
  2980. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  2981. auto* preview_widget = camera_controller->camera_preview_widget();
  2982. const gfx::Point capture_bounds_center_point =
  2983. GetCaptureBoundsInScreen().CenterPoint();
  2984. const gfx::Rect preview_bounds_in_screen_before_drag =
  2985. preview_widget->GetWindowBoundsInScreen();
  2986. const auto snap_position_before_drag =
  2987. camera_controller->camera_preview_snap_position();
  2988. // Verify by default snap position is `kBottomRight`.
  2989. EXPECT_EQ(snap_position_before_drag, CameraPreviewSnapPosition::kBottomRight);
  2990. // Try to drag camera preview at its origin point to the top left of current
  2991. // capture bounds' center point, verity it's not moved.
  2992. auto* event_generator = GetEventGenerator();
  2993. event_generator->MoveMouseTo(preview_bounds_in_screen_before_drag.origin());
  2994. event_generator->PressLeftButton();
  2995. event_generator->MoveMouseTo(capture_bounds_center_point);
  2996. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen(),
  2997. preview_bounds_in_screen_before_drag);
  2998. // Release drag, verify snap position is not changed.
  2999. event_generator->ReleaseLeftButton();
  3000. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3001. snap_position_before_drag);
  3002. }
  3003. // Tests that when mouse event is on top of camera preview circle, cursor type
  3004. // should be updated accordingly.
  3005. TEST_P(CaptureModeCameraPreviewTest, CursorTypeUpdates) {
  3006. StartCaptureSessionWithParam();
  3007. auto* camera_controller = GetCameraController();
  3008. AddDefaultCamera();
  3009. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3010. auto* preview_widget = camera_controller->camera_preview_widget();
  3011. const gfx::Rect preview_bounds_in_screen =
  3012. preview_widget->GetWindowBoundsInScreen();
  3013. const gfx::Point camera_preview_center_point =
  3014. preview_bounds_in_screen.CenterPoint();
  3015. const gfx::Point camera_preview_origin_point =
  3016. preview_bounds_in_screen.origin();
  3017. auto* event_generator = GetEventGenerator();
  3018. auto* cursor_manager = Shell::Get()->cursor_manager();
  3019. // Verify that moving mouse to the origin point on camera preview won't
  3020. // update the cursor type to `kPointer`.
  3021. event_generator->MoveMouseTo(preview_bounds_in_screen.origin());
  3022. EXPECT_NE(cursor_manager->GetCursor(), ui::mojom::CursorType::kPointer);
  3023. // Verify that moving mouse on camera preview will update the cursor type
  3024. // to `kPointer`.
  3025. event_generator->MoveMouseTo(camera_preview_center_point);
  3026. EXPECT_EQ(cursor_manager->GetCursor(), ui::mojom::CursorType::kPointer);
  3027. // Move mouse from camera preview to capture surface, verify cursor type is
  3028. // updated to the correct type of the current capture source.
  3029. event_generator->MoveMouseTo({camera_preview_origin_point.x() - 10,
  3030. camera_preview_origin_point.y() - 10});
  3031. EXPECT_EQ(cursor_manager->GetCursor(), GetCursorTypeOnCaptureSurface());
  3032. // Drag camera preview, verify that cursor type is updated to `kPointer`.
  3033. DragPreviewToPoint(preview_widget,
  3034. {camera_preview_center_point.x() - 10,
  3035. camera_preview_center_point.y() - 10},
  3036. /*by_touch_gestures=*/false,
  3037. /*drop=*/false);
  3038. EXPECT_EQ(cursor_manager->GetCursor(), ui::mojom::CursorType::kPointer);
  3039. // Continue dragging and then drop camera preview, make sure cursor's
  3040. // position is outside of camera preview after it's snapped. Verify cursor
  3041. // type is updated to the correct type of the current capture source.
  3042. DragPreviewToPoint(preview_widget, {camera_preview_origin_point.x() - 20,
  3043. camera_preview_origin_point.y() - 20});
  3044. EXPECT_EQ(cursor_manager->GetCursor(), GetCursorTypeOnCaptureSurface());
  3045. }
  3046. // Tests the functionality of resize button on changing the size of the camera
  3047. // preview widget, updating the icon image and tooltip text after clicking on
  3048. // it. It also tests the ability to restore to previous resize button settings
  3049. // if any when initiating a new capture mode session.
  3050. TEST_P(CaptureModeCameraPreviewTest, ResizePreviewWidget) {
  3051. UpdateDisplay("800x700");
  3052. StartCaptureSessionWithParam();
  3053. auto* controller = CaptureModeController::Get();
  3054. auto* camera_controller = GetCameraController();
  3055. AddDefaultCamera();
  3056. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3057. views::Widget* preview_widget = camera_controller->camera_preview_widget();
  3058. DCHECK(preview_widget);
  3059. const auto default_preview_bounds = preview_widget->GetWindowBoundsInScreen();
  3060. EXPECT_EQ(default_preview_bounds.size(),
  3061. GetExpectedPreviewSize(/*collapsed=*/false));
  3062. auto* resize_button = GetPreviewResizeButton();
  3063. auto* event_generator = GetEventGenerator();
  3064. // Tests the default settings of the resize button.
  3065. VerifyResizeButton(camera_controller->is_camera_preview_collapsed(),
  3066. resize_button);
  3067. // First time click on resize button will make the preview widget collapse
  3068. // to half of the default size with tooltip text and resize button icon
  3069. // changed to expanded related contents accordingly.
  3070. ClickOnView(resize_button, event_generator);
  3071. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().size(),
  3072. GetExpectedPreviewSize(/*collapsed=*/true));
  3073. VerifyResizeButton(camera_controller->is_camera_preview_collapsed(),
  3074. resize_button);
  3075. // Second time click on resize button will make the preview widget expand
  3076. // back to the default size with tooltip text and resize button icon changed
  3077. // to the collapsed related contents accordingly.
  3078. ClickOnView(resize_button, event_generator);
  3079. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen(), default_preview_bounds);
  3080. VerifyResizeButton(camera_controller->is_camera_preview_collapsed(),
  3081. resize_button);
  3082. // Click on the resize button again will collapse the preview widget. Exit the
  3083. // session and start a new session, the settings for preview widget bounds and
  3084. // resize button will be restored.
  3085. ClickOnView(resize_button, event_generator);
  3086. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().size(),
  3087. GetExpectedPreviewSize(/*collapsed=*/true));
  3088. VerifyResizeButton(camera_controller->is_camera_preview_collapsed(),
  3089. resize_button);
  3090. const auto collapsed_preview_bounds =
  3091. preview_widget->GetWindowBoundsInScreen();
  3092. controller->Stop();
  3093. StartCaptureSessionWithParam();
  3094. preview_widget = camera_controller->camera_preview_widget();
  3095. EXPECT_TRUE(preview_widget);
  3096. EXPECT_EQ(preview_widget->GetWindowBoundsInScreen(),
  3097. collapsed_preview_bounds);
  3098. resize_button = GetPreviewResizeButton();
  3099. EXPECT_TRUE(resize_button);
  3100. VerifyResizeButton(camera_controller->is_camera_preview_collapsed(),
  3101. resize_button);
  3102. }
  3103. // Tests that resizing the camera preview using the resize button, which uses
  3104. // the bounds animation, works correctly on a secondary display. Regression test
  3105. // for https://crbug.com/1313247.
  3106. TEST_P(CaptureModeCameraPreviewTest, MultiDisplayResize) {
  3107. UpdateDisplay("800x700,801+0-800x700");
  3108. ASSERT_EQ(2u, Shell::GetAllRootWindows().size());
  3109. auto* camera_controller = GetCameraController();
  3110. AddDefaultCamera();
  3111. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3112. // Put the cursor in the secondary display, and expect the session root to be
  3113. // there.
  3114. auto* event_generator = GetEventGenerator();
  3115. MoveMouseToAndUpdateCursorDisplay(gfx::Point(900, 500), event_generator);
  3116. StartCaptureSessionWithParam();
  3117. auto* controller = CaptureModeController::Get();
  3118. auto* session = controller->capture_mode_session();
  3119. auto* display_2_root = Shell::GetAllRootWindows()[1];
  3120. // When capturing a window, set its bounds such that it is placed on the
  3121. // secondary display.
  3122. if (GetParam() == CaptureModeSource::kWindow) {
  3123. views::Widget::GetWidgetForNativeWindow(window())->SetBounds(
  3124. {900, 10, 700, 650});
  3125. EXPECT_EQ(display_2_root, window()->GetRootWindow());
  3126. event_generator->MoveMouseToCenterOf(window());
  3127. }
  3128. EXPECT_EQ(display_2_root, session->current_root());
  3129. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  3130. auto* resize_button = GetPreviewResizeButton();
  3131. ClickOnView(resize_button, event_generator);
  3132. VerifyPreviewAlignment(GetCaptureBoundsInScreen());
  3133. }
  3134. // Tests the visibility of the resize button on mouse events.
  3135. TEST_P(CaptureModeCameraPreviewTest, ResizeButtonVisibilityOnMouseEvents) {
  3136. UpdateDisplay("1366x768");
  3137. StartCaptureSessionWithParam();
  3138. CaptureModeCameraController* camera_controller = GetCameraController();
  3139. AddDefaultCamera();
  3140. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3141. views::Widget* preview_widget = camera_controller->camera_preview_widget();
  3142. DCHECK(preview_widget);
  3143. const gfx::Rect default_preview_bounds =
  3144. preview_widget->GetWindowBoundsInScreen();
  3145. CaptureModeButton* resize_button = GetPreviewResizeButton();
  3146. auto* event_generator = GetEventGenerator();
  3147. // Tests that the resize button is hidden by default.
  3148. EXPECT_FALSE(resize_button->GetVisible());
  3149. // Tests that the resize button will show up when the mouse is entering the
  3150. // bounds of the preview widget.
  3151. event_generator->MoveMouseTo(default_preview_bounds.CenterPoint());
  3152. EXPECT_TRUE(resize_button->GetVisible());
  3153. // Tests that the resize button will stay visible while moving the mouse
  3154. // within the bounds of the preview widget.
  3155. event_generator->MoveMouseTo(default_preview_bounds.top_center());
  3156. EXPECT_TRUE(resize_button->GetVisible());
  3157. // Tests that when the mouse is exiting the bounds of the preview widget, the
  3158. // resize button will disappear after the predefined duration.
  3159. auto outside_point = default_preview_bounds.origin();
  3160. outside_point.Offset(-1, -1);
  3161. event_generator->MoveMouseTo(outside_point);
  3162. base::OneShotTimer* timer = camera_controller->camera_preview_view()
  3163. ->resize_button_hide_timer_for_test();
  3164. EXPECT_TRUE(timer->IsRunning());
  3165. EXPECT_EQ(timer->GetCurrentDelay(), capture_mode::kResizeButtonShowDuration);
  3166. {
  3167. ViewVisibilityChangeWaiter waiter(resize_button);
  3168. EXPECT_TRUE(resize_button->GetVisible());
  3169. timer->FireNow();
  3170. waiter.Wait();
  3171. EXPECT_FALSE(resize_button->GetVisible());
  3172. }
  3173. }
  3174. // Tests the visibility of the resize button on tap events.
  3175. TEST_P(CaptureModeCameraPreviewTest, ResizeButtonVisibilityOnTapEvents) {
  3176. UpdateDisplay("800x700");
  3177. StartCaptureSessionWithParam();
  3178. CaptureModeCameraController* camera_controller = GetCameraController();
  3179. AddDefaultCamera();
  3180. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3181. views::Widget* preview_widget = camera_controller->camera_preview_widget();
  3182. DCHECK(preview_widget);
  3183. const gfx::Rect default_preview_bounds =
  3184. preview_widget->GetWindowBoundsInScreen();
  3185. CaptureModeButton* resize_button = GetPreviewResizeButton();
  3186. auto* event_generator = GetEventGenerator();
  3187. // Tests that the resize button is hidden by default.
  3188. EXPECT_FALSE(resize_button->GetVisible());
  3189. // Tests that resize button shows up when tapping within the bounds of the
  3190. // preview widget and will fade out after the predefined duration.
  3191. event_generator->GestureTapAt(default_preview_bounds.CenterPoint());
  3192. EXPECT_TRUE(resize_button->GetVisible());
  3193. base::OneShotTimer* timer = camera_controller->camera_preview_view()
  3194. ->resize_button_hide_timer_for_test();
  3195. EXPECT_TRUE(timer->IsRunning());
  3196. EXPECT_EQ(timer->GetCurrentDelay(), capture_mode::kResizeButtonShowDuration);
  3197. {
  3198. ViewVisibilityChangeWaiter waiter(resize_button);
  3199. timer->FireNow();
  3200. waiter.Wait();
  3201. EXPECT_FALSE(resize_button->GetVisible());
  3202. }
  3203. }
  3204. // Tests the visibility of the resize button on camera preview drag to snap.
  3205. TEST_P(CaptureModeCameraPreviewTest,
  3206. ResizeButtonVisibilityOnCameraPreviewDragToSnap) {
  3207. UpdateDisplay("1366x768");
  3208. StartCaptureSessionWithParam();
  3209. CaptureModeCameraController* camera_controller = GetCameraController();
  3210. AddDefaultCamera();
  3211. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3212. views::Widget* preview_widget = camera_controller->camera_preview_widget();
  3213. const gfx::Rect preview_bounds = preview_widget->GetWindowBoundsInScreen();
  3214. CaptureModeButton* resize_button = GetPreviewResizeButton();
  3215. auto* event_generator = GetEventGenerator();
  3216. // Tests that the resize button is hidden by default.
  3217. EXPECT_FALSE(resize_button->GetVisible());
  3218. // Tests that the resize button will show up when the mouse is entering the
  3219. // bounds of the preview widget.
  3220. event_generator->MoveMouseTo(preview_bounds.CenterPoint());
  3221. EXPECT_TRUE(resize_button->GetVisible());
  3222. // Tests that when start dragging camera preview, resize button will be
  3223. // hidden.
  3224. event_generator->PressLeftButton();
  3225. EXPECT_FALSE(resize_button->GetVisible());
  3226. // Drag camera preview, test that resize button is still hidden.
  3227. event_generator->MoveMouseBy(-300, -300);
  3228. EXPECT_FALSE(resize_button->GetVisible());
  3229. // Now release drag, verify that resize button is still hidden since cursor is
  3230. // not on top of camera preview after it's snapped.
  3231. event_generator->ReleaseLeftButton();
  3232. EXPECT_FALSE(resize_button->GetVisible());
  3233. // Now drag camera preview with a small distance, make sure when it's snapped
  3234. // cursor is still on top of it. Verify that resize button is shown after
  3235. // camera preview is snapped.
  3236. const gfx::Vector2d delta(-30, -30);
  3237. DragPreviewToPoint(preview_widget, preview_bounds.CenterPoint() + delta);
  3238. EXPECT_TRUE(resize_button->GetVisible());
  3239. }
  3240. TEST_P(CaptureModeCameraPreviewTest, CameraPreviewDeintersectsWithSystemTray) {
  3241. UpdateDisplay("1366x768");
  3242. // Open system tray.
  3243. ui::test::EventGenerator* event_generator = GetEventGenerator();
  3244. auto* system_tray = GetPrimaryUnifiedSystemTray();
  3245. event_generator->MoveMouseTo(system_tray->GetBoundsInScreen().CenterPoint());
  3246. event_generator->ClickLeftButton();
  3247. EXPECT_TRUE(system_tray->IsBubbleShown());
  3248. StartCaptureSessionWithParam();
  3249. auto* camera_controller = GetCameraController();
  3250. // Verify current default snap position is the `kBottomRight` before we select
  3251. // a camera device.
  3252. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3253. CameraPreviewSnapPosition::kBottomRight);
  3254. AddDefaultCamera();
  3255. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3256. auto* preview_widget = camera_controller->camera_preview_widget();
  3257. EXPECT_TRUE(system_tray->IsBubbleShown());
  3258. // Verify that camera preview doesn't overlap with system tray when it's
  3259. // shown. Also verify current snap position is updated and not `kBottomRight`
  3260. // anymore.
  3261. EXPECT_FALSE(system_tray->GetBubbleBoundsInScreen().Intersects(
  3262. preview_widget->GetWindowBoundsInScreen()));
  3263. EXPECT_NE(camera_controller->camera_preview_snap_position(),
  3264. CameraPreviewSnapPosition::kBottomRight);
  3265. }
  3266. TEST_P(CaptureModeCameraPreviewTest,
  3267. CameraPreviewDeintersectsWithSystemTrayWhileVideoRecordingInProgress) {
  3268. // Update display size big enough to make sure when capture source is
  3269. // `kWindow`, the selected window is not system tray.
  3270. UpdateDisplay("1366x768");
  3271. StartCaptureSessionWithParam();
  3272. auto* camera_controller = GetCameraController();
  3273. AddDefaultCamera();
  3274. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3275. auto* preview_widget = camera_controller->camera_preview_widget();
  3276. const gfx::Point capture_bounds_center_point =
  3277. GetCaptureBoundsInScreen().CenterPoint();
  3278. StartVideoRecordingImmediately();
  3279. // Verify current snap position is `kBottomRight`;
  3280. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3281. CameraPreviewSnapPosition::kBottomRight);
  3282. // Now open system tray.
  3283. ui::test::EventGenerator* event_generator = GetEventGenerator();
  3284. auto* system_tray = GetPrimaryUnifiedSystemTray();
  3285. event_generator->MoveMouseTo(system_tray->GetBoundsInScreen().CenterPoint());
  3286. event_generator->ClickLeftButton();
  3287. EXPECT_TRUE(system_tray->IsBubbleShown());
  3288. // Verify that after system tray is open, camera preview is snapped and
  3289. // doesn't overlap with system tray.
  3290. EXPECT_NE(camera_controller->camera_preview_snap_position(),
  3291. CameraPreviewSnapPosition::kBottomRight);
  3292. EXPECT_FALSE(system_tray->GetBubbleBoundsInScreen().Intersects(
  3293. preview_widget->GetWindowBoundsInScreen()));
  3294. // Now try to drag camera preview to the bottom right corner, verify that
  3295. // since system tray is still open, when drag is released, camera preview is
  3296. // not snapped to the bottom right corner even it's the nearest corner to the
  3297. // release position if system tray is still shown.
  3298. const gfx::Vector2d delta(20, 20);
  3299. DragPreviewToPoint(preview_widget, capture_bounds_center_point + delta);
  3300. // Please notice, when capture source is `kWindow`, once the drag starts,
  3301. // system tray will be closed, in this use case we just need to verify camera
  3302. // preview is snapped to the bottom right corner.
  3303. if (system_tray->IsBubbleShown()) {
  3304. EXPECT_NE(camera_controller->camera_preview_snap_position(),
  3305. CameraPreviewSnapPosition::kBottomRight);
  3306. EXPECT_FALSE(system_tray->GetBubbleBoundsInScreen().Intersects(
  3307. preview_widget->GetWindowBoundsInScreen()));
  3308. } else {
  3309. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3310. CameraPreviewSnapPosition::kBottomRight);
  3311. }
  3312. }
  3313. TEST_P(CaptureModeCameraPreviewTest, CameraPreviewDeintersectsWithPipWindow) {
  3314. // Create a window at the bottom right of the display, then convert it to a
  3315. // PIP window.
  3316. std::unique_ptr<aura::Window> pip_window(
  3317. CreateTestWindow(gfx::Rect(700, 450, 104, 100)));
  3318. ConvertToPipWindow(pip_window.get());
  3319. const gfx::Rect origin_pip_window_bounds = pip_window->GetBoundsInScreen();
  3320. StartCaptureSessionWithParam();
  3321. auto* camera_controller = GetCameraController();
  3322. AddDefaultCamera();
  3323. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3324. auto* preview_widget = camera_controller->camera_preview_widget();
  3325. // Verify that after preview widget is enabled, pip window is repositioned to
  3326. // avoid the overlap with camera preview.
  3327. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3328. CameraPreviewSnapPosition::kBottomRight);
  3329. const gfx::Rect current_pip_window_bounds = pip_window->GetBoundsInScreen();
  3330. EXPECT_NE(origin_pip_window_bounds, current_pip_window_bounds);
  3331. EXPECT_FALSE(current_pip_window_bounds.Intersects(
  3332. preview_widget->GetWindowBoundsInScreen()));
  3333. }
  3334. TEST_P(CaptureModeCameraPreviewTest,
  3335. CameraPreviewDeintersectsWithPipWindowDuringRecording) {
  3336. // Create a window at the top left of the display, then convert it to a PIP
  3337. // window.
  3338. std::unique_ptr<aura::Window> pip_window(
  3339. CreateTestWindow(gfx::Rect(0, 0, 104, 100)));
  3340. ConvertToPipWindow(pip_window.get());
  3341. const gfx::Rect origin_pip_window_bounds = pip_window->GetBoundsInScreen();
  3342. StartCaptureSessionWithParam();
  3343. auto* camera_controller = GetCameraController();
  3344. AddDefaultCamera();
  3345. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3346. auto* preview_widget = camera_controller->camera_preview_widget();
  3347. const gfx::Point capture_bounds_center_point =
  3348. GetCaptureBoundsInScreen().CenterPoint();
  3349. // Verify camera preview is enabled, current snap position is `kBottomRight`
  3350. // and pip window is not repositioned since there's no overlap.
  3351. EXPECT_TRUE(preview_widget);
  3352. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3353. CameraPreviewSnapPosition::kBottomRight);
  3354. EXPECT_EQ(origin_pip_window_bounds, pip_window->GetBoundsInScreen());
  3355. StartVideoRecordingImmediately();
  3356. // Now drag camera preview to the top left corner, verify pip window is
  3357. // repositioned to avoid overlap with camera preview.
  3358. const gfx::Vector2d delta(-20, -20);
  3359. DragPreviewToPoint(preview_widget, capture_bounds_center_point + delta);
  3360. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3361. CameraPreviewSnapPosition::kTopLeft);
  3362. EXPECT_NE(origin_pip_window_bounds, pip_window->GetBoundsInScreen());
  3363. EXPECT_FALSE(preview_widget->GetWindowBoundsInScreen().Intersects(
  3364. pip_window->GetBoundsInScreen()));
  3365. }
  3366. TEST_P(CaptureModeCameraPreviewTest,
  3367. CameraPreviewDeintersectsWithAutoclickBar) {
  3368. // Update display size big enough to make sure when capture source is
  3369. // `kWindow`, the selected window is not system tray.
  3370. UpdateDisplay("1366x768");
  3371. // Enable autoclick bar.
  3372. auto* autoclick_controller = Shell::Get()->autoclick_controller();
  3373. autoclick_controller->SetEnabled(true, /*show_confirmation_dialog=*/false);
  3374. Shell::Get()
  3375. ->accessibility_controller()
  3376. ->GetFeature(AccessibilityControllerImpl::FeatureType::kAutoclick)
  3377. .SetEnabled(true);
  3378. views::Widget* autoclick_bubble_widget =
  3379. autoclick_controller->GetMenuBubbleControllerForTesting()
  3380. ->GetBubbleWidgetForTesting();
  3381. EXPECT_TRUE(autoclick_bubble_widget->IsVisible());
  3382. const gfx::Rect origin_autoclick_bar_bounds =
  3383. autoclick_bubble_widget->GetWindowBoundsInScreen();
  3384. StartCaptureSessionWithParam();
  3385. auto* camera_controller = GetCameraController();
  3386. AddDefaultCamera();
  3387. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3388. auto* preview_widget = camera_controller->camera_preview_widget();
  3389. // Verify that after preview widget is enabled, autoclick bar is repositioned
  3390. // to avoid the overlap with camera preview.
  3391. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3392. CameraPreviewSnapPosition::kBottomRight);
  3393. const gfx::Rect current_autoclick_bar_bounds =
  3394. autoclick_bubble_widget->GetWindowBoundsInScreen();
  3395. EXPECT_NE(origin_autoclick_bar_bounds, current_autoclick_bar_bounds);
  3396. EXPECT_FALSE(current_autoclick_bar_bounds.Intersects(
  3397. preview_widget->GetWindowBoundsInScreen()));
  3398. }
  3399. TEST_P(CaptureModeCameraPreviewTest,
  3400. CameraPreviewDeintersectsWithSystemTrayOnSizeChanged) {
  3401. // Update display size to make sure when system tray is open, camera preview
  3402. // can stay in the same side with it when camera preview is collapsed,
  3403. // otherwise, camera preview should be snapped to the other side of the
  3404. // display.
  3405. UpdateDisplay("1366x700");
  3406. StartCaptureSessionWithParam();
  3407. auto* camera_controller = GetCameraController();
  3408. AddDefaultCamera();
  3409. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3410. auto* preview_widget = camera_controller->camera_preview_widget();
  3411. // Verify camera preview is enabled, and by default, the current snap position
  3412. // should be `kBottomRight`.
  3413. EXPECT_TRUE(preview_widget);
  3414. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3415. CameraPreviewSnapPosition::kBottomRight);
  3416. // Click on resize button to collapse camera preview.
  3417. auto* resize_button = GetPreviewResizeButton();
  3418. auto* event_generator = GetEventGenerator();
  3419. ClickOnView(resize_button, event_generator);
  3420. EXPECT_TRUE(camera_controller->is_camera_preview_collapsed());
  3421. StartVideoRecordingImmediately();
  3422. // Open system tray.
  3423. auto* system_tray = GetPrimaryUnifiedSystemTray();
  3424. event_generator->MoveMouseTo(system_tray->GetBoundsInScreen().CenterPoint());
  3425. event_generator->ClickLeftButton();
  3426. EXPECT_TRUE(system_tray->IsBubbleShown());
  3427. // After system tray is shown, verify that camera preview is snapped to the
  3428. // top right corner, and there's no overlap between camera preview and system
  3429. // tray.
  3430. EXPECT_TRUE(system_tray->IsBubbleShown());
  3431. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3432. CameraPreviewSnapPosition::kTopRight);
  3433. EXPECT_FALSE(preview_widget->GetWindowBoundsInScreen().Intersects(
  3434. system_tray->GetBoundsInScreen()));
  3435. // Click on the resize button to enlarge camera preview. Verify that camera
  3436. // preview remains snapped to the top right corner, since there's no overlap.
  3437. ClickOnView(resize_button, event_generator);
  3438. EXPECT_FALSE(preview_widget->GetWindowBoundsInScreen().Intersects(
  3439. system_tray->GetBoundsInScreen()));
  3440. EXPECT_EQ(camera_controller->camera_preview_snap_position(),
  3441. CameraPreviewSnapPosition::kTopRight);
  3442. }
  3443. TEST_P(CaptureModeCameraPreviewTest, CameraPreviewSpecs) {
  3444. AddDefaultCamera();
  3445. CaptureModeTestApi().SelectCameraAtIndex(0);
  3446. auto* camera_controller = GetCameraController();
  3447. struct {
  3448. CameraPreviewState preview_state;
  3449. std::string scope_trace;
  3450. } kTestCases[] = {
  3451. {CameraPreviewState::kCollapsible, "Collapsible Preview"},
  3452. {CameraPreviewState::kNotCollapsible, "Not Collapsible Preview"},
  3453. {CameraPreviewState::kHidden, "Hidden Preview"},
  3454. };
  3455. for (const auto& test_case : kTestCases) {
  3456. SCOPED_TRACE(test_case.scope_trace);
  3457. UpdateDisplay("1366x700");
  3458. StartCaptureSessionWithParam();
  3459. auto* camera_preview_widget = camera_controller->camera_preview_widget();
  3460. auto* camera_preview_view = camera_controller->camera_preview_view();
  3461. EXPECT_TRUE(camera_preview_widget);
  3462. EXPECT_TRUE(camera_preview_widget->IsVisible());
  3463. EXPECT_TRUE(camera_preview_view->is_collapsible());
  3464. ResizeSurfaceSoCameraPreviewBecomes(test_case.preview_state);
  3465. const auto preview_screen_bounds =
  3466. camera_preview_widget->GetWindowBoundsInScreen();
  3467. switch (test_case.preview_state) {
  3468. case CameraPreviewState::kCollapsible:
  3469. EXPECT_TRUE(camera_preview_widget->IsVisible());
  3470. EXPECT_TRUE(camera_preview_view->is_collapsible());
  3471. EXPECT_EQ(preview_screen_bounds.size(),
  3472. GetExpectedPreviewSize(/*collapsed=*/false));
  3473. break;
  3474. case CameraPreviewState::kNotCollapsible:
  3475. EXPECT_TRUE(camera_preview_widget->IsVisible());
  3476. EXPECT_FALSE(camera_preview_view->is_collapsible());
  3477. EXPECT_EQ(preview_screen_bounds.size(),
  3478. GetExpectedPreviewSize(/*collapsed=*/false));
  3479. break;
  3480. case CameraPreviewState::kHidden:
  3481. EXPECT_FALSE(camera_preview_widget->IsVisible());
  3482. EXPECT_FALSE(camera_preview_view->is_collapsible());
  3483. break;
  3484. }
  3485. }
  3486. }
  3487. // Tests that the resize button will stay visible after mouse exiting the
  3488. // preview and time exceeding the predefined duration on mouse event when switch
  3489. // access is enabled. And the resize button will behave in a default way if
  3490. // switch access is not enabled.
  3491. TEST_P(CaptureModeCameraPreviewTest,
  3492. ResizeButtonSwitchAccessVisibilityTestOnMouseEvent) {
  3493. UpdateDisplay("1366x768");
  3494. CaptureModeCameraController* camera_controller = GetCameraController();
  3495. AddDefaultCamera();
  3496. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3497. auto* event_generator = GetEventGenerator();
  3498. for (const bool switch_access_enabled : {false, true}) {
  3499. AccessibilityControllerImpl* a11y_controller =
  3500. Shell::Get()->accessibility_controller();
  3501. a11y_controller->switch_access().SetEnabled(switch_access_enabled);
  3502. EXPECT_EQ(switch_access_enabled, a11y_controller->IsSwitchAccessRunning());
  3503. StartCaptureSessionWithParam();
  3504. views::Widget* preview_widget = camera_controller->camera_preview_widget();
  3505. DCHECK(preview_widget);
  3506. gfx::Rect preview_bounds = preview_widget->GetWindowBoundsInScreen();
  3507. CaptureModeButton* resize_button = GetPreviewResizeButton();
  3508. // Tests the default visibility of the resize button based on whether switch
  3509. // access is enabled or not.
  3510. EXPECT_EQ(resize_button->GetVisible(),
  3511. switch_access_enabled ? true : false);
  3512. event_generator->MoveMouseTo(preview_bounds.CenterPoint());
  3513. EXPECT_TRUE(resize_button->GetVisible());
  3514. auto outside_point = preview_bounds.origin();
  3515. outside_point.Offset(-1, -1);
  3516. event_generator->MoveMouseTo(outside_point);
  3517. base::OneShotTimer* timer = camera_controller->camera_preview_view()
  3518. ->resize_button_hide_timer_for_test();
  3519. timer->FireNow();
  3520. EXPECT_EQ(resize_button->GetVisible(),
  3521. switch_access_enabled ? true : false);
  3522. // Tests that the resize button will be hidden when start dragging the
  3523. // camera preview regardless of whether the switch access is enabled or not.
  3524. event_generator->MoveMouseTo(preview_bounds.CenterPoint());
  3525. EXPECT_TRUE(resize_button->GetVisible());
  3526. event_generator->PressLeftButton();
  3527. EXPECT_FALSE(resize_button->GetVisible());
  3528. event_generator->MoveMouseBy(-100, -100);
  3529. EXPECT_FALSE(resize_button->GetVisible());
  3530. // Tests that the resize button will be visible if the switch access is
  3531. // enabled after releasing the drag and not visible otherwise.
  3532. event_generator->ReleaseLeftButton();
  3533. EXPECT_EQ(resize_button->GetVisible(),
  3534. switch_access_enabled ? true : false);
  3535. CaptureModeController::Get()->Stop();
  3536. }
  3537. }
  3538. // Tests that the resize button will stay visible after tapping on the preview
  3539. // and time exceeding the predefined duration on tap event when switch access is
  3540. // enabled. And the resize button will behave in a default way if switch
  3541. // access is not enabled.
  3542. TEST_P(CaptureModeCameraPreviewTest,
  3543. ResizeButtonSwitchAccessVisibilityTestOnTapEvent) {
  3544. UpdateDisplay("1366x768");
  3545. SwitchToTabletMode();
  3546. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  3547. CaptureModeCameraController* camera_controller = GetCameraController();
  3548. AddDefaultCamera();
  3549. camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
  3550. auto* event_generator = GetEventGenerator();
  3551. for (const bool switch_access_enabled : {false, true}) {
  3552. AccessibilityControllerImpl* a11y_controller =
  3553. Shell::Get()->accessibility_controller();
  3554. a11y_controller->switch_access().SetEnabled(switch_access_enabled);
  3555. EXPECT_EQ(switch_access_enabled, a11y_controller->IsSwitchAccessRunning());
  3556. StartCaptureSessionWithParam();
  3557. views::Widget* preview_widget = camera_controller->camera_preview_widget();
  3558. DCHECK(preview_widget);
  3559. gfx::Rect preview_bounds = preview_widget->GetWindowBoundsInScreen();
  3560. CaptureModeButton* resize_button = GetPreviewResizeButton();
  3561. // Tests the default visibility of the resize button based on whether switch
  3562. // access is enabled or not.
  3563. EXPECT_EQ(resize_button->GetVisible(),
  3564. switch_access_enabled ? true : false);
  3565. event_generator->GestureTapAt(preview_bounds.CenterPoint());
  3566. EXPECT_TRUE(resize_button->GetVisible());
  3567. base::OneShotTimer* timer = camera_controller->camera_preview_view()
  3568. ->resize_button_hide_timer_for_test();
  3569. if (timer->IsRunning())
  3570. timer->FireNow();
  3571. EXPECT_EQ(resize_button->GetVisible(),
  3572. switch_access_enabled ? true : false);
  3573. CaptureModeController::Get()->Stop();
  3574. }
  3575. }
  3576. INSTANTIATE_TEST_SUITE_P(All,
  3577. CaptureModeCameraPreviewTest,
  3578. testing::Values(CaptureModeSource::kFullscreen,
  3579. CaptureModeSource::kRegion,
  3580. CaptureModeSource::kWindow));
  3581. class ProjectorCaptureModeCameraTest : public CaptureModeCameraTest {
  3582. public:
  3583. ProjectorCaptureModeCameraTest() = default;
  3584. ~ProjectorCaptureModeCameraTest() override = default;
  3585. // CaptureModeCameraTest:
  3586. void SetUp() override {
  3587. CaptureModeCameraTest::SetUp();
  3588. projector_helper_.SetUp();
  3589. }
  3590. void StartProjectorModeSession() {
  3591. projector_helper_.StartProjectorModeSession();
  3592. }
  3593. private:
  3594. ProjectorCaptureModeIntegrationHelper projector_helper_;
  3595. };
  3596. TEST_F(ProjectorCaptureModeCameraTest, NoAvailableCameras) {
  3597. // Initially no camera should be selected.
  3598. auto* camera_controller = GetCameraController();
  3599. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  3600. // Starting a projector session should not result in showing any cameras, or
  3601. // any crashes.
  3602. StartProjectorModeSession();
  3603. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  3604. EXPECT_FALSE(camera_controller->camera_preview_widget());
  3605. }
  3606. TEST_F(ProjectorCaptureModeCameraTest, FirstCamSelectedByDefault) {
  3607. AddDefaultCamera();
  3608. // Initially no camera should be selected.
  3609. auto* camera_controller = GetCameraController();
  3610. EXPECT_FALSE(camera_controller->selected_camera().is_valid());
  3611. // Starting a projector session should result in selecting the first available
  3612. // camera by default, and its preview should be visible.
  3613. StartProjectorModeSession();
  3614. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  3615. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3616. }
  3617. TEST_F(ProjectorCaptureModeCameraTest,
  3618. SessionStartsWithAnAlreadySelectedCamera) {
  3619. const std::string model_id_1 = "model1";
  3620. const std::string model_id_2 = "model2";
  3621. AddFakeCamera("/dev/video0", "fake cam 1", model_id_1);
  3622. AddFakeCamera("/dev/video1", "fake cam 2", model_id_2);
  3623. // Initially there's a camera already selected before we start the session,
  3624. // and it's the second camera in the list.
  3625. auto* camera_controller = GetCameraController();
  3626. CameraId cam_id_1(model_id_1, 1);
  3627. CameraId cam_id_2(model_id_2, 1);
  3628. EXPECT_EQ(cam_id_1, camera_controller->available_cameras()[0].camera_id);
  3629. EXPECT_EQ(cam_id_2, camera_controller->available_cameras()[1].camera_id);
  3630. camera_controller->SetSelectedCamera(cam_id_2);
  3631. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  3632. // Starting a projector session should not result in selecting the first
  3633. // camera. The already selected camera should remain as is.
  3634. StartProjectorModeSession();
  3635. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  3636. EXPECT_EQ(cam_id_2, camera_controller->selected_camera());
  3637. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3638. }
  3639. // Tests that the recording starts with camera metrics are recorded correctly in
  3640. // a projector-initiated recording.
  3641. TEST_F(ProjectorCaptureModeCameraTest,
  3642. ProjectorRecordingStartsWithCameraHistogramTest) {
  3643. base::HistogramTester histogram_tester;
  3644. constexpr char kHistogramNameBase[] =
  3645. "Ash.CaptureModeController.Projector.RecordingStartsWithCamera";
  3646. AddDefaultCamera();
  3647. struct {
  3648. bool tablet_enabled;
  3649. bool camera_on;
  3650. } kTestCases[] = {
  3651. {false, false},
  3652. {false, true},
  3653. {true, false},
  3654. {true, true},
  3655. };
  3656. for (const auto test_case : kTestCases) {
  3657. if (test_case.tablet_enabled) {
  3658. SwitchToTabletMode();
  3659. EXPECT_TRUE(Shell::Get()->IsInTabletMode());
  3660. } else {
  3661. EXPECT_FALSE(Shell::Get()->IsInTabletMode());
  3662. }
  3663. histogram_tester.ExpectBucketCount(
  3664. GetCaptureModeHistogramName(kHistogramNameBase), test_case.camera_on,
  3665. 0);
  3666. auto* controller = CaptureModeController::Get();
  3667. controller->SetType(CaptureModeType::kVideo);
  3668. controller->SetSource(CaptureModeSource::kFullscreen);
  3669. StartProjectorModeSession();
  3670. EXPECT_TRUE(controller->IsActive());
  3671. auto* session = controller->capture_mode_session();
  3672. EXPECT_TRUE(session->is_in_projector_mode());
  3673. GetCameraController()->SetSelectedCamera(
  3674. test_case.camera_on ? CameraId(kDefaultCameraModelId, 1) : CameraId());
  3675. StartVideoRecordingImmediately();
  3676. EXPECT_TRUE(controller->is_recording_in_progress());
  3677. WaitForSeconds(1);
  3678. controller->EndVideoRecording(EndRecordingReason::kStopRecordingButton);
  3679. WaitForCaptureFileToBeSaved();
  3680. histogram_tester.ExpectBucketCount(
  3681. GetCaptureModeHistogramName(kHistogramNameBase), test_case.camera_on,
  3682. 1);
  3683. }
  3684. }
  3685. // A test fixture for testing the rendered video frames. The boolean parameter
  3686. // determines the type of the buffer that backs the video frames. `true` means
  3687. // the `kGpuMemoryBuffer` is used, `false` means the `kSharedMemory` buffer type
  3688. // is used.
  3689. class CaptureModeCameraFramesTest : public CaptureModeCameraTest,
  3690. public testing::WithParamInterface<bool> {
  3691. public:
  3692. CaptureModeCameraFramesTest() {
  3693. // Ensure pixels get drawn since they are verified by tests.
  3694. base::CommandLine::ForCurrentProcess()->AppendSwitch(
  3695. ::switches::kEnablePixelOutputInTests);
  3696. }
  3697. CaptureModeCameraFramesTest(const CaptureModeCameraFramesTest&) = delete;
  3698. CaptureModeCameraFramesTest& operator=(const CaptureModeCameraFramesTest&) =
  3699. delete;
  3700. ~CaptureModeCameraFramesTest() override = default;
  3701. bool ShouldUseGpuMemoryBuffers() const { return GetParam(); }
  3702. // CaptureModeCameraFramesTest:
  3703. void SetUp() override {
  3704. CaptureModeCameraTest::SetUp();
  3705. CaptureModeTestApi test_api;
  3706. test_api.SetForceUseGpuMemoryBufferForCameraFrames(
  3707. ShouldUseGpuMemoryBuffers());
  3708. AddDefaultCamera();
  3709. ASSERT_EQ(1u, test_api.GetNumberOfAvailableCameras());
  3710. test_api.SelectCameraAtIndex(0);
  3711. const CameraId camera_id(kDefaultCameraModelId, 1);
  3712. EXPECT_EQ(camera_id, GetCameraController()->selected_camera());
  3713. }
  3714. void TearDown() override {
  3715. CaptureModeTestApi().SetForceUseGpuMemoryBufferForCameraFrames(false);
  3716. CaptureModeCameraTest::TearDown();
  3717. }
  3718. };
  3719. namespace {
  3720. // Waits for several rendered frames and verifies that the content of the
  3721. // received video frames are the same as that of the produced video frames.
  3722. void WaitForAndVerifyRenderedVideoFrame() {
  3723. // Render a number of frames that are 3 times the size of the buffer pool.
  3724. // This allows us to exercise calls to `OnNewBuffer()` and potentially
  3725. // `OnFrameDropped()`.
  3726. for (size_t i = 0; i < 3 * FakeCameraDevice::kMaxBufferCount; ++i) {
  3727. base::RunLoop loop;
  3728. CaptureModeTestApi().SetOnCameraVideoFrameRendered(
  3729. base::BindLambdaForTesting([&loop](
  3730. scoped_refptr<media::VideoFrame> frame) {
  3731. ASSERT_TRUE(frame);
  3732. const gfx::Size frame_size = frame->visible_rect().size();
  3733. const auto produced_frame_bitmap =
  3734. FakeCameraDevice::GetProducedFrameAsBitmap(frame_size);
  3735. media::PaintCanvasVideoRenderer renderer;
  3736. SkBitmap received_frame_bitmap;
  3737. scoped_refptr<viz::RasterContextProvider> raster_context_provider =
  3738. aura::Env::GetInstance()
  3739. ->context_factory()
  3740. ->SharedMainThreadRasterContextProvider();
  3741. received_frame_bitmap.allocN32Pixels(frame_size.width(),
  3742. frame_size.height());
  3743. cc::SkiaPaintCanvas canvas(received_frame_bitmap);
  3744. renderer.Copy(frame, &canvas, raster_context_provider.get());
  3745. EXPECT_TRUE(gfx::test::AreBitmapsEqual(produced_frame_bitmap,
  3746. received_frame_bitmap));
  3747. loop.Quit();
  3748. }));
  3749. loop.Run();
  3750. }
  3751. }
  3752. } // namespace
  3753. TEST_P(CaptureModeCameraFramesTest, VerifyFrames) {
  3754. CaptureModeTestApi().StartForFullscreen(/*for_video=*/true);
  3755. EXPECT_TRUE(GetCameraController()->camera_preview_widget());
  3756. WaitForAndVerifyRenderedVideoFrame();
  3757. }
  3758. TEST_P(CaptureModeCameraFramesTest, TurnOffCameraWhileRendering) {
  3759. CaptureModeTestApi test_api;
  3760. test_api.StartForFullscreen(/*for_video=*/true);
  3761. auto* camera_controller = GetCameraController();
  3762. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3763. WaitForAndVerifyRenderedVideoFrame();
  3764. test_api.TurnCameraOff();
  3765. EXPECT_FALSE(camera_controller->camera_preview_widget());
  3766. }
  3767. TEST_P(CaptureModeCameraFramesTest, DisconnectCameraWhileRendering) {
  3768. CaptureModeTestApi test_api;
  3769. test_api.StartForFullscreen(/*for_video=*/true);
  3770. auto* camera_controller = GetCameraController();
  3771. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3772. WaitForAndVerifyRenderedVideoFrame();
  3773. RemoveDefaultCamera();
  3774. EXPECT_FALSE(camera_controller->camera_preview_widget());
  3775. }
  3776. TEST_P(CaptureModeCameraFramesTest, SelectAnotherCameraWhileRendering) {
  3777. CaptureModeTestApi test_api;
  3778. test_api.StartForFullscreen(/*for_video=*/true);
  3779. auto* camera_controller = GetCameraController();
  3780. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3781. auto* preview_view = camera_controller->camera_preview_view();
  3782. ASSERT_TRUE(preview_view);
  3783. EXPECT_EQ(preview_view->camera_id(), camera_controller->selected_camera());
  3784. WaitForAndVerifyRenderedVideoFrame();
  3785. // Adding a new camera while rendering an existing one should not affect
  3786. // anything since the new one is not selected yet.
  3787. const std::string device_id = "/dev/video0";
  3788. const std::string display_name = "Integrated Webcam";
  3789. const std::string model_id = "0123:4567";
  3790. AddFakeCamera(device_id, display_name, model_id);
  3791. EXPECT_EQ(preview_view, camera_controller->camera_preview_view());
  3792. // Now select the new camera, a new widget should be created immediately for
  3793. // the new camera.
  3794. const CameraId second_camera_id(model_id, 1);
  3795. camera_controller->SetSelectedCamera(second_camera_id);
  3796. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3797. EXPECT_NE(preview_view, camera_controller->camera_preview_view());
  3798. preview_view = camera_controller->camera_preview_view();
  3799. EXPECT_EQ(preview_view->camera_id(), second_camera_id);
  3800. WaitForAndVerifyRenderedVideoFrame();
  3801. }
  3802. // Regression test for https://crbug.com/1316230.
  3803. TEST_P(CaptureModeCameraFramesTest, CameraFatalErrors) {
  3804. CaptureModeTestApi().StartForFullscreen(/*for_video=*/true);
  3805. auto* camera_controller = GetCameraController();
  3806. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  3807. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3808. WaitForAndVerifyRenderedVideoFrame();
  3809. // When a camera fatal error happens during rendering, we detect that an
  3810. // consider it as a camera disconnection, which will result in the temporary
  3811. // removal of the preview, before it gets re-added again when we refresh the
  3812. // list of cameras.
  3813. auto* video_source_provider = GetTestDelegate()->video_source_provider();
  3814. video_source_provider->TriggerFatalErrorOnCamera(kDefaultCameraDeviceId);
  3815. CameraDevicesChangeWaiter().Wait();
  3816. EXPECT_FALSE(camera_controller->camera_preview_widget());
  3817. EXPECT_TRUE(camera_controller->selected_camera().is_valid());
  3818. // Now wait for the camera to be re-added again.
  3819. CameraDevicesChangeWaiter().Wait();
  3820. EXPECT_TRUE(camera_controller->camera_preview_widget());
  3821. WaitForAndVerifyRenderedVideoFrame();
  3822. }
  3823. INSTANTIATE_TEST_SUITE_P(All, CaptureModeCameraFramesTest, testing::Bool());
  3824. // The test fixture for starting test without active session.
  3825. using NoSessionCaptureModeCameraTest = NoSessionAshTestBase;
  3826. // Tests that camera info is requested after the user logs in instead of on
  3827. // Chrome startup.
  3828. TEST_F(NoSessionCaptureModeCameraTest, RequestCameraInfoAfterUserLogsIn) {
  3829. auto* camera_controller = GetCameraController();
  3830. GetTestDelegate()->video_source_provider()->AddFakeCameraWithoutNotifying(
  3831. "/dev/video0", "Integrated Webcam", "0123:4567",
  3832. media::MEDIA_VIDEO_FACING_NONE);
  3833. // Verify that the camera devices info is not updated yet.
  3834. EXPECT_TRUE(camera_controller->available_cameras().empty());
  3835. // Simulate the user login process and wait for the camera info to be updated.
  3836. {
  3837. base::RunLoop loop;
  3838. GetCameraController()->SetOnCameraListReceivedForTesting(
  3839. loop.QuitClosure());
  3840. SimulateUserLogin("example@gmail.com", user_manager::USER_TYPE_REGULAR);
  3841. loop.Run();
  3842. }
  3843. // Verify that after the user logs in, the camera info is up-to-date.
  3844. EXPECT_EQ(camera_controller->available_cameras().size(), 1u);
  3845. }
  3846. } // namespace ash