Data class and interface for wallpaper effects generation api.

Test: manual build and run cts on devices
Bug: 213238425
CTS-Coverage-Bug: 213238425
Change-Id: I8c3d579a5123aaa99999f9d0df92998cec9dec34
This commit is contained in:
Sharon Su
2022-02-01 22:08:49 +00:00
parent dc97de5820
commit 0b1dea8145
17 changed files with 1546 additions and 0 deletions

View File

@@ -75,6 +75,7 @@ package android {
field public static final String BIND_TRANSLATION_SERVICE = "android.permission.BIND_TRANSLATION_SERVICE";
field public static final String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
field public static final String BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE = "android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE";
field public static final String BLUETOOTH_MAP = "android.permission.BLUETOOTH_MAP";
field public static final String BRICK = "android.permission.BRICK";
field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
@@ -187,6 +188,7 @@ package android {
field public static final String MANAGE_USB = "android.permission.MANAGE_USB";
field public static final String MANAGE_USERS = "android.permission.MANAGE_USERS";
field public static final String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE";
field public static final String MANAGE_WALLPAPER_EFFECTS_GENERATION = "android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION";
field public static final String MANAGE_WEAK_ESCROW_TOKEN = "android.permission.MANAGE_WEAK_ESCROW_TOKEN";
field public static final String MANAGE_WIFI_AUTO_JOIN = "android.permission.MANAGE_WIFI_AUTO_JOIN";
field public static final String MANAGE_WIFI_COUNTRY_CODE = "android.permission.MANAGE_WIFI_COUNTRY_CODE";
@@ -2533,6 +2535,107 @@ package android.app.usage {
}
package android.app.wallpapereffectsgeneration {
public final class CameraAttributes implements android.os.Parcelable {
method public int describeContents();
method @NonNull public float[] getAnchorPointInOutputUvSpace();
method @NonNull public float[] getAnchorPointInWorldSpace();
method public float getCameraOrbitPitchDegrees();
method public float getCameraOrbitYawDegrees();
method public float getDollyDistanceInWorldSpace();
method public float getFrustumFarInWorldSpace();
method public float getFrustumNearInWorldSpace();
method public float getVerticalFovDegrees();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CameraAttributes> CREATOR;
}
public static final class CameraAttributes.Builder {
ctor public CameraAttributes.Builder(@NonNull float[], @NonNull 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);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setDollyDistanceInWorldSpace(float);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setFrustumFarInWorldSpace(@FloatRange(from=0.0f) float);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setFrustumNearInWorldSpace(@FloatRange(from=0.0f) float);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setVerticalFovDegrees(@FloatRange(from=0.0f, to=180.0f, fromInclusive=false) float);
}
public final class CinematicEffectRequest implements android.os.Parcelable {
ctor public CinematicEffectRequest(@NonNull String, @NonNull android.graphics.Bitmap);
method public int describeContents();
method @NonNull public android.graphics.Bitmap getBitmap();
method @NonNull public String getTaskId();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CinematicEffectRequest> CREATOR;
}
public final class CinematicEffectResponse implements android.os.Parcelable {
method public int describeContents();
method @Nullable public android.app.wallpapereffectsgeneration.CameraAttributes getEndKeyFrame();
method public int getImageContentType();
method @Nullable public android.app.wallpapereffectsgeneration.CameraAttributes getStartKeyFrame();
method public int getStatusCode();
method @NonNull public String getTaskId();
method @NonNull public java.util.List<android.app.wallpapereffectsgeneration.TexturedMesh> 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_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 @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CinematicEffectResponse> CREATOR;
field public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2; // 0x2
field public static final int IMAGE_CONTENT_TYPE_OTHER = 3; // 0x3
field public static final int IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT = 1; // 0x1
field public static final int IMAGE_CONTENT_TYPE_UNKNOWN = 0; // 0x0
}
public static final class CinematicEffectResponse.Builder {
ctor public CinematicEffectResponse.Builder(int, @NonNull String);
method @NonNull public android.app.wallpapereffectsgeneration.CinematicEffectResponse build();
method @NonNull public android.app.wallpapereffectsgeneration.CinematicEffectResponse.Builder setEndKeyFrame(@Nullable android.app.wallpapereffectsgeneration.CameraAttributes);
method @NonNull public android.app.wallpapereffectsgeneration.CinematicEffectResponse.Builder setImageContentType(int);
method @NonNull public android.app.wallpapereffectsgeneration.CinematicEffectResponse.Builder setStartKeyFrame(@Nullable android.app.wallpapereffectsgeneration.CameraAttributes);
method @NonNull public android.app.wallpapereffectsgeneration.CinematicEffectResponse.Builder setTexturedMeshes(@NonNull java.util.List<android.app.wallpapereffectsgeneration.TexturedMesh>);
}
public final class TexturedMesh implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.graphics.Bitmap getBitmap();
method @NonNull public int[] getIndices();
method @NonNull public int getIndicesLayoutType();
method @NonNull public float[] getVertices();
method @NonNull public int getVerticesLayoutType();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.TexturedMesh> CREATOR;
field public static final int INDICES_LAYOUT_TRIANGLES = 1; // 0x1
field public static final int INDICES_LAYOUT_UNDEFINED = 0; // 0x0
field public static final int VERTICES_LAYOUT_POSITION3_UV2 = 1; // 0x1
field public static final int VERTICES_LAYOUT_UNDEFINED = 0; // 0x0
}
public static final class TexturedMesh.Builder {
ctor public TexturedMesh.Builder(@NonNull android.graphics.Bitmap);
method @NonNull public android.app.wallpapereffectsgeneration.TexturedMesh build();
method @NonNull public android.app.wallpapereffectsgeneration.TexturedMesh.Builder setIndices(@NonNull int[]);
method @NonNull public android.app.wallpapereffectsgeneration.TexturedMesh.Builder setIndicesLayoutType(int);
method @NonNull public android.app.wallpapereffectsgeneration.TexturedMesh.Builder setVertices(@NonNull float[]);
method @NonNull public android.app.wallpapereffectsgeneration.TexturedMesh.Builder setVerticesLayoutType(int);
}
public final class WallpaperEffectsGenerationManager {
method @RequiresPermission(android.Manifest.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION) public void generateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.wallpapereffectsgeneration.WallpaperEffectsGenerationManager.CinematicEffectListener);
}
public static interface WallpaperEffectsGenerationManager.CinematicEffectListener {
method public void onCinematicEffectGenerated(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectResponse);
}
}
package android.apphibernation {
public class AppHibernationManager {
@@ -2716,6 +2819,7 @@ package android.content {
field public static final String UI_TRANSLATION_SERVICE = "ui_translation";
field public static final String UWB_SERVICE = "uwb";
field public static final String VR_SERVICE = "vrmanager";
field public static final String WALLPAPER_EFFECTS_GENERATION_SERVICE = "wallpaper_effects_generation";
field public static final String WIFI_NL80211_SERVICE = "wifinl80211";
field @Deprecated public static final String WIFI_RTT_SERVICE = "rttmanager";
field public static final String WIFI_SCANNING_SERVICE = "wifiscanner";
@@ -11648,6 +11752,17 @@ package android.service.wallpaper {
}
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 public final void returnCinematicEffectResponse(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectResponse);
}
}
package android.service.watchdog {
public abstract class ExplicitHealthCheckService extends android.app.Service {

View File

@@ -51,6 +51,8 @@ import android.app.usage.IUsageStatsManager;
import android.app.usage.NetworkStatsManager;
import android.app.usage.StorageStatsManager;
import android.app.usage.UsageStatsManager;
import android.app.wallpapereffectsgeneration.IWallpaperEffectsGenerationManager;
import android.app.wallpapereffectsgeneration.WallpaperEffectsGenerationManager;
import android.apphibernation.AppHibernationManager;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothFrameworkInitializer;
@@ -1298,6 +1300,20 @@ public final class SystemServiceRegistry {
}
});
registerService(Context.WALLPAPER_EFFECTS_GENERATION_SERVICE,
WallpaperEffectsGenerationManager.class,
new CachedServiceFetcher<WallpaperEffectsGenerationManager>() {
@Override
public WallpaperEffectsGenerationManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
IBinder b = ServiceManager.getService(
Context.WALLPAPER_EFFECTS_GENERATION_SERVICE);
return b == null ? null :
new WallpaperEffectsGenerationManager(
IWallpaperEffectsGenerationManager.Stub.asInterface(b));
}
});
registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
@Override
public VrManager createService(ContextImpl ctx) throws ServiceNotFoundException {

View File

@@ -0,0 +1,301 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Representing the position and other parameters of camera of a single frame.
*
* @hide
*/
@SystemApi
public final class CameraAttributes implements Parcelable {
/**
* The location of the anchor within the 3D scene.
* Expecting 3 floats representing the x, y, z coordinates
* of the anchor point.
*/
@NonNull
private float[] mAnchorPointInWorldSpace;
/**
* Where the anchor point should project to in the output image.
* Expecting 2 floats representing the u,v coordinates of the
* anchor point.
*/
@NonNull
private float[] mAnchorPointInOutputUvSpace;
/**
* Specifies the amount of yaw orbit rotation the camera should perform
* around the anchor point in world space.
*/
private float mCameraOrbitYawDegrees;
/**
* Specifies the amount of pitch orbit rotation the camera should perform
* around the anchor point in world space.
*/
private float mCameraOrbitPitchDegrees;
/**
* Specifies by how much the camera should be placed towards the anchor
* point in world space, which is also called dolly distance.
*/
private float mDollyDistanceInWorldSpace;
/**
* Specifies the vertical fov degrees of the virtual image.
*/
private float mVerticalFovDegrees;
/**
* The frustum of near plane.
*/
private float mFrustumNearInWorldSpace;
/**
* The frustum of far plane.
*/
private float mFrustumFarInWorldSpace;
private CameraAttributes(Parcel in) {
this.mCameraOrbitYawDegrees = in.readFloat();
this.mCameraOrbitPitchDegrees = in.readFloat();
this.mDollyDistanceInWorldSpace = in.readFloat();
this.mVerticalFovDegrees = in.readFloat();
this.mFrustumNearInWorldSpace = in.readFloat();
this.mFrustumFarInWorldSpace = in.readFloat();
this.mAnchorPointInWorldSpace = in.createFloatArray();
this.mAnchorPointInOutputUvSpace = in.createFloatArray();
}
private CameraAttributes(float[] anchorPointInWorldSpace, float[] anchorPointInOutputUvSpace,
float cameraOrbitYawDegrees, float cameraOrbitPitchDegrees,
float dollyDistanceInWorldSpace,
float verticalFovDegrees, float frustumNearInWorldSpace, float frustumFarInWorldSpace) {
mAnchorPointInWorldSpace = anchorPointInWorldSpace;
mAnchorPointInOutputUvSpace = anchorPointInOutputUvSpace;
mCameraOrbitYawDegrees = cameraOrbitYawDegrees;
mCameraOrbitPitchDegrees = cameraOrbitPitchDegrees;
mDollyDistanceInWorldSpace = dollyDistanceInWorldSpace;
mVerticalFovDegrees = verticalFovDegrees;
mFrustumNearInWorldSpace = frustumNearInWorldSpace;
mFrustumFarInWorldSpace = frustumFarInWorldSpace;
}
/**
* Get the location of the anchor within the 3D scene. The response float array contains
* 3 floats representing the x, y, z coordinates
*/
@NonNull
public float[] getAnchorPointInWorldSpace() {
return mAnchorPointInWorldSpace;
}
/**
* Get where the anchor point should project to in the output image. The response float
* array contains 2 floats representing the u,v coordinates of the anchor point.
*/
@NonNull
public float[] getAnchorPointInOutputUvSpace() {
return mAnchorPointInOutputUvSpace;
}
/**
* Get the camera yaw orbit rotation.
*/
public float getCameraOrbitYawDegrees() {
return mCameraOrbitYawDegrees;
}
/**
* Get the camera pitch orbit rotation.
*/
public float getCameraOrbitPitchDegrees() {
return mCameraOrbitPitchDegrees;
}
/**
* Get how many units the camera should be placed towards the anchor point in world space.
*/
public float getDollyDistanceInWorldSpace() {
return mDollyDistanceInWorldSpace;
}
/**
* Get the camera vertical fov degrees.
*/
public float getVerticalFovDegrees() {
return mVerticalFovDegrees;
}
/**
* Get the frustum in near plane.
*/
public float getFrustumNearInWorldSpace() {
return mFrustumNearInWorldSpace;
}
/**
* Get the frustum in far plane.
*/
public float getFrustumFarInWorldSpace() {
return mFrustumFarInWorldSpace;
}
@NonNull
public static final Creator<CameraAttributes> CREATOR = new Creator<CameraAttributes>() {
@Override
public CameraAttributes createFromParcel(Parcel in) {
return new CameraAttributes(in);
}
@Override
public CameraAttributes[] newArray(int size) {
return new CameraAttributes[size];
}
};
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeFloat(mCameraOrbitYawDegrees);
out.writeFloat(mCameraOrbitPitchDegrees);
out.writeFloat(mDollyDistanceInWorldSpace);
out.writeFloat(mVerticalFovDegrees);
out.writeFloat(mFrustumNearInWorldSpace);
out.writeFloat(mFrustumFarInWorldSpace);
out.writeFloatArray(mAnchorPointInWorldSpace);
out.writeFloatArray(mAnchorPointInOutputUvSpace);
}
@Override
public int describeContents() {
return 0;
}
/**
* Builder for {@link CameraAttributes}.
*
* @hide
*/
@SystemApi
public static final class Builder {
@NonNull
private float[] mAnchorPointInWorldSpace;
@NonNull
private float[] mAnchorPointInOutputUvSpace;
private float mCameraOrbitYawDegrees;
private float mCameraOrbitPitchDegrees;
private float mDollyDistanceInWorldSpace;
private float mVerticalFovDegrees;
private float mFrustumNearInWorldSpace;
private float mFrustumFarInWorldSpace;
/**
* Constructor with anchor point in world space and anchor point in output image
* space.
*
* @param anchorPointInWorldSpace the location of the anchor within the 3D scene. The
* float array contains 3 floats representing the x, y, z coordinates.
* @param anchorPointInOutputUvSpace where the anchor point should project to in the
* output image. The float array contains 2 floats representing the u,v coordinates
* of the anchor point.
*
* @hide
*/
@SystemApi
public Builder(@NonNull float[] anchorPointInWorldSpace,
@NonNull float[] anchorPointInOutputUvSpace) {
mAnchorPointInWorldSpace = anchorPointInWorldSpace;
mAnchorPointInOutputUvSpace = anchorPointInOutputUvSpace;
}
/**
* Sets the camera orbit yaw rotation.
*/
@NonNull
public Builder setCameraOrbitYawDegrees(
@FloatRange(from = -180.0f, to = 180.0f) float cameraOrbitYawDegrees) {
mCameraOrbitYawDegrees = cameraOrbitYawDegrees;
return this;
}
/**
* Sets the camera orbit pitch rotation.
*/
@NonNull
public Builder setCameraOrbitPitchDegrees(
@FloatRange(from = -90.0f, to = 90.0f) float cameraOrbitPitchDegrees) {
mCameraOrbitPitchDegrees = cameraOrbitPitchDegrees;
return this;
}
/**
* Sets the camera dolly distance.
*/
@NonNull
public Builder setDollyDistanceInWorldSpace(float dollyDistanceInWorldSpace) {
mDollyDistanceInWorldSpace = dollyDistanceInWorldSpace;
return this;
}
/**
* Sets the camera vertical fov degree.
*/
@NonNull
public Builder setVerticalFovDegrees(
@FloatRange(from = 0.0f, to = 180.0f, fromInclusive = false)
float verticalFovDegrees) {
mVerticalFovDegrees = verticalFovDegrees;
return this;
}
/**
* Sets the frustum in near plane.
*/
@NonNull
public Builder setFrustumNearInWorldSpace(
@FloatRange(from = 0.0f) float frustumNearInWorldSpace) {
mFrustumNearInWorldSpace = frustumNearInWorldSpace;
return this;
}
/**
* Sets the frustum in far plane.
*/
@NonNull
public Builder setFrustumFarInWorldSpace(
@FloatRange(from = 0.0f) float frustumFarInWorldSpace) {
mFrustumFarInWorldSpace = frustumFarInWorldSpace;
return this;
}
/**
* Builds a new {@link CameraAttributes} instance.
*/
@NonNull
public CameraAttributes build() {
return new CameraAttributes(mAnchorPointInWorldSpace,
mAnchorPointInOutputUvSpace,
mCameraOrbitYawDegrees,
mCameraOrbitPitchDegrees,
mDollyDistanceInWorldSpace,
mVerticalFovDegrees,
mFrustumNearInWorldSpace,
mFrustumFarInWorldSpace);
}
}
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2022, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
parcelable CinematicEffectRequest;

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* A {@link CinematicEffectRequest} is the data class having all the information
* passed to wallpaper effects generation service.
*
* @hide
*/
@SystemApi
public final class CinematicEffectRequest implements Parcelable {
/**
* Unique id of a cienmatic effect generation task.
*/
@NonNull
private String mTaskId;
/**
* The bitmap to generate cinematic effect from.
*/
@NonNull
private Bitmap mBitmap;
private CinematicEffectRequest(Parcel in) {
this.mTaskId = in.readString();
this.mBitmap = Bitmap.CREATOR.createFromParcel(in);
}
/**
* Constructor with task id and bitmap.
*/
public CinematicEffectRequest(@NonNull String taskId, @NonNull Bitmap bitmap) {
mTaskId = taskId;
mBitmap = bitmap;
}
/**
* Returns the task id.
*/
@NonNull
public String getTaskId() {
return mTaskId;
}
/**
* Returns the bitmap of this request.
*/
@NonNull
public Bitmap getBitmap() {
return mBitmap;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) {
return false;
}
CinematicEffectRequest that = (CinematicEffectRequest) o;
return mTaskId.equals(that.mTaskId);
}
@Override
public int hashCode() {
return Objects.hash(mTaskId);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeString(mTaskId);
mBitmap.writeToParcel(out, flags);
}
@NonNull
public static final Creator<CinematicEffectRequest> CREATOR =
new Creator<CinematicEffectRequest>() {
@Override
public CinematicEffectRequest createFromParcel(Parcel in) {
return new CinematicEffectRequest(in);
}
@Override
public CinematicEffectRequest[] newArray(int size) {
return new CinematicEffectRequest[size];
}
};
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2022, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
parcelable CinematicEffectResponse;

View File

@@ -0,0 +1,299 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* A {@link CinematicEffectResponse} include textured meshes
* and camera attributes of key frames.
*
* @hide
*/
@SystemApi
public final class CinematicEffectResponse implements Parcelable {
/** @hide */
@IntDef(prefix = {"CINEMATIC_EFFECT_STATUS_"},
value = {CINEMATIC_EFFECT_STATUS_UNKNOWN,
CINEMATIC_EFFECT_STATUS_OK,
CINEMATIC_EFFECT_STATUS_ERROR,
CINEMATIC_EFFECT_STATUS_NOT_READY,
CINEMATIC_EFFECT_STATUS_PENDING,
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 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;
/** @hide */
@IntDef(prefix = {"IMAGE_CONTENT_TYPE_"},
value = {IMAGE_CONTENT_TYPE_UNKNOWN,
IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT,
IMAGE_CONTENT_TYPE_LANDSCAPE,
IMAGE_CONTENT_TYPE_OTHER
})
@Retention(RetentionPolicy.SOURCE)
public @interface ImageContentType {}
/** Image content unknown. */
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. */
public static final int IMAGE_CONTENT_TYPE_OTHER = 3;
@CinematicEffectStatusCode
private int mStatusCode;
/** The id of the cinematic effect generation task. */
@NonNull
private String mTaskId;
@ImageContentType
private int mImageContentType;
/** The textured mesh required to render cinematic effect. */
@NonNull
private List<TexturedMesh> mTexturedMeshes;
/** The start camera position for animation. */
@Nullable
private CameraAttributes mStartKeyFrame;
/** The end camera position for animation. */
@Nullable
private CameraAttributes mEndKeyFrame;
private CinematicEffectResponse(Parcel in) {
mStatusCode = in.readInt();
mTaskId = in.readString();
mImageContentType = in.readInt();
mTexturedMeshes = new ArrayList<TexturedMesh>();
in.readTypedList(mTexturedMeshes, TexturedMesh.CREATOR);
mStartKeyFrame = in.readTypedObject(CameraAttributes.CREATOR);
mEndKeyFrame = in.readTypedObject(CameraAttributes.CREATOR);
}
private CinematicEffectResponse(@CinematicEffectStatusCode int statusCode,
String taskId,
@ImageContentType int imageContentType,
List<TexturedMesh> texturedMeshes,
CameraAttributes startKeyFrame,
CameraAttributes endKeyFrame) {
mStatusCode = statusCode;
mTaskId = taskId;
mImageContentType = imageContentType;
mStartKeyFrame = startKeyFrame;
mEndKeyFrame = endKeyFrame;
mTexturedMeshes = texturedMeshes;
}
/** Gets the cinematic effect generation status code. */
@CinematicEffectStatusCode
public int getStatusCode() {
return mStatusCode;
}
/** Get the task id. */
@NonNull
public String getTaskId() {
return mTaskId;
}
/**
* Get the image content type, which briefly classifies what's
* the content of image, like people portrait, landscape etc.
*/
@ImageContentType
public int getImageContentType() {
return mImageContentType;
}
/** Get the textured meshes. */
@NonNull
public List<TexturedMesh> getTexturedMeshes() {
return mTexturedMeshes;
}
/**
* Get the camera attributes (position info and other parameters, see docs of
* {@link CameraAttributes}) of the start key frame on the animation path.
*/
@Nullable
public CameraAttributes getStartKeyFrame() {
return mStartKeyFrame;
}
/**
* Get the camera attributes (position info and other parameters, see docs of
* {@link CameraAttributes}) of the end key frame on the animation path.
*/
@Nullable
public CameraAttributes getEndKeyFrame() {
return mEndKeyFrame;
}
@NonNull
public static final Creator<CinematicEffectResponse> CREATOR =
new Creator<CinematicEffectResponse>() {
@Override
public CinematicEffectResponse createFromParcel(Parcel in) {
return new CinematicEffectResponse(in);
}
@Override
public CinematicEffectResponse[] newArray(int size) {
return new CinematicEffectResponse[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeInt(mStatusCode);
out.writeString(mTaskId);
out.writeInt(mImageContentType);
out.writeTypedList(mTexturedMeshes, flags);
out.writeTypedObject(mStartKeyFrame, flags);
out.writeTypedObject(mEndKeyFrame, flags);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) {
return false;
}
CinematicEffectResponse that = (CinematicEffectResponse) o;
return mTaskId.equals(that.mTaskId);
}
@Override
public int hashCode() {
return Objects.hash(mTaskId);
}
/**
* Builder of {@link CinematicEffectResponse}
*
* @hide
*/
@SystemApi
public static final class Builder {
@CinematicEffectStatusCode
private int mStatusCode;
@NonNull
private String mTaskId;
@ImageContentType
private int mImageContentType;
@NonNull
private List<TexturedMesh> mTexturedMeshes;
@Nullable
private CameraAttributes mStartKeyFrame;
@Nullable
private CameraAttributes mEndKeyFrame;
/**
* Constructor with task id and status code.
*
* @hide
*/
@SystemApi
public Builder(@CinematicEffectStatusCode int statusCode, @NonNull String taskId) {
mStatusCode = statusCode;
mTaskId = taskId;
}
/**
* Sets the image content type.
*/
@NonNull
public Builder setImageContentType(@ImageContentType int imageContentType) {
mImageContentType = imageContentType;
return this;
}
/**
* Sets the textured meshes.
*/
@NonNull
public Builder setTexturedMeshes(@NonNull List<TexturedMesh> texturedMeshes) {
mTexturedMeshes = texturedMeshes;
return this;
}
/**
* Sets start key frame.
*/
@NonNull
public Builder setStartKeyFrame(@Nullable CameraAttributes startKeyFrame) {
mStartKeyFrame = startKeyFrame;
return this;
}
/**
* Sets end key frame.
*/
@NonNull
public Builder setEndKeyFrame(@Nullable CameraAttributes endKeyFrame) {
mEndKeyFrame = endKeyFrame;
return this;
}
/**
* Builds a {@link CinematicEffectResponse} instance.
*/
@NonNull
public CinematicEffectResponse build() {
if (mTexturedMeshes == null) {
// Place holder because build doesn't allow list to be nullable.
mTexturedMeshes = new ArrayList<>(0);
}
return new CinematicEffectResponse(mStatusCode, mTaskId, mImageContentType,
mTexturedMeshes, mStartKeyFrame, mEndKeyFrame);
}
}
}

View File

@@ -0,0 +1,30 @@
/**
* Copyright (c) 2022, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.app.wallpapereffectsgeneration.CinematicEffectResponse;
/**
* Callback used by system server to notify invoker of {@link WallpaperEffectsGenerationMAnager}
* of the cinematic effect generation result.
*
* @hide
*/
oneway interface ICinematicEffectListener {
void onCinematicEffectGenerated(in CinematicEffectResponse response);
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2022, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.app.wallpapereffectsgeneration.CinematicEffectRequest;
import android.app.wallpapereffectsgeneration.CinematicEffectResponse;
import android.app.wallpapereffectsgeneration.ICinematicEffectListener;
/**
* Used by {@link android.app.wallpapereffectsgeneration.WallpaperEffectsGenerationManager}
* to to generate effects.
*
* @hide
*/
oneway interface IWallpaperEffectsGenerationManager {
void generateCinematicEffect(in CinematicEffectRequest request,
in ICinematicEffectListener listener);
void returnCinematicEffectResponse(in CinematicEffectResponse response);
}

View File

@@ -0,0 +1,273 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* The textured mesh representation, including a texture (bitmap) to sample from when rendering,
* and a mesh consisting of primitives such as triangles. The mesh is represented by an indices
* array describing the set of primitives in the mesh, and a vertices array that the indices
* refer to.
*
* @hide
*/
@SystemApi
public final class TexturedMesh implements Parcelable {
/**
* The texture to sample from when rendering mesh.
*/
@NonNull
private Bitmap mBitmap;
/**
* The set of primitives as pointers into the vertices.
*/
@NonNull
private int[] mIndices;
/**
* The specific vertices that the indices refer to.
*/
@NonNull
private float[] mVertices;
/** @hide */
@IntDef(prefix = {"INDICES_LAYOUT_"}, value = {
INDICES_LAYOUT_UNDEFINED,
INDICES_LAYOUT_TRIANGLES})
@Retention(RetentionPolicy.SOURCE)
public @interface IndicesLayoutType {
}
/** Undefined indices layout */
public static final int INDICES_LAYOUT_UNDEFINED = 0;
/**
* Indices layout is triangle. Vertices are grouped into 3 and each
* group forms a triangle.
*/
public static final int INDICES_LAYOUT_TRIANGLES = 1;
@IndicesLayoutType
private int mIndicesLayoutType;
/** @hide */
@IntDef(prefix = {"VERTICES_LAYOUT_"}, value = {
VERTICES_LAYOUT_UNDEFINED,
VERTICES_LAYOUT_POSITION3_UV2})
@Retention(RetentionPolicy.SOURCE)
public @interface VerticesLayoutType {
}
/**
* Undefined vertices layout.
*/
public static final int VERTICES_LAYOUT_UNDEFINED = 0;
/**
* The vertices array uses 5 numbers to represent a point, in the format
* of [x1, y1, z1, u1, v1, x2, y2, z2, u2, v2, ...].
*/
public static final int VERTICES_LAYOUT_POSITION3_UV2 = 1;
@VerticesLayoutType
private int mVerticesLayoutType;
private TexturedMesh(Parcel in) {
this.mIndicesLayoutType = in.readInt();
this.mVerticesLayoutType = in.readInt();
this.mBitmap = in.readTypedObject(Bitmap.CREATOR);
Parcel data = Parcel.obtain();
try {
byte[] bytes = in.readBlob();
data.unmarshall(bytes, 0, bytes.length);
data.setDataPosition(0);
this.mIndices = data.createIntArray();
this.mVertices = data.createFloatArray();
} finally {
data.recycle();
}
}
private TexturedMesh(@NonNull Bitmap bitmap, @NonNull int[] indices,
@NonNull float[] vertices, @IndicesLayoutType int indicesLayoutType,
@VerticesLayoutType int verticesLayoutType) {
mBitmap = bitmap;
mIndices = indices;
mVertices = vertices;
mIndicesLayoutType = indicesLayoutType;
mVerticesLayoutType = verticesLayoutType;
}
/** Get the bitmap, which is the texture to sample from when rendering. */
@NonNull
public Bitmap getBitmap() {
return mBitmap;
}
/**
* Get the indices as pointers to the vertices array. Depending on the getIndicesLayoutType(),
* the primitives may have different shapes. For example, with INDICES_LAYOUT_TRIANGLES,
* indices 0, 1, 2 forms a triangle, indices 3, 4, 5 form another triangle.
*/
@NonNull
public int[] getIndices() {
return mIndices;
}
/**
* Get the vertices that the index array refers to. Depending on the getVerticesLayoutType()
* result, the vertices array can represent different per-vertex coordinates. For example,
* with VERTICES_LAYOUT_POSITION3_UV2 type, vertices are in the format of
* [x1, y1, z1, u1, v1, x2, y2, z2, u2, v2, ...].
*/
@NonNull
public float[] getVertices() {
return mVertices;
}
/** Get the indices layout type. */
@IndicesLayoutType
@NonNull
public int getIndicesLayoutType() {
return mIndicesLayoutType;
}
/** Get the indices layout type. */
@VerticesLayoutType
@NonNull
public int getVerticesLayoutType() {
return mVerticesLayoutType;
}
@NonNull
public static final Creator<TexturedMesh> CREATOR = new Creator<TexturedMesh>() {
@Override
public TexturedMesh createFromParcel(Parcel in) {
return new TexturedMesh(in);
}
@Override
public TexturedMesh[] newArray(int size) {
return new TexturedMesh[size];
}
};
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeInt(mIndicesLayoutType);
out.writeInt(mVerticesLayoutType);
out.writeTypedObject(mBitmap, flags);
// Indices and vertices can reach 5MB. Write the data as a Blob,
// which will be written to ashmem if too large.
Parcel data = Parcel.obtain();
try {
data.writeIntArray(mIndices);
data.writeFloatArray(mVertices);
out.writeBlob(data.marshall());
} finally {
data.recycle();
}
}
@Override
public int describeContents() {
return 0;
}
/**
* A builder for {@link TexturedMesh}
*
* @hide
*/
@SystemApi
public static final class Builder {
private Bitmap mBitmap;
private int[] mIndices;
private float[] mVertices;
@IndicesLayoutType
private int mIndicesLayoutType;
@VerticesLayoutType
private int mVerticesLayouttype;
/**
* Constructor with bitmap.
*
* @hide
*/
@SystemApi
public Builder(@NonNull Bitmap bitmap) {
mBitmap = bitmap;
}
/**
* Set the required indices. The indices should represent the primitives. For example,
* with INDICES_LAYOUT_TRIANGLES, indices 0, 1, 2 forms a triangle, indices 3, 4, 5
* form another triangle.
*/
@NonNull
public Builder setIndices(@NonNull int[] indices) {
mIndices = indices;
return this;
}
/**
* Set the required vertices. The vertices array should represent per-vertex coordinates.
* For example, with VERTICES_LAYOUT_POSITION3_UV2 type, vertices are in the format of
* [x1, y1, z1, u1, v1, x2, y2, z2, u2, v2, ...].
*
*/
@NonNull
public Builder setVertices(@NonNull float[] vertices) {
mVertices = vertices;
return this;
}
/**
* Set the required indices layout type.
*/
@NonNull
public Builder setIndicesLayoutType(@IndicesLayoutType int indicesLayoutType) {
mIndicesLayoutType = indicesLayoutType;
return this;
}
/**
* Set the required vertices layout type.
*/
@NonNull
public Builder setVerticesLayoutType(@VerticesLayoutType int verticesLayoutype) {
mVerticesLayouttype = verticesLayoutype;
return this;
}
/** Builds a TexturedMesh based on the given parameters. */
@NonNull
public TexturedMesh build() {
return new TexturedMesh(mBitmap, mIndices, mVertices, mIndicesLayoutType,
mVerticesLayouttype);
}
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.app.wallpapereffectsgeneration;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
import java.util.concurrent.Executor;
/**
* A {@link WallpaperEffectsGenerationManager} is the class that passes wallpaper effects
* generation requests to wallpaper effect generation service. For example, create a cinematic
* and render a cinematic live wallpaper with the response.
*
* Usage:
* <pre>{@code
* mWallpaperEffectsGenerationManager =
* context.getSystemService(WallpaperEffectsGenerationManager.class);
* mWallpaperEffectsGenerationManager.
* generateCinematicEffect(cinematicEffectRequest, response->{
* // proceed cinematic effect response.
* });
* }</pre>
*
* @hide
*/
@SystemApi
@SystemService(Context.WALLPAPER_EFFECTS_GENERATION_SERVICE)
public final class WallpaperEffectsGenerationManager {
/**
* Interface for the cinematic effect listener.
*/
public interface CinematicEffectListener {
/**
* Async call when the cinematic effect response is generated.
* Client needs to check the status code of {@link CinematicEffectResponse}
* to determine if the effect generation is successful.
*
* @param response The generated cinematic effect response.
*/
void onCinematicEffectGenerated(@NonNull CinematicEffectResponse response);
}
private final IWallpaperEffectsGenerationManager mService;
/** @hide */
public WallpaperEffectsGenerationManager(
@NonNull IWallpaperEffectsGenerationManager service) {
mService = service;
}
/**
* Execute a {@link android.app.wallpapereffectsgeneration.CinematicEffectRequest} from
* the given parameters to the wallpaper effects generation service. After the cinematic
* effect response is ready, the given listener is invoked by the system with the response.
* The listener may never receive a callback if unexpected error happened when proceeding
* request.
*
* @param request request to generate cinematic effect.
* @param executor where the listener is invoked.
* @param listener listener invoked when the cinematic effect response is available.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION)
public void generateCinematicEffect(@NonNull CinematicEffectRequest request,
@NonNull @CallbackExecutor Executor executor,
@NonNull CinematicEffectListener listener) {
try {
mService.generateCinematicEffect(request,
new CinematicEffectListenerWrapper(listener, executor));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private static final class CinematicEffectListenerWrapper
extends ICinematicEffectListener.Stub {
@NonNull
private final CinematicEffectListener mListener;
@NonNull
private final Executor mExecutor;
CinematicEffectListenerWrapper(@NonNull CinematicEffectListener listener,
@NonNull Executor executor) {
mListener = listener;
mExecutor = executor;
}
@Override
public void onCinematicEffectGenerated(CinematicEffectResponse response) {
mExecutor.execute(() -> mListener.onCinematicEffectGenerated(response));
}
}
}

View File

@@ -5010,6 +5010,20 @@ public abstract class Context {
*/
public static final String SOUND_TRIGGER_MIDDLEWARE_SERVICE = "soundtrigger_middleware";
/**
* Used for getting the wallpaper effects generation service.
*
* <p><b>NOTE: </b> this service is optional; callers of
* {@code Context.getSystemServiceName(WALLPAPER_EFFECTS_GENERATION_SERVICE)} should check for
* {@code null}.
*
* @hide
* @see #getSystemService(String)
*/
@SystemApi
public static final String WALLPAPER_EFFECTS_GENERATION_SERVICE =
"wallpaper_effects_generation";
/**
* Used to access {@link MusicRecognitionManagerService}.
*

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.service.wallpapereffectsgeneration;
import android.app.wallpapereffectsgeneration.CinematicEffectRequest;
/**
* Interface from the system to WallpaperEffectsGeneration service.
*
* @hide
*/
oneway interface IWallpaperEffectsGenerationService {
void onGenerateCinematicEffect(in CinematicEffectRequest request);
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.service.wallpapereffectsgeneration;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
import android.app.wallpapereffectsgeneration.CinematicEffectRequest;
import android.app.wallpapereffectsgeneration.CinematicEffectResponse;
import android.app.wallpapereffectsgeneration.IWallpaperEffectsGenerationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.Slog;
/**
* A service for handling wallpaper effects generation tasks. It must implement
* (onGenerateCinematicEffect} method to generate response and call returnCinematicEffectResponse
* to send the response.
*
* <p>To extend this service, you must declare the service in your manifest file with the
* {@link android.Manifest.permission#BIND_WALLPAPER_EFFECTS_GENERATION} permission and includes
* an intent filter with the {@link #SERVICE_INTERFACE} action. For example: </p>
* <pre>
* <application>
* <service android:name=".CtsWallpaperEffectsGenerationService"
* android:exported="true"
* android:label="CtsWallpaperEffectsGenerationService"
* android:permission="android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE">
* <intent-filter>
* <action android:name="android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService"
/>
* </intent-filter>
* </service>
* <uses-library android:name="android.test.runner"/>
* </application>
* </pre>
*
* @hide
*/
@SystemApi
public abstract class WallpaperEffectsGenerationService extends Service {
/**
* The {@link Intent} that must be declared as handled by the service.
*
* <p>The service must also require the
* {@link android.permission#MANAGE_WALLPAPER_EFFECTS_GENERATION}
* permission.
*
* @hide
*/
public static final String SERVICE_INTERFACE =
"android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService";
private static final boolean DEBUG = false;
private static final String TAG = "WallpaperEffectsGenerationService";
private Handler mHandler;
private IWallpaperEffectsGenerationManager mService;
private final IWallpaperEffectsGenerationService mInterface =
new IWallpaperEffectsGenerationService.Stub() {
@Override
public void onGenerateCinematicEffect(CinematicEffectRequest request) {
mHandler.sendMessage(
obtainMessage(
WallpaperEffectsGenerationService::onGenerateCinematicEffect,
WallpaperEffectsGenerationService.this, request));
}
};
/**
* Called when the OS receives a request for generating cinematic effect. On receiving the
* request, it extract cinematic information from the input and call
* {@link #returnCinematicEffectResponse} with the textured mesh
* and metadata wrapped in CinematicEffectResponse.
*
* @param request the cinematic effect request passed from the client.
*/
public abstract void onGenerateCinematicEffect(@NonNull CinematicEffectRequest request);
/**
* Returns the cinematic effect response. Must be called when cinematic effect
* response is generated and ready to be sent back. Otherwise the response won't be
* returned.
*
* @param response the cinematic effect response returned from service provider.
*/
public final void returnCinematicEffectResponse(@NonNull CinematicEffectResponse response) {
try {
mService.returnCinematicEffectResponse(response);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@CallSuper
@Override
public void onCreate() {
super.onCreate();
if (DEBUG) {
Log.d(TAG, "onCreate WallpaperEffectsGenerationService");
}
mHandler = new Handler(Looper.getMainLooper(), null, true);
IBinder b = ServiceManager.getService(Context.WALLPAPER_EFFECTS_GENERATION_SERVICE);
mService = IWallpaperEffectsGenerationManager.Stub.asInterface(b);
}
@NonNull
@Override
public final IBinder onBind(@NonNull Intent intent) {
if (DEBUG) {
Log.d(TAG, "onBind WallpaperEffectsGenerationService");
}
if (SERVICE_INTERFACE.equals(intent.getAction())) {
return mInterface.asBinder();
}
Slog.w(TAG,
"Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
return null;
}
}

View File

@@ -4162,6 +4162,16 @@
<permission android:name="android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by a
android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService,
to ensure that only the system can bind to it.
@SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
<p>Protection level: signature
-->
<permission android:name="android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE"
android:protectionLevel="signature" />
<!-- Must be declared by a android.service.musicrecognition.MusicRecognitionService,
to ensure that only the system can bind to it.
@SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
@@ -5849,6 +5859,13 @@
<permission android:name="android.permission.MANAGE_SMARTSPACE"
android:protectionLevel="signature" />
<!-- @SystemApi Allows an application to manage the wallpaper effects
generation service.
@hide <p>Not for use by third-party applications.</p> -->
<permission android:name="android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION"
android:protectionLevel="signature" />
<!-- Allows an app to set the theme overlay in /vendor/overlay
being used.
@hide <p>Not for use by third-party applications.</p> -->

View File

@@ -4161,6 +4161,15 @@
<string name="config_defaultMusicRecognitionService" translatable="false"></string>
<!-- The package name for the system's wallpaper effects generation service.
This service returns wallpaper effects results.
This service must be trusted, as it can be activated without explicit consent of the user.
If no service with the specified name exists on the device, wallpaper effects
generation service will be disabled.
Example: "com.android.intelligence/.WallpaperEffectsGenerationService"
-->
<string name="config_defaultWallpaperEffectsGenerationService" translatable="false"></string>
<!-- The package name for the default retail demo app.
This package must be trusted, as it has the permissions to query the usage stats on the
device.

View File

@@ -3670,6 +3670,7 @@
<java-symbol type="string" name="config_defaultContentSuggestionsService" />
<java-symbol type="string" name="config_defaultSearchUiService" />
<java-symbol type="string" name="config_defaultSmartspaceService" />
<java-symbol type="string" name="config_defaultWallpaperEffectsGenerationService" />
<java-symbol type="string" name="config_defaultMusicRecognitionService" />
<java-symbol type="string" name="config_defaultAttentionService" />
<java-symbol type="string" name="config_defaultRotationResolverService" />