diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e5e13a8a1fbc..1b626d411c8e 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2636,18 +2636,18 @@ package android.app.wallpapereffectsgeneration { method public int describeContents(); method @NonNull public float[] getAnchorPointInOutputUvSpace(); method @NonNull public float[] getAnchorPointInWorldSpace(); - method public float getCameraOrbitPitchDegrees(); - method public float getCameraOrbitYawDegrees(); + method @FloatRange(from=-90.0F, to=90.0f) public float getCameraOrbitPitchDegrees(); + method @FloatRange(from=-180.0F, to=180.0f) public float getCameraOrbitYawDegrees(); method public float getDollyDistanceInWorldSpace(); - method public float getFrustumFarInWorldSpace(); - method public float getFrustumNearInWorldSpace(); - method public float getVerticalFovDegrees(); + method @FloatRange(from=0.0f) public float getFrustumFarInWorldSpace(); + method @FloatRange(from=0.0f) public float getFrustumNearInWorldSpace(); + method @FloatRange(from=0.0f, to=180.0f, fromInclusive=false) public float getVerticalFovDegrees(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } public static final class CameraAttributes.Builder { - ctor public CameraAttributes.Builder(@NonNull float[], @NonNull float[]); + ctor public CameraAttributes.Builder(@NonNull @Size(3) float[], @NonNull @Size(2) float[]); method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes build(); method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setCameraOrbitPitchDegrees(@FloatRange(from=-90.0F, to=90.0f) float); method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setCameraOrbitYawDegrees(@FloatRange(from=-180.0F, to=180.0f) float); @@ -2675,12 +2675,11 @@ package android.app.wallpapereffectsgeneration { method @NonNull public String getTaskId(); method @NonNull public java.util.List getTexturedMeshes(); method public void writeToParcel(@NonNull android.os.Parcel, int); - field public static final int CINEMATIC_EFFECT_STATUS_ERROR = 2; // 0x2 - field public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 3; // 0x3 + field public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0; // 0x0 + field public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2; // 0x2 field public static final int CINEMATIC_EFFECT_STATUS_OK = 1; // 0x1 - field public static final int CINEMATIC_EFFECT_STATUS_PENDING = 4; // 0x4 - field public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 5; // 0x5 - field public static final int CINEMATIC_EFFECT_STATUS_UNKNOWN = 0; // 0x0 + field public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3; // 0x3 + field public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4; // 0x4 field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2; // 0x2 field public static final int IMAGE_CONTENT_TYPE_OTHER = 3; // 0x3 @@ -12041,8 +12040,9 @@ package android.service.wallpapereffectsgeneration { public abstract class WallpaperEffectsGenerationService extends android.app.Service { ctor public WallpaperEffectsGenerationService(); method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); - method public abstract void onGenerateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest); + method @MainThread public abstract void onGenerateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest); method public final void returnCinematicEffectResponse(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectResponse); + field public static final String SERVICE_INTERFACE = "android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService"; } } diff --git a/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java b/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java index dfbc7a4c3276..c91ce24dfd8d 100644 --- a/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java +++ b/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java @@ -18,6 +18,7 @@ package android.app.wallpapereffectsgeneration; import android.annotation.FloatRange; import android.annotation.NonNull; +import android.annotation.Size; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -117,6 +118,7 @@ public final class CameraAttributes implements Parcelable { /** * Get the camera yaw orbit rotation. */ + @FloatRange(from = -180.0f, to = 180.0f) public float getCameraOrbitYawDegrees() { return mCameraOrbitYawDegrees; } @@ -124,6 +126,7 @@ public final class CameraAttributes implements Parcelable { /** * Get the camera pitch orbit rotation. */ + @FloatRange(from = -90.0f, to = 90.0f) public float getCameraOrbitPitchDegrees() { return mCameraOrbitPitchDegrees; } @@ -138,6 +141,7 @@ public final class CameraAttributes implements Parcelable { /** * Get the camera vertical fov degrees. */ + @FloatRange(from = 0.0f, to = 180.0f, fromInclusive = false) public float getVerticalFovDegrees() { return mVerticalFovDegrees; } @@ -145,6 +149,7 @@ public final class CameraAttributes implements Parcelable { /** * Get the frustum in near plane. */ + @FloatRange(from = 0.0f) public float getFrustumNearInWorldSpace() { return mFrustumNearInWorldSpace; } @@ -152,6 +157,7 @@ public final class CameraAttributes implements Parcelable { /** * Get the frustum in far plane. */ + @FloatRange(from = 0.0f) public float getFrustumFarInWorldSpace() { return mFrustumFarInWorldSpace; } @@ -217,8 +223,8 @@ public final class CameraAttributes implements Parcelable { * @hide */ @SystemApi - public Builder(@NonNull float[] anchorPointInWorldSpace, - @NonNull float[] anchorPointInOutputUvSpace) { + public Builder(@NonNull @Size(3) float[] anchorPointInWorldSpace, + @NonNull @Size(2) float[] anchorPointInOutputUvSpace) { mAnchorPointInWorldSpace = anchorPointInWorldSpace; mAnchorPointInOutputUvSpace = anchorPointInOutputUvSpace; } diff --git a/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java b/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java index 1254794964dd..b1d2b384a80b 100644 --- a/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java +++ b/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java @@ -39,27 +39,31 @@ import java.util.Objects; public final class CinematicEffectResponse implements Parcelable { /** @hide */ @IntDef(prefix = {"CINEMATIC_EFFECT_STATUS_"}, - value = {CINEMATIC_EFFECT_STATUS_UNKNOWN, + value = {CINEMATIC_EFFECT_STATUS_ERROR, CINEMATIC_EFFECT_STATUS_OK, - CINEMATIC_EFFECT_STATUS_ERROR, CINEMATIC_EFFECT_STATUS_NOT_READY, CINEMATIC_EFFECT_STATUS_PENDING, - CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS}) + CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS + }) @Retention(RetentionPolicy.SOURCE) public @interface CinematicEffectStatusCode {} - /** Cinematic effect generation unknown status. */ - public static final int CINEMATIC_EFFECT_STATUS_UNKNOWN = 0; + /** Cinematic effect generation failure with internal error. */ + public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0; + /** Cinematic effect generation success. */ public static final int CINEMATIC_EFFECT_STATUS_OK = 1; - /** Cinematic effect generation failure. */ - public static final int CINEMATIC_EFFECT_STATUS_ERROR = 2; + /** Service not ready for cinematic effect generation. */ - public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 3; - /** Cienmatic effect generation process is pending. */ - public static final int CINEMATIC_EFFECT_STATUS_PENDING = 4; - /** Too manay requests for server to handle. */ - public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 5; + public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2; + /** + * There is already a task being processed for the same task id. + * Client should wait for the response and not send the same request + * again. + */ + public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3; + /** Too many requests for server to handle. */ + public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4; /** @hide */ @IntDef(prefix = {"IMAGE_CONTENT_TYPE_"}, @@ -71,13 +75,13 @@ public final class CinematicEffectResponse implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface ImageContentType {} - /** Image content unknown. */ + /** Unable to determine image type. */ public static final int IMAGE_CONTENT_TYPE_UNKNOWN = 0; /** Image content is people portrait. */ public static final int IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT = 1; /** Image content is landscape. */ public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2; - /** Image content is doesn't belong to other types. */ + /** Image content is not people portrait or landscape. */ public static final int IMAGE_CONTENT_TYPE_OTHER = 3; diff --git a/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java b/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java index 18b654ec8f04..2898149036c1 100644 --- a/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java +++ b/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java @@ -19,6 +19,7 @@ package android.service.wallpapereffectsgeneration; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import android.annotation.CallSuper; +import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.SystemApi; import android.app.Service; @@ -69,7 +70,6 @@ public abstract class WallpaperEffectsGenerationService extends Service { * {@link android.permission#MANAGE_WALLPAPER_EFFECTS_GENERATION} * permission. * - * @hide */ public static final String SERVICE_INTERFACE = "android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService"; @@ -97,6 +97,7 @@ public abstract class WallpaperEffectsGenerationService extends Service { * * @param request the cinematic effect request passed from the client. */ + @MainThread public abstract void onGenerateCinematicEffect(@NonNull CinematicEffectRequest request); /** diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java index 0d0b3e098750..076059f6b0f2 100644 --- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java +++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java @@ -108,7 +108,7 @@ public class WallpaperEffectsGenerationManagerService extends @Override public void generateCinematicEffect(@NonNull CinematicEffectRequest request, @NonNull ICinematicEffectListener listener) { - if (!runForUserLocked("generateCinematicEffect", (service) -> + if (!runForUser("generateCinematicEffect", true, (service) -> service.onGenerateCinematicEffectLocked(request, listener))) { try { listener.onCinematicEffectGenerated( @@ -126,7 +126,7 @@ public class WallpaperEffectsGenerationManagerService extends @Override public void returnCinematicEffectResponse(@NonNull CinematicEffectResponse response) { - runForUserLocked("returnCinematicResponse", (service) -> + runForUser("returnCinematicResponse", false, (service) -> service.onReturnCinematicEffectResponseLocked(response)); } @@ -140,30 +140,42 @@ public class WallpaperEffectsGenerationManagerService extends } /** - * Execute the operation for the user locked. Return true if - * WallpaperEffectsGenerationPerUserService is found for the user. - * Otherwise return false. + * Execute the operation for the user. + * + * @param func The name of function for logging purpose. + * @param checkManageWallpaperEffectsPermission whether to check if caller has + * MANAGE_WALLPAPER_EFFECTS_GENERATION. + * If false, check the uid of caller matching bind service. + * @param c WallpaperEffectsGenerationPerUserService operation. + * @return whether WallpaperEffectsGenerationPerUserService is found. */ - private boolean runForUserLocked(@NonNull final String func, + private boolean runForUser(@NonNull final String func, + @NonNull final boolean checkManageWallpaperEffectsPermission, @NonNull final Consumer c) { ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class); final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), Binder.getCallingUserHandle().getIdentifier(), false, ALLOW_NON_FULL, null, null); if (DEBUG) { - Slog.d(TAG, "runForUserLocked:" + func + " from pid=" + Binder.getCallingPid() + Slog.d(TAG, "runForUser:" + func + " from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); } - Context ctx = getContext(); - if (!(ctx.checkCallingPermission(MANAGE_WALLPAPER_EFFECTS_GENERATION) - == PERMISSION_GRANTED - || mServiceNameResolver.isTemporary(userId) - || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) { - String msg = "Permission Denial: Cannot call " + func + " from pid=" - + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); - Slog.w(TAG, msg); - throw new SecurityException(msg); + if (checkManageWallpaperEffectsPermission) { + // MANAGE_WALLPAPER_EFFECTS_GENERATION is required for all functions except for + // "returnCinematicResponse", whose calling permission checked in + // WallpaperEffectsGenerationPerUserService against remote binding. + Context ctx = getContext(); + if (!(ctx.checkCallingPermission(MANAGE_WALLPAPER_EFFECTS_GENERATION) + == PERMISSION_GRANTED + || mServiceNameResolver.isTemporary(userId) + || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) { + String msg = "Permission Denial: Cannot call " + func + " from pid=" + + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); + Slog.w(TAG, msg); + throw new SecurityException(msg); + } } + final int origCallingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); boolean accepted = false; try { @@ -171,6 +183,16 @@ public class WallpaperEffectsGenerationManagerService extends final WallpaperEffectsGenerationPerUserService service = getServiceForUserLocked(userId); if (service != null) { + // Check uid of caller matches bind service implementation if + // MANAGE_WALLPAPER_EFFECTS_GENERATION is skipped. This is useful + // for service implementation to return response. + if (!checkManageWallpaperEffectsPermission + && !service.isCallingUidAllowed(origCallingUid)) { + String msg = "Permission Denial: cannot call " + func + ", uid[" + + origCallingUid + "] doesn't match service implementation"; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } accepted = true; c.accept(service); } diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java index d541051e5ab2..7ba72dbbd511 100644 --- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java +++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java @@ -141,6 +141,13 @@ public class WallpaperEffectsGenerationPerUserService extends invokeCinematicListenerAndCleanup(cinematicEffectResponse); } + /** + * Checks whether the calling uid matches the bind service uid. + */ + public boolean isCallingUidAllowed(int callingUid) { + return getServiceUidLocked() == callingUid; + } + @GuardedBy("mLock") private void updateRemoteServiceLocked() { if (mRemoteService != null) { @@ -152,7 +159,6 @@ public class WallpaperEffectsGenerationPerUserService extends invokeCinematicListenerAndCleanup( createErrorCinematicEffectResponse(mCinematicEffectListenerWrapper.mTaskId)); } - } void onPackageUpdatedLocked() {