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 17 package android.server.wm.jetpack.utils; 18 19 import static android.server.wm.jetpack.extensions.util.SidecarUtil.getSidecarInterface; 20 import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.getActivityWindowToken; 21 import static com.google.common.truth.Truth.assertThat; 22 import static org.junit.Assert.assertEquals; 23 24 import android.os.Bundle; 25 import android.os.IBinder; 26 import android.view.View; 27 28 import androidx.annotation.NonNull; 29 import androidx.annotation.Nullable; 30 import androidx.window.sidecar.SidecarDisplayFeature; 31 import androidx.window.sidecar.SidecarInterface; 32 import androidx.window.sidecar.SidecarWindowLayoutInfo; 33 34 import java.util.HashSet; 35 import java.util.Set; 36 import java.util.stream.Collectors; 37 38 /** 39 * Activity that can verify the return value of 40 * {@link SidecarInterface#getWindowLayoutInfo(IBinder)} on activity's different states. 41 */ 42 // TODO (b/201119421) - explore moving the assert logic out from here and into the calling test 43 public class TestGetWindowLayoutInfoActivity extends TestActivity { 44 45 private SidecarInterface mSidecarInterface; 46 @Nullable private SidecarWindowLayoutInfo mPrevWindowLayoutInfo; 47 48 @Override onCreate(@ullable Bundle savedInstanceState)49 public void onCreate(@Nullable Bundle savedInstanceState) { 50 super.onCreate(savedInstanceState); 51 mSidecarInterface = getSidecarInterface(this); 52 assertCorrectWindowLayoutInfoOrException(true /* isOkToThrowException */); 53 } 54 55 @Override onAttachedToWindow()56 public void onAttachedToWindow() { 57 super.onAttachedToWindow(); 58 assertCorrectWindowLayoutInfoOrException(true /* isOkToThrowException */); 59 } 60 61 @Override onResume()62 protected void onResume() { 63 super.onResume(); 64 assertCorrectWindowLayoutInfoOrException(true /* isOkToThrowException */); 65 } 66 67 @Override onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)68 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, 69 int oldTop, int oldRight, int oldBottom) { 70 super.onLayoutChange(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom); 71 assertCorrectWindowLayoutInfoOrException(false /* isOkToThrowException */); 72 } 73 74 @Override onDestroy()75 public void onDestroy() { 76 super.onDestroy(); 77 } 78 assertCorrectWindowLayoutInfoOrException(boolean isOkToThrowException)79 private void assertCorrectWindowLayoutInfoOrException(boolean isOkToThrowException) { 80 IBinder windowToken = getActivityWindowToken(this); 81 if (windowToken == null) { 82 return; 83 } 84 85 SidecarWindowLayoutInfo windowLayoutInfo = null; 86 try { 87 windowLayoutInfo = mSidecarInterface.getWindowLayoutInfo(windowToken); 88 } catch (Exception e) { 89 assertThat(isOkToThrowException).isTrue(); 90 } 91 92 if (mPrevWindowLayoutInfo == null) { 93 mPrevWindowLayoutInfo = windowLayoutInfo; 94 } else { 95 assertEqualWindowLayoutInfo(mPrevWindowLayoutInfo, windowLayoutInfo); 96 } 97 } 98 99 private static class SidecarDisplayFeatureComparisonWrapper { 100 101 private SidecarDisplayFeature mFeature; 102 SidecarDisplayFeatureComparisonWrapper( @onNull SidecarDisplayFeature feature)103 private SidecarDisplayFeatureComparisonWrapper( 104 @NonNull SidecarDisplayFeature feature) { 105 mFeature = feature; 106 } 107 create( @onNull SidecarDisplayFeature feature)108 public static SidecarDisplayFeatureComparisonWrapper create( 109 @NonNull SidecarDisplayFeature feature) { 110 return new SidecarDisplayFeatureComparisonWrapper(feature); 111 } 112 113 @Override equals(Object o)114 public boolean equals(Object o) { 115 if (o == this) { 116 return true; 117 } 118 if (!(o instanceof SidecarDisplayFeatureComparisonWrapper)) { 119 return false; 120 } 121 SidecarDisplayFeatureComparisonWrapper other 122 = (SidecarDisplayFeatureComparisonWrapper) o; 123 return mFeature.getRect().equals(other.mFeature.getRect()) 124 && mFeature.getType() == other.mFeature.getType(); 125 } 126 127 @Override hashCode()128 public final int hashCode() { 129 int result = mFeature.getRect().hashCode(); 130 result = 31 * result + mFeature.getType(); 131 return result; 132 } 133 } 134 assertEqualWindowLayoutInfo(SidecarWindowLayoutInfo info1, SidecarWindowLayoutInfo info2)135 private void assertEqualWindowLayoutInfo(SidecarWindowLayoutInfo info1, 136 SidecarWindowLayoutInfo info2) { 137 // If neither has any display features, then they are equal 138 if (info1.displayFeatures == null && info2.displayFeatures == null) { 139 return; 140 } 141 // Convert display features into comparable display features 142 Set<SidecarDisplayFeatureComparisonWrapper> displayFeatures1 = collectDisplayFeatures( 143 info1); 144 Set<SidecarDisplayFeatureComparisonWrapper> displayFeatures2 = collectDisplayFeatures( 145 info2); 146 assertEquals(displayFeatures1, displayFeatures2); 147 } 148 collectDisplayFeatures( @onNull SidecarWindowLayoutInfo info)149 private Set<SidecarDisplayFeatureComparisonWrapper> collectDisplayFeatures( 150 @NonNull SidecarWindowLayoutInfo info) { 151 if (info.displayFeatures == null) { 152 return new HashSet<SidecarDisplayFeatureComparisonWrapper>(); 153 } 154 return info.displayFeatures 155 .stream() 156 .map(SidecarDisplayFeatureComparisonWrapper::create) 157 .collect(Collectors.toSet()); 158 } 159 } 160