1 /* 2 * Copyright (C) 2022 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.wallpapereffectsgeneration; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Objects; 31 32 /** 33 * A {@link CinematicEffectResponse} include textured meshes 34 * and camera attributes of key frames. 35 * 36 * @hide 37 */ 38 @SystemApi 39 public final class CinematicEffectResponse implements Parcelable { 40 /** @hide */ 41 @IntDef(prefix = {"CINEMATIC_EFFECT_STATUS_"}, 42 value = {CINEMATIC_EFFECT_STATUS_ERROR, 43 CINEMATIC_EFFECT_STATUS_OK, 44 CINEMATIC_EFFECT_STATUS_NOT_READY, 45 CINEMATIC_EFFECT_STATUS_PENDING, 46 CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS, 47 CINEMATIC_EFFECT_STATUS_FEATURE_DISABLED, 48 CINEMATIC_EFFECT_STATUS_IMAGE_FORMAT_NOT_SUITABLE, 49 CINEMATIC_EFFECT_STATUS_CONTENT_UNSUPPORTED, 50 CINEMATIC_EFFECT_STATUS_CONTENT_TARGET_ERROR, 51 CINEMATIC_EFFECT_STATUS_CONTENT_TOO_FLAT, 52 CINEMATIC_EFFECT_STATUS_ANIMATION_FAILURE 53 }) 54 @Retention(RetentionPolicy.SOURCE) 55 public @interface CinematicEffectStatusCode {} 56 57 /** Cinematic effect generation failure with generic error. */ 58 public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0; 59 60 /** Cinematic effect generation success. */ 61 public static final int CINEMATIC_EFFECT_STATUS_OK = 1; 62 63 /** 64 * Service not ready for cinematic effect generation, e.g. a 65 * dependency is unavailable. 66 */ 67 public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2; 68 69 /** 70 * There is already a task being processed for the same task id. 71 * Client should wait for the response and not send the same request 72 * again. 73 */ 74 public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3; 75 76 /** Too many requests (with different task id) for server to handle. */ 77 public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4; 78 79 /** Feature is disabled, for example, in an emergency situation. */ 80 public static final int CINEMATIC_EFFECT_STATUS_FEATURE_DISABLED = 5; 81 82 /** Image format related problems (i.e. resolution or aspect ratio problems). */ 83 public static final int CINEMATIC_EFFECT_STATUS_IMAGE_FORMAT_NOT_SUITABLE = 6; 84 85 /** 86 * The cinematic effect feature is not supported on certain types of images, 87 * for example, some implementation only support portrait. 88 */ 89 public static final int CINEMATIC_EFFECT_STATUS_CONTENT_UNSUPPORTED = 7; 90 91 /** 92 * Cannot generate cinematic effect with the targets on the image, for example, 93 * too many targets on the image. 94 */ 95 public static final int CINEMATIC_EFFECT_STATUS_CONTENT_TARGET_ERROR = 8; 96 97 /** Image is too flat to generate cinematic effect. */ 98 public static final int CINEMATIC_EFFECT_STATUS_CONTENT_TOO_FLAT = 9; 99 100 /** Something is wrong with generating animation. */ 101 public static final int CINEMATIC_EFFECT_STATUS_ANIMATION_FAILURE = 10; 102 103 /** @hide */ 104 @IntDef(prefix = {"IMAGE_CONTENT_TYPE_"}, 105 value = {IMAGE_CONTENT_TYPE_UNKNOWN, 106 IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT, 107 IMAGE_CONTENT_TYPE_LANDSCAPE, 108 IMAGE_CONTENT_TYPE_OTHER 109 }) 110 @Retention(RetentionPolicy.SOURCE) 111 public @interface ImageContentType {} 112 113 /** Unable to determine image type. */ 114 public static final int IMAGE_CONTENT_TYPE_UNKNOWN = 0; 115 /** Image content is people portrait. */ 116 public static final int IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT = 1; 117 /** Image content is landscape. */ 118 public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2; 119 /** Image content is not people portrait or landscape. */ 120 public static final int IMAGE_CONTENT_TYPE_OTHER = 3; 121 122 123 @CinematicEffectStatusCode 124 private int mStatusCode; 125 126 /** The id of the cinematic effect generation task. */ 127 @NonNull 128 private String mTaskId; 129 130 @ImageContentType 131 private int mImageContentType; 132 133 /** The textured mesh required to render cinematic effect. */ 134 @NonNull 135 private List<TexturedMesh> mTexturedMeshes; 136 137 /** The start camera position for animation. */ 138 @Nullable 139 private CameraAttributes mStartKeyFrame; 140 141 /** The end camera position for animation. */ 142 @Nullable 143 private CameraAttributes mEndKeyFrame; 144 CinematicEffectResponse(Parcel in)145 private CinematicEffectResponse(Parcel in) { 146 mStatusCode = in.readInt(); 147 mTaskId = in.readString(); 148 mImageContentType = in.readInt(); 149 mTexturedMeshes = new ArrayList<TexturedMesh>(); 150 in.readTypedList(mTexturedMeshes, TexturedMesh.CREATOR); 151 mStartKeyFrame = in.readTypedObject(CameraAttributes.CREATOR); 152 mEndKeyFrame = in.readTypedObject(CameraAttributes.CREATOR); 153 } 154 CinematicEffectResponse(@inematicEffectStatusCode int statusCode, String taskId, @ImageContentType int imageContentType, List<TexturedMesh> texturedMeshes, CameraAttributes startKeyFrame, CameraAttributes endKeyFrame)155 private CinematicEffectResponse(@CinematicEffectStatusCode int statusCode, 156 String taskId, 157 @ImageContentType int imageContentType, 158 List<TexturedMesh> texturedMeshes, 159 CameraAttributes startKeyFrame, 160 CameraAttributes endKeyFrame) { 161 mStatusCode = statusCode; 162 mTaskId = taskId; 163 mImageContentType = imageContentType; 164 mStartKeyFrame = startKeyFrame; 165 mEndKeyFrame = endKeyFrame; 166 mTexturedMeshes = texturedMeshes; 167 } 168 169 /** Gets the cinematic effect generation status code. */ 170 @CinematicEffectStatusCode getStatusCode()171 public int getStatusCode() { 172 return mStatusCode; 173 } 174 175 /** Get the task id. */ 176 @NonNull getTaskId()177 public String getTaskId() { 178 return mTaskId; 179 } 180 181 /** 182 * Get the image content type, which briefly classifies what's 183 * the content of image, like people portrait, landscape etc. 184 */ 185 @ImageContentType getImageContentType()186 public int getImageContentType() { 187 return mImageContentType; 188 } 189 190 /** Get the textured meshes. */ 191 @NonNull getTexturedMeshes()192 public List<TexturedMesh> getTexturedMeshes() { 193 return mTexturedMeshes; 194 } 195 196 /** 197 * Get the camera attributes (position info and other parameters, see docs of 198 * {@link CameraAttributes}) of the start key frame on the animation path. 199 */ 200 @Nullable getStartKeyFrame()201 public CameraAttributes getStartKeyFrame() { 202 return mStartKeyFrame; 203 } 204 205 /** 206 * Get the camera attributes (position info and other parameters, see docs of 207 * {@link CameraAttributes}) of the end key frame on the animation path. 208 */ 209 @Nullable getEndKeyFrame()210 public CameraAttributes getEndKeyFrame() { 211 return mEndKeyFrame; 212 } 213 214 @NonNull 215 public static final Creator<CinematicEffectResponse> CREATOR = 216 new Creator<CinematicEffectResponse>() { 217 @Override 218 public CinematicEffectResponse createFromParcel(Parcel in) { 219 return new CinematicEffectResponse(in); 220 } 221 222 @Override 223 public CinematicEffectResponse[] newArray(int size) { 224 return new CinematicEffectResponse[size]; 225 } 226 }; 227 228 @Override describeContents()229 public int describeContents() { 230 return 0; 231 } 232 233 @Override writeToParcel(@onNull Parcel out, int flags)234 public void writeToParcel(@NonNull Parcel out, int flags) { 235 out.writeInt(mStatusCode); 236 out.writeString(mTaskId); 237 out.writeInt(mImageContentType); 238 out.writeTypedList(mTexturedMeshes, flags); 239 out.writeTypedObject(mStartKeyFrame, flags); 240 out.writeTypedObject(mEndKeyFrame, flags); 241 } 242 243 @Override equals(Object o)244 public boolean equals(Object o) { 245 if (this == o) return true; 246 if (o == null || getClass() != o.getClass()) { 247 return false; 248 } 249 CinematicEffectResponse that = (CinematicEffectResponse) o; 250 return mTaskId.equals(that.mTaskId); 251 } 252 253 @Override hashCode()254 public int hashCode() { 255 return Objects.hash(mTaskId); 256 } 257 /** 258 * Builder of {@link CinematicEffectResponse} 259 * 260 * @hide 261 */ 262 @SystemApi 263 public static final class Builder { 264 @CinematicEffectStatusCode 265 private int mStatusCode; 266 @NonNull 267 private String mTaskId; 268 @ImageContentType 269 private int mImageContentType; 270 @NonNull 271 private List<TexturedMesh> mTexturedMeshes; 272 @Nullable 273 private CameraAttributes mStartKeyFrame; 274 @Nullable 275 private CameraAttributes mEndKeyFrame; 276 277 /** 278 * Constructor with task id and status code. 279 * 280 * @hide 281 */ 282 @SystemApi Builder(@inematicEffectStatusCode int statusCode, @NonNull String taskId)283 public Builder(@CinematicEffectStatusCode int statusCode, @NonNull String taskId) { 284 mStatusCode = statusCode; 285 mTaskId = taskId; 286 } 287 288 /** 289 * Sets the image content type. 290 */ 291 @NonNull setImageContentType(@mageContentType int imageContentType)292 public Builder setImageContentType(@ImageContentType int imageContentType) { 293 mImageContentType = imageContentType; 294 return this; 295 } 296 297 298 /** 299 * Sets the textured meshes. 300 */ 301 @NonNull setTexturedMeshes(@onNull List<TexturedMesh> texturedMeshes)302 public Builder setTexturedMeshes(@NonNull List<TexturedMesh> texturedMeshes) { 303 mTexturedMeshes = texturedMeshes; 304 return this; 305 } 306 307 /** 308 * Sets start key frame. 309 */ 310 @NonNull setStartKeyFrame(@ullable CameraAttributes startKeyFrame)311 public Builder setStartKeyFrame(@Nullable CameraAttributes startKeyFrame) { 312 mStartKeyFrame = startKeyFrame; 313 return this; 314 } 315 316 /** 317 * Sets end key frame. 318 */ 319 @NonNull setEndKeyFrame(@ullable CameraAttributes endKeyFrame)320 public Builder setEndKeyFrame(@Nullable CameraAttributes endKeyFrame) { 321 mEndKeyFrame = endKeyFrame; 322 return this; 323 } 324 325 /** 326 * Builds a {@link CinematicEffectResponse} instance. 327 */ 328 @NonNull build()329 public CinematicEffectResponse build() { 330 if (mTexturedMeshes == null) { 331 // Place holder because build doesn't allow list to be nullable. 332 mTexturedMeshes = new ArrayList<>(0); 333 } 334 return new CinematicEffectResponse(mStatusCode, mTaskId, mImageContentType, 335 mTexturedMeshes, mStartKeyFrame, mEndKeyFrame); 336 } 337 } 338 } 339