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