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.service.wallpapereffectsgeneration; 18 19 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; 20 21 import android.annotation.CallSuper; 22 import android.annotation.MainThread; 23 import android.annotation.NonNull; 24 import android.annotation.SystemApi; 25 import android.app.Service; 26 import android.app.wallpapereffectsgeneration.CinematicEffectRequest; 27 import android.app.wallpapereffectsgeneration.CinematicEffectResponse; 28 import android.app.wallpapereffectsgeneration.IWallpaperEffectsGenerationManager; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.os.Handler; 32 import android.os.IBinder; 33 import android.os.Looper; 34 import android.os.RemoteException; 35 import android.os.ServiceManager; 36 import android.util.Log; 37 import android.util.Slog; 38 39 /** 40 * A service for handling wallpaper effects generation tasks. It must implement 41 * (onGenerateCinematicEffect} method to generate response and call returnCinematicEffectResponse 42 * to send the response. 43 * 44 * <p>To extend this service, you must declare the service in your manifest file with the 45 * {@link android.Manifest.permission#BIND_WALLPAPER_EFFECTS_GENERATION} permission and includes 46 * an intent filter with the {@link #SERVICE_INTERFACE} action. For example: </p> 47 * <pre> 48 * <application> 49 * <service android:name=".CtsWallpaperEffectsGenerationService" 50 * android:exported="true" 51 * android:label="CtsWallpaperEffectsGenerationService" 52 * android:permission="android.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE"> 53 * <intent-filter> 54 * <action android:name="android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService" 55 /> 56 * </intent-filter> 57 * </service> 58 * <uses-library android:name="android.test.runner"/> 59 * </application> 60 * </pre> 61 * 62 * @hide 63 */ 64 @SystemApi 65 public abstract class WallpaperEffectsGenerationService extends Service { 66 /** 67 * The {@link Intent} that must be declared as handled by the service. 68 * 69 * <p>The service must also require the 70 * {@link android.permission#MANAGE_WALLPAPER_EFFECTS_GENERATION} 71 * permission. 72 * 73 */ 74 public static final String SERVICE_INTERFACE = 75 "android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService"; 76 private static final boolean DEBUG = false; 77 private static final String TAG = "WallpaperEffectsGenerationService"; 78 private Handler mHandler; 79 private IWallpaperEffectsGenerationManager mService; 80 81 private final IWallpaperEffectsGenerationService mInterface = 82 new IWallpaperEffectsGenerationService.Stub() { 83 @Override 84 public void onGenerateCinematicEffect(CinematicEffectRequest request) { 85 mHandler.sendMessage( 86 obtainMessage( 87 WallpaperEffectsGenerationService::onGenerateCinematicEffect, 88 WallpaperEffectsGenerationService.this, request)); 89 } 90 }; 91 92 /** 93 * Called when the OS receives a request for generating cinematic effect. On receiving the 94 * request, it extract cinematic information from the input and call 95 * {@link #returnCinematicEffectResponse} with the textured mesh 96 * and metadata wrapped in CinematicEffectResponse. 97 * 98 * @param request the cinematic effect request passed from the client. 99 */ 100 @MainThread onGenerateCinematicEffect(@onNull CinematicEffectRequest request)101 public abstract void onGenerateCinematicEffect(@NonNull CinematicEffectRequest request); 102 103 /** 104 * Returns the cinematic effect response. Must be called when cinematic effect 105 * response is generated and ready to be sent back. Otherwise the response won't be 106 * returned. 107 * 108 * @param response the cinematic effect response returned from service provider. 109 */ returnCinematicEffectResponse(@onNull CinematicEffectResponse response)110 public final void returnCinematicEffectResponse(@NonNull CinematicEffectResponse response) { 111 try { 112 mService.returnCinematicEffectResponse(response); 113 } catch (RemoteException e) { 114 throw e.rethrowFromSystemServer(); 115 } 116 } 117 118 @CallSuper 119 @Override onCreate()120 public void onCreate() { 121 super.onCreate(); 122 if (DEBUG) { 123 Log.d(TAG, "onCreate WallpaperEffectsGenerationService"); 124 } 125 mHandler = new Handler(Looper.getMainLooper(), null, true); 126 IBinder b = ServiceManager.getService(Context.WALLPAPER_EFFECTS_GENERATION_SERVICE); 127 mService = IWallpaperEffectsGenerationManager.Stub.asInterface(b); 128 } 129 130 @NonNull 131 @Override onBind(@onNull Intent intent)132 public final IBinder onBind(@NonNull Intent intent) { 133 if (DEBUG) { 134 Log.d(TAG, "onBind WallpaperEffectsGenerationService"); 135 } 136 if (SERVICE_INTERFACE.equals(intent.getAction())) { 137 return mInterface.asBinder(); 138 } 139 Slog.w(TAG, 140 "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent); 141 return null; 142 } 143 } 144