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 android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 28 /** 29 * Stores Camera Compat information about a particular Task. 30 * @hide 31 */ 32 public class CameraCompatTaskInfo implements Parcelable { 33 /** 34 * Camera compat control isn't shown because it's not requested by heuristics. 35 */ 36 public static final int CAMERA_COMPAT_CONTROL_HIDDEN = 0; 37 38 /** 39 * Camera compat control is shown with the treatment suggested. 40 */ 41 public static final int CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED = 1; 42 43 /** 44 * Camera compat control is shown to allow reverting the applied treatment. 45 */ 46 public static final int CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED = 2; 47 48 /** 49 * Camera compat control is dismissed by user. 50 */ 51 public static final int CAMERA_COMPAT_CONTROL_DISMISSED = 3; 52 53 /** 54 * Enum for the Camera app compat control states. 55 */ 56 @Retention(RetentionPolicy.SOURCE) 57 @IntDef(prefix = { "CAMERA_COMPAT_CONTROL_" }, value = { 58 CAMERA_COMPAT_CONTROL_HIDDEN, 59 CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED, 60 CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED, 61 CAMERA_COMPAT_CONTROL_DISMISSED, 62 }) 63 public @interface CameraCompatControlState {} 64 65 /** 66 * State of the Camera app compat control which is used to correct stretched viewfinder 67 * in apps that don't handle all possible configurations and changes between them correctly. 68 */ 69 @CameraCompatControlState 70 public int cameraCompatControlState = CAMERA_COMPAT_CONTROL_HIDDEN; 71 72 /** 73 * The value to use when no camera compat treatment should be applied to a windowed task. 74 */ 75 public static final int CAMERA_COMPAT_FREEFORM_NONE = 0; 76 77 /** 78 * The value to use when portrait camera compat treatment should be applied to a windowed task. 79 */ 80 public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT = 1; 81 82 /** 83 * The value to use when landscape camera compat treatment should be applied to a windowed task. 84 */ 85 public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE = 2; 86 87 @Retention(RetentionPolicy.SOURCE) 88 @IntDef(prefix = { "CAMERA_COMPAT_FREEFORM_" }, value = { 89 CAMERA_COMPAT_FREEFORM_NONE, 90 CAMERA_COMPAT_FREEFORM_PORTRAIT, 91 CAMERA_COMPAT_FREEFORM_LANDSCAPE, 92 }) 93 public @interface FreeformCameraCompatMode {} 94 95 /** 96 * Whether the camera activity is letterboxed in freeform windowing mode to emulate expected 97 * aspect ratio for fixed-orientation apps. 98 * 99 * <p>This field is used by the WM and the camera framework, to coordinate camera compat mode 100 * setup. 101 */ 102 @FreeformCameraCompatMode 103 public int freeformCameraCompatMode; 104 CameraCompatTaskInfo()105 private CameraCompatTaskInfo() { 106 // Do nothing 107 } 108 109 @NonNull create()110 static CameraCompatTaskInfo create() { 111 return new CameraCompatTaskInfo(); 112 } 113 CameraCompatTaskInfo(Parcel source)114 private CameraCompatTaskInfo(Parcel source) { 115 readFromParcel(source); 116 } 117 118 @Override describeContents()119 public int describeContents() { 120 return 0; 121 } 122 123 public static final Creator<CameraCompatTaskInfo> CREATOR = 124 new Creator<>() { 125 @Override 126 public CameraCompatTaskInfo createFromParcel(Parcel in) { 127 return new CameraCompatTaskInfo(in); 128 } 129 130 @Override 131 public CameraCompatTaskInfo[] newArray(int size) { 132 return new CameraCompatTaskInfo[size]; 133 } 134 }; 135 136 /** 137 * Reads the CameraCompatTaskInfo from a parcel. 138 */ readFromParcel(Parcel source)139 void readFromParcel(Parcel source) { 140 cameraCompatControlState = source.readInt(); 141 freeformCameraCompatMode = source.readInt(); 142 } 143 144 /** 145 * Writes the CameraCompatTaskInfo to a parcel. 146 */ 147 @Override writeToParcel(Parcel dest, int flags)148 public void writeToParcel(Parcel dest, int flags) { 149 dest.writeInt(cameraCompatControlState); 150 dest.writeInt(freeformCameraCompatMode); 151 } 152 153 /** 154 * @return {@value true} if the task has camera compat controls. 155 */ hasCameraCompatControl()156 public boolean hasCameraCompatControl() { 157 return cameraCompatControlState != CAMERA_COMPAT_CONTROL_HIDDEN 158 && cameraCompatControlState != CAMERA_COMPAT_CONTROL_DISMISSED; 159 } 160 161 /** 162 * @return {@value true} if the task has some compat ui. 163 */ hasCameraCompatUI()164 public boolean hasCameraCompatUI() { 165 return hasCameraCompatControl(); 166 } 167 168 /** 169 * @return {@code true} if the camera compat parameters that are important for task organizers 170 * are equal. 171 */ equalsForTaskOrganizer(@ullable CameraCompatTaskInfo that)172 public boolean equalsForTaskOrganizer(@Nullable CameraCompatTaskInfo that) { 173 if (that == null) { 174 return false; 175 } 176 return freeformCameraCompatMode == that.freeformCameraCompatMode; 177 } 178 179 /** 180 * @return {@code true} if parameters that are important for size compat have changed. 181 */ equalsForCompatUi(@ullable CameraCompatTaskInfo that)182 public boolean equalsForCompatUi(@Nullable CameraCompatTaskInfo that) { 183 if (that == null) { 184 return false; 185 } 186 return cameraCompatControlState == that.cameraCompatControlState 187 && freeformCameraCompatMode == that.freeformCameraCompatMode; 188 } 189 190 @Override toString()191 public String toString() { 192 return "CameraCompatTaskInfo { cameraCompatControlState=" 193 + cameraCompatControlStateToString(cameraCompatControlState) 194 + " freeformCameraCompatMode=" 195 + freeformCameraCompatModeToString(freeformCameraCompatMode) 196 + "}"; 197 } 198 199 /** Human readable version of the camera control state. */ 200 @NonNull cameraCompatControlStateToString( @ameraCompatControlState int cameraCompatControlState)201 public static String cameraCompatControlStateToString( 202 @CameraCompatControlState int cameraCompatControlState) { 203 return switch (cameraCompatControlState) { 204 case CAMERA_COMPAT_CONTROL_HIDDEN -> "hidden"; 205 case CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED -> "treatment-suggested"; 206 case CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED -> "treatment-applied"; 207 case CAMERA_COMPAT_CONTROL_DISMISSED -> "dismissed"; 208 default -> throw new AssertionError( 209 "Unexpected camera compat control state: " + cameraCompatControlState); 210 }; 211 } 212 213 /** Human readable version of the freeform camera compat mode. */ 214 @NonNull freeformCameraCompatModeToString( @reeformCameraCompatMode int freeformCameraCompatMode)215 public static String freeformCameraCompatModeToString( 216 @FreeformCameraCompatMode int freeformCameraCompatMode) { 217 return switch (freeformCameraCompatMode) { 218 case CAMERA_COMPAT_FREEFORM_NONE -> "inactive"; 219 case CAMERA_COMPAT_FREEFORM_PORTRAIT -> "portrait"; 220 case CAMERA_COMPAT_FREEFORM_LANDSCAPE -> "landscape"; 221 default -> throw new AssertionError( 222 "Unexpected camera compat mode: " + freeformCameraCompatMode); 223 }; 224 } 225 } 226