1 /* 2 * Copyright (C) 2024 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.provider; 18 19 import static java.lang.annotation.RetentionPolicy.SOURCE; 20 21 import android.annotation.FlaggedApi; 22 import android.annotation.NonNull; 23 import android.annotation.SystemApi; 24 import android.app.Service; 25 import android.content.Intent; 26 import android.os.CancellationSignal; 27 import android.os.IBinder; 28 import android.provider.mediacognitionutils.GetProcessingVersionsCallbackImpl; 29 import android.provider.mediacognitionutils.ICognitionGetVersionsCallbackInternal; 30 import android.provider.mediacognitionutils.ICognitionProcessMediaCallbackInternal; 31 import android.provider.mediacognitionutils.IMediaCognitionService; 32 import android.provider.mediacognitionutils.ProcessMediaCallbackImpl; 33 import android.util.Log; 34 35 import androidx.annotation.IntDef; 36 import androidx.annotation.Nullable; 37 38 import com.android.providers.media.flags.Flags; 39 40 import java.lang.annotation.Retention; 41 import java.util.List; 42 43 44 /** 45 * <p> Base class for a service which can be implemented by privileged APKs. 46 * This service gets request only from {@link com.android.providers.media.MediaProvider} to extract 47 * data from media using various smart processing like image ocr, image labeling, etc. </p> 48 * 49 * <p> 50 * <h3>Manifest entry</h3> 51 * <p>MediaCognitionService must require the permission 52 * "com.android.providers.media.permission.BIND_MEDIA_COGNITION_SERVICE". </p> 53 * 54 * <pre class="prettyprint"> 55 * {@literal 56 * <service 57 * android:name=".MyMediaCognitionService" 58 * android:exported="true" 59 * android:permission="com.android.providers.media.permission.BIND_MEDIA_COGNITION_SERVICE"> 60 * <intent-filter> 61 * <action android:name="android.provider.MediaCognitionService" /> 62 * <category android:name="android.intent.category.DEFAULT"/> 63 * </intent-filter> 64 * </service>} 65 * </pre> 66 * </p> 67 * 68 * Only one instance of MediaCognitionService will be in function at a time. 69 * OEMs can specify the default MediaCognitionService through runtime resource overlay, 70 * by setting value of the resource {@code config_default_media_cognition_service_package}. 71 * The overlayable subset which has this resource is {@code MediaProviderConfig} 72 * 73 * @hide 74 */ 75 @SystemApi 76 @FlaggedApi(Flags.FLAG_MEDIA_COGNITION_SERVICE) 77 public abstract class MediaCognitionService extends Service { 78 79 /** 80 * @hide 81 */ 82 public static final String TAG = "MediaCognitionService"; 83 84 public static final String SERVICE_INTERFACE = "android.provider.MediaCognitionService"; 85 86 /** 87 * Permission required to protect {@link MediaCognitionService} instances. Implementation should 88 * require this in the {@code permission} attribute in their {@code <service>} tag. 89 * The OS will not bind to a service without this protection. 90 */ 91 public static final String BIND_MEDIA_COGNITION_SERVICE = 92 "com.android.providers.media.permission.BIND_MEDIA_COGNITION_SERVICE"; 93 94 /** 95 * This contains variables representing different processing types that 96 * MediaProvider can request the service. 97 */ 98 public interface ProcessingTypes { 99 /** 100 * Variable for representing processing of image ocr of latin script. 101 */ 102 public static final int IMAGE_OCR_LATIN = 1 << 0; 103 104 /** 105 * Variable for representing processing of image labeling. 106 */ 107 public static final int IMAGE_LABEL = 1 << 1; 108 } 109 110 /** 111 * IntDef for bitmasks of ProcessingTypes 112 * @hide 113 */ 114 @IntDef(flag = true, value = {ProcessingTypes.IMAGE_OCR_LATIN, 115 ProcessingTypes.IMAGE_LABEL}) 116 @Retention(SOURCE) 117 public @interface ProcessingCombination { 118 } 119 120 /** 121 * IntDef for the values in ProcessingTypes. No bitmask. 122 * @hide 123 */ 124 @IntDef(value = {ProcessingTypes.IMAGE_OCR_LATIN, 125 ProcessingTypes.IMAGE_LABEL}) 126 @Retention(SOURCE) 127 public @interface ProcessingType { 128 } 129 130 @Override 131 @Nullable onBind(@ullable Intent intent)132 public final IBinder onBind(@Nullable Intent intent) { 133 if (!SERVICE_INTERFACE.equals(intent.getAction())) { 134 Log.w(TAG, "Wrong action"); 135 return null; 136 } 137 return mInterface.asBinder(); 138 } 139 140 /** 141 * <p> Implement this to process media for different cognition processing. Return the results 142 * through the callback. For every {@link MediaCognitionProcessingRequest} prepare a 143 * {@link MediaCognitionProcessingResponse} and return list of responses 144 * through the callback function: {@link MediaCognitionProcessingCallback#onSuccess(List)}. 145 * The responses must be returned all at once, for all the requests given. 146 * If one of the request could not be processed, add an empty response for that specific request 147 * in the returned responses. 148 * </p> 149 * <p> Each MediaCognitionProcessingRequest object contains a checker function 150 * {@link MediaCognitionProcessingRequest#checkProcessingRequired(int)} in which you can pass any 151 * processing type from the available ones here: {@link ProcessingTypes}. 152 * If the request requires a processing include the result 153 * in {@link MediaCognitionProcessingResponse}. 154 * </p> 155 * 156 * 157 * 158 * <p> There is a time limit to respond to the callback. 159 * Callback must be responded within less than 5 minutes.</p> 160 * 161 * @param requests List of {@link MediaCognitionProcessingRequest} 162 * @param cancellationSignal Signal to attach a listener to, and receive cancellation signals 163 * from the client. 164 * @param callback Callback for giving the result 165 */ onProcessMedia(@onNull List<MediaCognitionProcessingRequest> requests, @Nullable CancellationSignal cancellationSignal, @NonNull MediaCognitionProcessingCallback callback)166 public abstract void onProcessMedia(@NonNull List<MediaCognitionProcessingRequest> requests, 167 @Nullable CancellationSignal cancellationSignal, 168 @NonNull MediaCognitionProcessingCallback callback); 169 170 /** 171 * <p>Implement this to return version of all processing types. 172 * This will be used by MediaProvider to assess if reprocessing is required, 173 * once the version changes. </p> 174 * 175 * <p>Set versions of each processing types available here: {@link ProcessingTypes}. 176 * The result need to be composed using {@link MediaCognitionProcessingVersions}. 177 * Return the result via the callback function: 178 * {@link MediaCognitionGetVersionsCallback#onSuccess(MediaCognitionProcessingVersions)} 179 * </p> 180 * 181 * <p> There is a time limit to respond to the callback. 182 * Callback must be responded within less than 5 minutes.</p> 183 * 184 */ onGetProcessingVersions( @onNull MediaCognitionGetVersionsCallback callback)185 public abstract void onGetProcessingVersions( 186 @NonNull MediaCognitionGetVersionsCallback callback); 187 188 189 private final IMediaCognitionService mInterface = new IMediaCognitionService.Stub() { 190 @Override 191 public void processMedia(List<MediaCognitionProcessingRequest> requests, 192 ICognitionProcessMediaCallbackInternal binderCallback) { 193 onProcessMedia(requests, null, new ProcessMediaCallbackImpl(binderCallback)); 194 } 195 196 @Override 197 public void getProcessingVersions(ICognitionGetVersionsCallbackInternal binderCallback) { 198 onGetProcessingVersions(new GetProcessingVersionsCallbackImpl(binderCallback)); 199 } 200 }; 201 202 } 203