• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.federatedcompute;
18 
19 import android.annotation.CallbackExecutor;
20 import android.annotation.NonNull;
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.federatedcompute.aidl.IFederatedComputeCallback;
24 import android.federatedcompute.aidl.IFederatedComputeService;
25 import android.federatedcompute.common.ScheduleFederatedComputeRequest;
26 import android.os.OutcomeReceiver;
27 
28 import com.android.federatedcompute.internal.util.AbstractServiceBinder;
29 import com.android.federatedcompute.internal.util.LogUtil;
30 
31 import java.util.List;
32 import java.util.Objects;
33 import java.util.concurrent.Executor;
34 
35 /**
36  * FederatedCompute Manager.
37  *
38  * @hide
39  */
40 public final class FederatedComputeManager {
41     /**
42      * Constant that represents the service name for {@link FederatedComputeManager} to be used in
43      * {@link android.ondevicepersonalization.OnDevicePersonalizationFrameworkInitializer
44      * #registerServiceWrappers}
45      *
46      * @hide
47      */
48     public static final String FEDERATED_COMPUTE_SERVICE = "federated_compute_service";
49 
50     private static final String TAG = FederatedComputeManager.class.getSimpleName();
51     private static final String FEDERATED_COMPUTATION_SERVICE_INTENT_FILTER_NAME =
52             "android.federatedcompute.FederatedComputeService";
53     private static final String FEDERATED_COMPUTATION_SERVICE_PACKAGE =
54             "com.android.federatedcompute.services";
55     private static final String ALT_FEDERATED_COMPUTATION_SERVICE_PACKAGE =
56             "com.google.android.federatedcompute";
57 
58     private final Context mContext;
59 
60     private final AbstractServiceBinder<IFederatedComputeService> mServiceBinder;
61 
FederatedComputeManager(Context context)62     public FederatedComputeManager(Context context) {
63         this.mContext = context;
64         this.mServiceBinder =
65                 AbstractServiceBinder.getServiceBinderByIntent(
66                         context,
67                         FEDERATED_COMPUTATION_SERVICE_INTENT_FILTER_NAME,
68                         List.of(
69                                 FEDERATED_COMPUTATION_SERVICE_PACKAGE,
70                                 ALT_FEDERATED_COMPUTATION_SERVICE_PACKAGE),
71                         IFederatedComputeService.Stub::asInterface);
72     }
73 
74     /**
75      * Schedule FederatedCompute task.
76      *
77      * @hide
78      */
schedule( @onNull ScheduleFederatedComputeRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Object, Exception> callback)79     public void schedule(
80             @NonNull ScheduleFederatedComputeRequest request,
81             @NonNull @CallbackExecutor Executor executor,
82             @NonNull OutcomeReceiver<Object, Exception> callback) {
83         Objects.requireNonNull(request);
84         final IFederatedComputeService service = mServiceBinder.getService(executor);
85         try {
86             IFederatedComputeCallback federatedComputeCallback =
87                     new IFederatedComputeCallback.Stub() {
88                         @Override
89                         public void onSuccess() {
90                             LogUtil.d(TAG, ": schedule onSuccess() called");
91                             executor.execute(() -> callback.onResult(null));
92                             unbindFromService();
93                         }
94 
95                         @Override
96                         public void onFailure(int errorCode) {
97                             LogUtil.d(
98                                     TAG,
99                                     ": schedule onFailure() called with errorCode %d",
100                                     errorCode);
101                             executor.execute(
102                                     () ->
103                                             callback.onError(
104                                                     new FederatedComputeException(errorCode)));
105                             unbindFromService();
106                         }
107                     };
108             service.schedule(
109                     mContext.getPackageName(),
110                     request.getTrainingOptions(),
111                     federatedComputeCallback);
112         } catch (Exception e) {
113             LogUtil.e(TAG, e, "Exception when schedule federated job");
114             executor.execute(() -> callback.onError(e));
115             unbindFromService();
116         }
117     }
118 
119     /**
120      * Cancel FederatedCompute task.
121      *
122      * @hide
123      */
cancel( @onNull ComponentName ownerComponent, @NonNull String populationName, @NonNull @CallbackExecutor Executor executor, @NonNull OutcomeReceiver<Object, Exception> callback)124     public void cancel(
125             @NonNull ComponentName ownerComponent,
126             @NonNull String populationName,
127             @NonNull @CallbackExecutor Executor executor,
128             @NonNull OutcomeReceiver<Object, Exception> callback) {
129         Objects.requireNonNull(populationName);
130         final IFederatedComputeService service = mServiceBinder.getService(executor);
131         try {
132             IFederatedComputeCallback federatedComputeCallback =
133                     new IFederatedComputeCallback.Stub() {
134                         @Override
135                         public void onSuccess() {
136                             LogUtil.d(TAG, ": cancel onSuccess() called");
137                             executor.execute(() -> callback.onResult(null));
138                             unbindFromService();
139                         }
140 
141                         @Override
142                         public void onFailure(int errorCode) {
143                             LogUtil.d(
144                                     TAG,
145                                     ": cancel onFailure() called with errorCode %d",
146                                     errorCode);
147                             executor.execute(
148                                     () ->
149                                             callback.onError(
150                                                     new FederatedComputeException(errorCode)));
151                             unbindFromService();
152                         }
153                     };
154             service.cancel(ownerComponent, populationName, federatedComputeCallback);
155         } catch (Exception e) {
156             LogUtil.e(TAG, e, "Exception when cancel federated job %s", populationName);
157             executor.execute(() -> callback.onError(e));
158             unbindFromService();
159         }
160     }
161 
unbindFromService()162     public void unbindFromService() {
163         mServiceBinder.unbindFromService();
164     }
165 }
166