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 com.android.ondevicepersonalization.services.process; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.ondevicepersonalization.IsolatedComputationService; 22 import android.ondevicepersonalization.aidl.IIsolatedComputationService; 23 import android.ondevicepersonalization.aidl.IIsolatedComputationServiceCallback; 24 import android.os.Bundle; 25 import android.os.RemoteException; 26 import android.util.Log; 27 28 import com.android.ondevicepersonalization.libraries.plugin.FailureType; 29 import com.android.ondevicepersonalization.libraries.plugin.Plugin; 30 import com.android.ondevicepersonalization.libraries.plugin.PluginCallback; 31 import com.android.ondevicepersonalization.libraries.plugin.PluginContext; 32 33 /** Plugin that runs in an isolated process. */ 34 public class OnDevicePersonalizationPlugin implements Plugin { 35 private static final String TAG = "OnDevicePersonalizationPlugin"; 36 private Bundle mInput; 37 private PluginCallback mPluginCallback; 38 private PluginContext mPluginContext; 39 private ClassLoader mClassLoader; 40 41 @Override setClassLoader(ClassLoader classLoader)42 public void setClassLoader(ClassLoader classLoader) { 43 mClassLoader = classLoader; 44 } 45 46 @Override onExecute( @onNull Bundle input, @NonNull PluginCallback callback, @Nullable PluginContext pluginContext)47 public void onExecute( 48 @NonNull Bundle input, 49 @NonNull PluginCallback callback, 50 @Nullable PluginContext pluginContext) { 51 Log.d(TAG, "Executing plugin: " + input.toString()); 52 mInput = input; 53 mPluginCallback = callback; 54 mPluginContext = pluginContext; 55 56 try { 57 String className = input.getString(ProcessUtils.PARAM_CLASS_NAME_KEY); 58 if (className == null || className.isEmpty()) { 59 Log.e(TAG, "className missing."); 60 sendErrorResult(FailureType.ERROR_EXECUTING_PLUGIN); 61 return; 62 } 63 64 int operation = input.getInt(ProcessUtils.PARAM_OPERATION_KEY); 65 if (operation == 0) { 66 Log.e(TAG, "operation missing or invalid."); 67 sendErrorResult(FailureType.ERROR_EXECUTING_PLUGIN); 68 return; 69 } 70 71 Bundle serviceParams = input.getParcelable(ProcessUtils.PARAM_SERVICE_INPUT, 72 Bundle.class); 73 if (serviceParams == null) { 74 Log.e(TAG, "Missing service input."); 75 sendErrorResult(FailureType.ERROR_EXECUTING_PLUGIN); 76 return; 77 } 78 79 Class<?> clazz = Class.forName(className, true, mClassLoader); 80 IsolatedComputationService service = 81 (IsolatedComputationService) clazz.getDeclaredConstructor().newInstance(); 82 // TODO(b/249345663): Set the 'Context' for the service. 83 service.onCreate(); 84 IIsolatedComputationService binder = 85 (IIsolatedComputationService) service.onBind(null); 86 87 binder.onRequest(operation, serviceParams, 88 new IIsolatedComputationServiceCallback.Stub() { 89 @Override public void onSuccess(Bundle result) { 90 try { 91 mPluginCallback.onSuccess(result); 92 } catch (RemoteException e) { 93 Log.e(TAG, "Callback error.", e); 94 } 95 } 96 @Override public void onError(int errorCode) { 97 try { 98 mPluginCallback.onFailure(FailureType.ERROR_EXECUTING_PLUGIN); 99 } catch (RemoteException e) { 100 Log.e(TAG, "Callback error.", e); 101 } 102 } 103 } 104 ); 105 106 } catch (Exception e) { 107 Log.e(TAG, "Plugin failed. ", e); 108 sendErrorResult(FailureType.ERROR_EXECUTING_PLUGIN); 109 } 110 } 111 sendErrorResult(FailureType failure)112 private void sendErrorResult(FailureType failure) { 113 try { 114 mPluginCallback.onFailure(failure); 115 } catch (RemoteException e) { 116 Log.e(TAG, "Callback error.", e); 117 } 118 } 119 } 120