1 /* 2 * Copyright (C) 2024 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 androidx.window.sidecar; 17 18 import static android.view.Display.DEFAULT_DISPLAY; 19 20 import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation; 21 import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect; 22 23 import android.annotation.NonNull; 24 import android.app.Activity; 25 import android.app.ActivityThread; 26 import android.graphics.Rect; 27 import android.os.IBinder; 28 29 import androidx.window.common.CommonFoldingFeature; 30 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.List; 34 35 /** 36 * A utility class for transforming between Sidecar and Extensions features. 37 */ 38 class SidecarHelper { 39 SidecarHelper()40 private SidecarHelper() {} 41 42 /** 43 * Returns the {@link SidecarDeviceState} posture that is calculated for the first fold in 44 * the feature list. Sidecar devices only have one fold so we only pick the first one to 45 * determine the state. 46 * @param featureList the {@link CommonFoldingFeature} that are currently active. 47 * @return the {@link SidecarDeviceState} calculated from the {@link List} of 48 * {@link CommonFoldingFeature}. 49 */ 50 @SuppressWarnings("deprecation") deviceStateFromFeatureList(@onNull List<CommonFoldingFeature> featureList)51 private static int deviceStateFromFeatureList(@NonNull List<CommonFoldingFeature> featureList) { 52 for (int i = 0; i < featureList.size(); i++) { 53 final CommonFoldingFeature feature = featureList.get(i); 54 final int state = feature.getState(); 55 switch (state) { 56 case CommonFoldingFeature.COMMON_STATE_FLAT: 57 return SidecarDeviceState.POSTURE_OPENED; 58 case CommonFoldingFeature.COMMON_STATE_HALF_OPENED: 59 return SidecarDeviceState.POSTURE_HALF_OPENED; 60 case CommonFoldingFeature.COMMON_STATE_UNKNOWN: 61 return SidecarDeviceState.POSTURE_UNKNOWN; 62 case CommonFoldingFeature.COMMON_STATE_NO_FOLDING_FEATURES: 63 return SidecarDeviceState.POSTURE_UNKNOWN; 64 case CommonFoldingFeature.COMMON_STATE_USE_BASE_STATE: 65 return SidecarDeviceState.POSTURE_UNKNOWN; 66 } 67 } 68 return SidecarDeviceState.POSTURE_UNKNOWN; 69 } 70 71 /** 72 * Returns a {@link SidecarDeviceState} calculated from a {@link List} of 73 * {@link CommonFoldingFeature}s. 74 */ 75 @SuppressWarnings("deprecation") calculateDeviceState( @onNull List<CommonFoldingFeature> featureList)76 static SidecarDeviceState calculateDeviceState( 77 @NonNull List<CommonFoldingFeature> featureList) { 78 final SidecarDeviceState deviceState = new SidecarDeviceState(); 79 deviceState.posture = deviceStateFromFeatureList(featureList); 80 return deviceState; 81 } 82 83 @SuppressWarnings("deprecation") calculateDisplayFeatures( @onNull Activity activity, @NonNull List<CommonFoldingFeature> featureList )84 private static List<SidecarDisplayFeature> calculateDisplayFeatures( 85 @NonNull Activity activity, 86 @NonNull List<CommonFoldingFeature> featureList 87 ) { 88 final int displayId = activity.getDisplay().getDisplayId(); 89 if (displayId != DEFAULT_DISPLAY) { 90 return Collections.emptyList(); 91 } 92 93 if (activity.isInMultiWindowMode()) { 94 // It is recommended not to report any display features in multi-window mode, since it 95 // won't be possible to synchronize the display feature positions with window movement. 96 return Collections.emptyList(); 97 } 98 99 final List<SidecarDisplayFeature> features = new ArrayList<>(); 100 final int rotation = activity.getResources().getConfiguration().windowConfiguration 101 .getDisplayRotation(); 102 for (CommonFoldingFeature baseFeature : featureList) { 103 final SidecarDisplayFeature feature = new SidecarDisplayFeature(); 104 final Rect featureRect = baseFeature.getRect(); 105 rotateRectToDisplayRotation(displayId, rotation, featureRect); 106 transformToWindowSpaceRect(activity, featureRect); 107 feature.setRect(featureRect); 108 feature.setType(baseFeature.getType()); 109 features.add(feature); 110 } 111 return Collections.unmodifiableList(features); 112 } 113 114 /** 115 * Returns a {@link SidecarWindowLayoutInfo} calculated from the {@link List} of 116 * {@link CommonFoldingFeature}. 117 */ 118 @SuppressWarnings("deprecation") calculateWindowLayoutInfo(@onNull IBinder windowToken, @NonNull List<CommonFoldingFeature> featureList)119 static SidecarWindowLayoutInfo calculateWindowLayoutInfo(@NonNull IBinder windowToken, 120 @NonNull List<CommonFoldingFeature> featureList) { 121 final Activity activity = ActivityThread.currentActivityThread().getActivity(windowToken); 122 final SidecarWindowLayoutInfo windowLayoutInfo = new SidecarWindowLayoutInfo(); 123 if (activity == null) { 124 return windowLayoutInfo; 125 } 126 windowLayoutInfo.displayFeatures = calculateDisplayFeatures(activity, featureList); 127 return windowLayoutInfo; 128 } 129 } 130