• 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 
17 package android.app;
18 
19 import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
20 import static android.view.Surface.ROTATION_0;
21 import static android.view.Surface.ROTATION_90;
22 
23 import android.annotation.IntDef;
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 import android.view.Surface;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 
33 /**
34  * Stores Camera Compat information about a particular Task.
35  * @hide
36  */
37 public class CameraCompatTaskInfo implements Parcelable {
38     /**
39      * Undefined camera compat mode.
40      */
41     public static final int CAMERA_COMPAT_FREEFORM_UNSPECIFIED = 0;
42 
43     /**
44      * The value to use when no camera compat treatment should be applied to a windowed task.
45      */
46     public static final int CAMERA_COMPAT_FREEFORM_NONE = 1;
47 
48     /**
49      * The value to use when camera compat treatment should be applied to an activity requesting
50      * portrait orientation, while a device is in landscape. Applies only to freeform tasks.
51      */
52     public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE = 2;
53 
54     /**
55      * The value to use when camera compat treatment should be applied to an activity requesting
56      * landscape orientation, while a device is in landscape. Applies only to freeform tasks.
57      */
58     public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE = 3;
59 
60     /**
61      * The value to use when camera compat treatment should be applied to an activity requesting
62      * portrait orientation, while a device is in portrait. Applies only to freeform tasks.
63      */
64     public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT = 4;
65 
66     /**
67      * The value to use when camera compat treatment should be applied to an activity requesting
68      * landscape orientation, while a device is in portrait. Applies only to freeform tasks.
69      */
70     public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT = 5;
71 
72     @Retention(RetentionPolicy.SOURCE)
73     @IntDef(prefix = { "CAMERA_COMPAT_FREEFORM_" }, value = {
74             CAMERA_COMPAT_FREEFORM_UNSPECIFIED,
75             CAMERA_COMPAT_FREEFORM_NONE,
76             CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE,
77             CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE,
78             CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT,
79             CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT,
80     })
81     public @interface FreeformCameraCompatMode {}
82 
83     /**
84      * Whether the camera activity is letterboxed in freeform windowing mode to emulate expected
85      * aspect ratio for fixed-orientation apps.
86      *
87      * <p>This field is used by the WM and the camera framework, to coordinate camera compat mode
88      * setup.
89      */
90     @FreeformCameraCompatMode
91     public int freeformCameraCompatMode;
92 
CameraCompatTaskInfo()93     private CameraCompatTaskInfo() {
94         // Do nothing
95     }
96 
97     @NonNull
create()98     static CameraCompatTaskInfo create() {
99         return new CameraCompatTaskInfo();
100     }
101 
CameraCompatTaskInfo(Parcel source)102     private CameraCompatTaskInfo(Parcel source) {
103         readFromParcel(source);
104     }
105 
106     @Override
describeContents()107     public int describeContents() {
108         return 0;
109     }
110 
111     public static final Creator<CameraCompatTaskInfo> CREATOR =
112             new Creator<>() {
113                 @Override
114                 public CameraCompatTaskInfo createFromParcel(Parcel in) {
115                     return new CameraCompatTaskInfo(in);
116                 }
117 
118                 @Override
119                 public CameraCompatTaskInfo[] newArray(int size) {
120                     return new CameraCompatTaskInfo[size];
121                 }
122             };
123 
124     /**
125      * Reads the CameraCompatTaskInfo from a parcel.
126      */
readFromParcel(Parcel source)127     void readFromParcel(Parcel source) {
128         freeformCameraCompatMode = source.readInt();
129     }
130 
131     /**
132      * Writes the CameraCompatTaskInfo to a parcel.
133      */
134     @Override
writeToParcel(Parcel dest, int flags)135     public void writeToParcel(Parcel dest, int flags) {
136         dest.writeInt(freeformCameraCompatMode);
137     }
138 
139     /**
140      * @return  {@code true} if the camera compat parameters that are important for task organizers
141      * are equal.
142      */
equalsForTaskOrganizer(@ullable CameraCompatTaskInfo that)143     public boolean equalsForTaskOrganizer(@Nullable CameraCompatTaskInfo that) {
144         if (that == null) {
145             return false;
146         }
147         return freeformCameraCompatMode == that.freeformCameraCompatMode;
148     }
149 
150     /**
151      * @return {@code true} if parameters that are important for size compat have changed.
152      */
equalsForCompatUi(@ullable CameraCompatTaskInfo that)153     public boolean equalsForCompatUi(@Nullable CameraCompatTaskInfo that) {
154         if (that == null) {
155             return false;
156         }
157         return freeformCameraCompatMode == that.freeformCameraCompatMode;
158     }
159 
160     @Override
toString()161     public String toString() {
162         return "CameraCompatTaskInfo { freeformCameraCompatMode="
163                 + freeformCameraCompatModeToString(freeformCameraCompatMode)
164                 + "}";
165     }
166 
167     /**
168      * Returns the sandboxed display rotation based on the given {@code cameraCompatMode}.
169      *
170      * <p>This will be what the app likely expects in its requested orientation while running on a
171      * device with portrait natural orientation: `CAMERA_COMPAT_FREEFORM_PORTRAIT_*` is 0, and
172      * `CAMERA_COMPAT_FREEFORM_LANDSCAPE_*` is 90.
173      *
174      * @return {@link WindowConfiguration#ROTATION_UNDEFINED} if not in camera compat mode.
175      */
176     @Surface.Rotation
getDisplayRotationFromCameraCompatMode(@reeformCameraCompatMode int cameraCompatMode)177     public static int getDisplayRotationFromCameraCompatMode(@FreeformCameraCompatMode int
178             cameraCompatMode) {
179         return switch (cameraCompatMode) {
180             case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE,
181                  CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT -> ROTATION_0;
182             case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE,
183                  CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT -> ROTATION_90;
184             default -> ROTATION_UNDEFINED;
185         };
186     }
187 
188     /** Human readable version of the freeform camera compat mode. */
189     @NonNull
freeformCameraCompatModeToString( @reeformCameraCompatMode int freeformCameraCompatMode)190     public static String freeformCameraCompatModeToString(
191             @FreeformCameraCompatMode int freeformCameraCompatMode) {
192         return switch (freeformCameraCompatMode) {
193             case CAMERA_COMPAT_FREEFORM_UNSPECIFIED -> "undefined";
194             case CAMERA_COMPAT_FREEFORM_NONE -> "inactive";
195             case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE ->
196                     "app-portrait-device-landscape";
197             case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE ->
198                     "app-landscape-device-landscape";
199             case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT ->
200                     "app-portrait-device-portrait";
201             case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT ->
202                     "app-landscape-device-portrait";
203             default -> throw new AssertionError(
204                     "Unexpected camera compat mode: " + freeformCameraCompatMode);
205         };
206     }
207 }
208