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