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.CallbackExecutor;
20 import android.annotation.NonNull;
21 import android.annotation.RequiresPermission;
22 import android.annotation.SystemApi;
23 import android.annotation.SystemService;
24 import android.content.Context;
25 import android.os.RemoteException;
26 
27 import java.util.concurrent.Executor;
28 
29 /**
30  * A {@link WallpaperEffectsGenerationManager} is the class that passes wallpaper effects
31  * generation requests to wallpaper effect generation service. For example, create a cinematic
32  * and render a cinematic live wallpaper with the response.
33  *
34  * Usage:
35  * <pre>{@code
36  *      mWallpaperEffectsGenerationManager =
37  *          context.getSystemService(WallpaperEffectsGenerationManager.class);
38  *      mWallpaperEffectsGenerationManager.
39  *          generateCinematicEffect(cinematicEffectRequest, response->{
40  *              // proceed cinematic effect response.
41  *          });
42  * }</pre>
43  *
44  * @hide
45  */
46 @SystemApi
47 @SystemService(Context.WALLPAPER_EFFECTS_GENERATION_SERVICE)
48 public final class WallpaperEffectsGenerationManager {
49     /**
50      * Interface for the cinematic effect listener.
51      */
52     public interface CinematicEffectListener {
53         /**
54          * Async call when the cinematic effect response is generated.
55          * Client needs to check the status code of {@link CinematicEffectResponse}
56          * to determine if the effect generation is successful.
57          *
58          * @param response The generated cinematic effect response.
59          */
onCinematicEffectGenerated(@onNull CinematicEffectResponse response)60         void onCinematicEffectGenerated(@NonNull CinematicEffectResponse response);
61     }
62 
63     private final IWallpaperEffectsGenerationManager mService;
64 
65     /** @hide */
WallpaperEffectsGenerationManager( @onNull IWallpaperEffectsGenerationManager service)66     public WallpaperEffectsGenerationManager(
67             @NonNull IWallpaperEffectsGenerationManager service) {
68         mService = service;
69     }
70 
71     /**
72      * Execute a {@link android.app.wallpapereffectsgeneration.CinematicEffectRequest} from
73      * the given parameters to the wallpaper effects generation service. After the cinematic
74      * effect response is ready, the given listener is invoked by the system with the response.
75      * The listener may never receive a callback if unexpected error happened when proceeding
76      * request.
77      *
78      * @param request  request to generate cinematic effect.
79      * @param executor where the listener is invoked.
80      * @param listener listener invoked when the cinematic effect response is available.
81      * @hide
82      */
83     @SystemApi
84     @RequiresPermission(android.Manifest.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION)
generateCinematicEffect(@onNull CinematicEffectRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull CinematicEffectListener listener)85     public void generateCinematicEffect(@NonNull CinematicEffectRequest request,
86             @NonNull @CallbackExecutor Executor executor,
87             @NonNull CinematicEffectListener listener) {
88         try {
89             mService.generateCinematicEffect(request,
90                     new CinematicEffectListenerWrapper(listener, executor));
91         } catch (RemoteException e) {
92             throw e.rethrowFromSystemServer();
93         }
94     }
95 
96     private static final class CinematicEffectListenerWrapper
97             extends ICinematicEffectListener.Stub {
98         @NonNull
99         private final CinematicEffectListener mListener;
100         @NonNull
101         private final Executor mExecutor;
102 
CinematicEffectListenerWrapper(@onNull CinematicEffectListener listener, @NonNull Executor executor)103         CinematicEffectListenerWrapper(@NonNull CinematicEffectListener listener,
104                 @NonNull Executor executor) {
105             mListener = listener;
106             mExecutor = executor;
107         }
108 
109         @Override
onCinematicEffectGenerated(CinematicEffectResponse response)110         public void onCinematicEffectGenerated(CinematicEffectResponse response) {
111             mExecutor.execute(() -> mListener.onCinematicEffectGenerated(response));
112         }
113     }
114 }
115