• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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