1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.car.rotary; 17 18 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 19 import static android.view.accessibility.AccessibilityWindowInfo.UNDEFINED_WINDOW_ID; 20 21 import static org.mockito.Mockito.any; 22 import static org.mockito.Mockito.doAnswer; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.when; 25 26 import android.graphics.Rect; 27 import android.view.Display; 28 import android.view.accessibility.AccessibilityNodeInfo; 29 import android.view.accessibility.AccessibilityWindowInfo; 30 31 import androidx.annotation.Nullable; 32 33 /** 34 * A builder which builds a mock {@link AccessibilityWindowInfo}. Unlike real windows, mock windows 35 * don't need to be recycled. 36 */ 37 class WindowBuilder { 38 /** The ID of the window. */ 39 private int mId = UNDEFINED_WINDOW_ID; 40 /** The root node in the window's hierarchy. */ 41 private AccessibilityNodeInfo mRoot; 42 /** The bounds of this window in the screen. */ 43 private Rect mBoundsInScreen; 44 /** The window type, if specified. */ 45 private int mType; 46 /** Whether the window is focused. */ 47 private boolean mFocused = false; 48 /** The display ID, if specified. */ 49 private int mDisplayId = Display.DEFAULT_DISPLAY; 50 /** The task ID, if specified. */ 51 private int mTaskId = INVALID_TASK_ID; 52 build()53 AccessibilityWindowInfo build() { 54 AccessibilityWindowInfo window = mock(AccessibilityWindowInfo.class); 55 when(window.getId()).thenReturn(mId); 56 when(window.getRoot()) 57 .thenReturn(MockNodeCopierProvider.get().copy(mRoot)) 58 .thenReturn(MockNodeCopierProvider.get().copy(mRoot)) 59 .thenReturn(MockNodeCopierProvider.get().copy(mRoot)) 60 .thenReturn(MockNodeCopierProvider.get().copy(mRoot)) 61 .thenReturn(MockNodeCopierProvider.get().copy(mRoot)) 62 .thenReturn(MockNodeCopierProvider.get().copy(mRoot)) 63 .thenThrow(new RuntimeException( 64 "Exceeded the maximum calls. Please add more parameters")); 65 if (mBoundsInScreen != null) { 66 // Mock AccessibilityWindowInfo#getBoundsInScreen(Rect). 67 doAnswer(invocation -> { 68 Object[] args = invocation.getArguments(); 69 ((Rect) args[0]).set(mBoundsInScreen); 70 return null; 71 }).when(window).getBoundsInScreen(any(Rect.class)); 72 } 73 when(window.getType()).thenReturn(mType); 74 when(window.isFocused()).thenReturn(mFocused); 75 when(window.getDisplayId()).thenReturn(mDisplayId); 76 when(window.getTaskId()).thenReturn(mTaskId); 77 return window; 78 } 79 setId(int id)80 WindowBuilder setId(int id) { 81 mId = id; 82 return this; 83 } 84 setRoot(@ullable AccessibilityNodeInfo root)85 WindowBuilder setRoot(@Nullable AccessibilityNodeInfo root) { 86 mRoot = MockNodeCopierProvider.get().copy(root); 87 return this; 88 } 89 setBoundsInScreen(@ullable Rect boundsInScreen)90 WindowBuilder setBoundsInScreen(@Nullable Rect boundsInScreen) { 91 mBoundsInScreen = boundsInScreen; 92 return this; 93 } 94 setType(int type)95 WindowBuilder setType(int type) { 96 mType = type; 97 return this; 98 } 99 setFocused(boolean isFocused)100 WindowBuilder setFocused(boolean isFocused) { 101 mFocused = isFocused; 102 return this; 103 } 104 setDisplayId(int displayId)105 WindowBuilder setDisplayId(int displayId) { 106 mDisplayId = displayId; 107 return this; 108 } 109 setTaskId(int taskId)110 WindowBuilder setTaskId(int taskId) { 111 mTaskId = taskId; 112 return this; 113 } 114 } 115