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;
18 
19 import static android.adservices.ondevicepersonalization.OnDevicePersonalizationPermissions.NOTIFY_MEASUREMENT_EVENT;
20 
21 import static com.android.adservices.shared.spe.JobServiceConstants.SCHEDULING_RESULT_CODE_SUCCESSFUL;
22 
23 import static com.google.common.util.concurrent.Futures.immediateVoidFuture;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertThrows;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.anyBoolean;
30 import static org.mockito.Mockito.doReturn;
31 import static org.mockito.Mockito.spy;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.adservices.ondevicepersonalization.CalleeMetadata;
37 import android.adservices.ondevicepersonalization.CallerMetadata;
38 import android.adservices.ondevicepersonalization.Constants;
39 import android.adservices.ondevicepersonalization.aidl.IExecuteCallback;
40 import android.adservices.ondevicepersonalization.aidl.IRegisterMeasurementEventCallback;
41 import android.adservices.ondevicepersonalization.aidl.IRequestSurfacePackageCallback;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.pm.PackageManager;
46 import android.os.Binder;
47 import android.os.Bundle;
48 import android.os.IBinder;
49 import android.os.PersistableBundle;
50 import android.view.SurfaceControlViewHost;
51 
52 import androidx.test.core.app.ApplicationProvider;
53 import androidx.test.rule.ServiceTestRule;
54 
55 import com.android.dx.mockito.inline.extended.ExtendedMockito;
56 import com.android.modules.utils.testing.ExtendedMockitoRule;
57 import com.android.odp.module.common.DeviceUtils;
58 import com.android.ondevicepersonalization.internal.util.ByteArrayParceledSlice;
59 import com.android.ondevicepersonalization.internal.util.PersistableBundleUtils;
60 import com.android.ondevicepersonalization.services.data.user.UserDataCollectionJobService;
61 import com.android.ondevicepersonalization.services.data.user.UserPrivacyStatus;
62 import com.android.ondevicepersonalization.services.download.mdd.MobileDataDownloadFactory;
63 import com.android.ondevicepersonalization.services.maintenance.OnDevicePersonalizationMaintenanceJobService;
64 
65 import com.google.android.libraries.mobiledatadownload.MobileDataDownload;
66 
67 import org.junit.Before;
68 import org.junit.Rule;
69 import org.junit.Test;
70 import org.junit.runner.RunWith;
71 import org.junit.runners.JUnit4;
72 import org.mockito.Mock;
73 import org.mockito.Spy;
74 import org.mockito.quality.Strictness;
75 
76 import java.util.concurrent.CountDownLatch;
77 import java.util.concurrent.TimeoutException;
78 
79 @RunWith(JUnit4.class)
80 public class OnDevicePersonalizationManagingServiceTest {
81     @Rule
82     public final ServiceTestRule serviceRule = new ServiceTestRule();
83     private final Context mContext = spy(ApplicationProvider.getApplicationContext());
84     private OnDevicePersonalizationManagingServiceDelegate mService =
85             new OnDevicePersonalizationManagingServiceDelegate(mContext);
86 
87     @Mock
88     private UserPrivacyStatus mUserPrivacyStatus;
89     @Mock private MobileDataDownload mMockMdd;
90     @Spy
91     private Flags mSpyFlags = spy(FlagsFactory.getFlags());
92     @Rule
93     public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
94             .mockStatic(FlagsFactory.class)
95             .spyStatic(UserPrivacyStatus.class)
96             .spyStatic(DeviceUtils.class)
97             .spyStatic(OnDevicePersonalizationMaintenanceJobService.class)
98             .spyStatic(UserDataCollectionJobService.class)
99             .spyStatic(MobileDataDownloadFactory.class)
100             .setStrictness(Strictness.LENIENT)
101             .build();
102 
103     @Before
setup()104     public void setup() throws Exception {
105         ExtendedMockito.doReturn(mSpyFlags).when(FlagsFactory::getFlags);
106         when(mSpyFlags.getGlobalKillSwitch()).thenReturn(false);
107         PhFlagsTestUtil.setUpDeviceConfigPermissions();
108         ExtendedMockito.doReturn(true).when(() -> DeviceUtils.isOdpSupported(any()));
109         ExtendedMockito.doReturn(mUserPrivacyStatus).when(UserPrivacyStatus::getInstance);
110         doReturn(true).when(mUserPrivacyStatus).isMeasurementEnabled();
111         doReturn(true).when(mUserPrivacyStatus).isProtectedAudienceEnabled();
112         when(mContext.checkCallingPermission(NOTIFY_MEASUREMENT_EVENT))
113                 .thenReturn(PackageManager.PERMISSION_GRANTED);
114 
115         ExtendedMockito.doReturn(SCHEDULING_RESULT_CODE_SUCCESSFUL)
116                 .when(
117                         () ->
118                                 OnDevicePersonalizationMaintenanceJobService.schedule(
119                                         any(), anyBoolean()));
120         ExtendedMockito.doReturn(1).when(() -> UserDataCollectionJobService.schedule(any()));
121         ExtendedMockito.doReturn(mMockMdd).when(() -> MobileDataDownloadFactory.getMdd(any()));
122         doReturn(immediateVoidFuture()).when(mMockMdd).schedulePeriodicBackgroundTasks();
123     }
124 
125     @Test
testVersion()126     public void testVersion() throws Exception {
127         assertEquals(mService.getVersion(), "1.0");
128     }
129 
130     @Test
testEnabledGlobalKillSwitchOnExecute()131     public void testEnabledGlobalKillSwitchOnExecute() throws Exception {
132         when(mSpyFlags.getGlobalKillSwitch()).thenReturn(true);
133         var callback = new ExecuteCallback();
134         assertThrows(
135                 IllegalStateException.class,
136                 () ->
137                         mService.execute(
138                                 mContext.getPackageName(),
139                                 new ComponentName(
140                                         mContext.getPackageName(),
141                                         "com.test.TestPersonalizationHandler"),
142                                 createWrappedAppParams(),
143                                 new CallerMetadata.Builder().build(),
144                                 callback
145                         ));
146     }
147 
148     @Test
testUnsupportedDeviceOnExecute()149     public void testUnsupportedDeviceOnExecute() throws Exception {
150         ExtendedMockito.doReturn(false).when(() -> DeviceUtils.isOdpSupported(any()));
151         assertThrows(
152                 IllegalStateException.class,
153                 () ->
154                         mService.execute(
155                                 mContext.getPackageName(),
156                                 new ComponentName(
157                                         mContext.getPackageName(),
158                                         "com.test.TestPersonalizationHandler"),
159                                 createWrappedAppParams(),
160                                 new CallerMetadata.Builder().build(),
161                                 new ExecuteCallback()
162                         ));
163     }
164 
165     @Test
testExecuteInvokesAppRequestFlow()166     public void testExecuteInvokesAppRequestFlow() throws Exception {
167         var callback = new ExecuteCallback();
168         mService.execute(
169                 mContext.getPackageName(),
170                 new ComponentName(
171                         mContext.getPackageName(), "com.test.TestPersonalizationHandler"),
172                 createWrappedAppParams(),
173                 new CallerMetadata.Builder().build(),
174                 callback);
175         callback.await();
176         assertTrue(callback.mWasInvoked);
177     }
178 
179     @Test
testExecuteThrowsIfAppPackageNameIncorrect()180     public void testExecuteThrowsIfAppPackageNameIncorrect() throws Exception {
181         var callback = new ExecuteCallback();
182         assertThrows(
183                 SecurityException.class,
184                 () ->
185                         mService.execute(
186                                 "abc",
187                                 new ComponentName(
188                                         mContext.getPackageName(),
189                                         "com.test.TestPersonalizationHandler"),
190                                 createWrappedAppParams(),
191                                 new CallerMetadata.Builder().build(),
192                                 callback));
193     }
194 
195     @Test
testExecuteThrowsIfAppPackageNameNull()196     public void testExecuteThrowsIfAppPackageNameNull() throws Exception {
197         var callback = new ExecuteCallback();
198         assertThrows(
199                 NullPointerException.class,
200                 () ->
201                         mService.execute(
202                                 null,
203                                 new ComponentName(
204                                         mContext.getPackageName(),
205                                         "com.test.TestPersonalizationHandler"),
206                                 createWrappedAppParams(),
207                                 new CallerMetadata.Builder().build(),
208                                 callback));
209     }
210 
211     @Test
testExecuteThrowsIfAppPackageNameMissing()212     public void testExecuteThrowsIfAppPackageNameMissing() throws Exception {
213         var callback = new ExecuteCallback();
214         assertThrows(
215                 IllegalArgumentException.class,
216                 () ->
217                         mService.execute(
218                                 "",
219                                 new ComponentName(
220                                         mContext.getPackageName(),
221                                         "com.test.TestPersonalizationHandler"),
222                                 createWrappedAppParams(),
223                                 new CallerMetadata.Builder().build(),
224                                 callback));
225     }
226 
227     @Test
testExecuteThrowsIfHandlerMissing()228     public void testExecuteThrowsIfHandlerMissing() throws Exception {
229         var callback = new ExecuteCallback();
230         assertThrows(
231                 NullPointerException.class,
232                 () ->
233                         mService.execute(
234                                 mContext.getPackageName(),
235                                 null,
236                                 createWrappedAppParams(),
237                                 new CallerMetadata.Builder().build(),
238                                 callback));
239     }
240 
241     @Test
testExecuteThrowsIfServicePackageMissing()242     public void testExecuteThrowsIfServicePackageMissing() throws Exception {
243         var callback = new ExecuteCallback();
244         assertThrows(
245                 IllegalArgumentException.class,
246                 () ->
247                         mService.execute(
248                                 mContext.getPackageName(),
249                                 new ComponentName("", "ServiceClass"),
250                                 createWrappedAppParams(),
251                                 new CallerMetadata.Builder().build(),
252                                 callback));
253     }
254 
255     @Test
testExecuteThrowsIfServiceClassMissing()256     public void testExecuteThrowsIfServiceClassMissing() throws Exception {
257         var callback = new ExecuteCallback();
258         assertThrows(
259                 IllegalArgumentException.class,
260                 () ->
261                         mService.execute(
262                                 mContext.getPackageName(),
263                                 new ComponentName("com.test.TestPackage", ""),
264                                 createWrappedAppParams(),
265                                 new CallerMetadata.Builder().build(),
266                                 callback));
267     }
268 
269     @Test
testExecuteThrowsIfMetadataMissing()270     public void testExecuteThrowsIfMetadataMissing() throws Exception {
271         var callback = new ExecuteCallback();
272         assertThrows(
273                 NullPointerException.class,
274                 () ->
275                         mService.execute(
276                                 mContext.getPackageName(),
277                                 new ComponentName(
278                                         mContext.getPackageName(),
279                                         "com.test.TestPersonalizationHandler"),
280                                 createWrappedAppParams(),
281                                 null,
282                                 callback));
283     }
284 
285     @Test
testExecuteThrowsIfCallbackMissing()286     public void testExecuteThrowsIfCallbackMissing() throws Exception {
287         assertThrows(
288                 NullPointerException.class,
289                 () ->
290                         mService.execute(
291                                 mContext.getPackageName(),
292                                 new ComponentName(
293                                         mContext.getPackageName(),
294                                         "com.test.TestPersonalizationHandler"),
295                                 createWrappedAppParams(),
296                                 new CallerMetadata.Builder().build(),
297                                 null));
298     }
299 
300     @Test
testExecuteThrowsIfCallerNotEnrolled()301     public void testExecuteThrowsIfCallerNotEnrolled() throws Exception {
302         var callback = new ExecuteCallback();
303         var originalCallerAppAllowList = mSpyFlags.getCallerAppAllowList();
304         PhFlagsTestUtil.setCallerAppAllowList("");
305         try {
306             assertThrows(
307                     IllegalStateException.class,
308                     () ->
309                             mService.execute(
310                                     mContext.getPackageName(),
311                                     new ComponentName(
312                                             mContext.getPackageName(),
313                                             "com.test.TestPersonalizationHandler"),
314                                     createWrappedAppParams(),
315                                     new CallerMetadata.Builder().build(),
316                                     callback));
317         } finally {
318             PhFlagsTestUtil.setCallerAppAllowList(originalCallerAppAllowList);
319         }
320     }
321 
322     @Test
testExecuteThrowsIfIsolatedServiceNotEnrolled()323     public void testExecuteThrowsIfIsolatedServiceNotEnrolled() throws Exception {
324         var callback = new ExecuteCallback();
325         var originalIsolatedServiceAllowList =
326                 FlagsFactory.getFlags().getIsolatedServiceAllowList();
327         PhFlagsTestUtil.setIsolatedServiceAllowList("");
328         try {
329             assertThrows(
330                     IllegalStateException.class,
331                     () ->
332                             mService.execute(
333                                     mContext.getPackageName(),
334                                     new ComponentName(
335                                             mContext.getPackageName(),
336                                             "com.test.TestPersonalizationHandler"),
337                                     createWrappedAppParams(),
338                                     new CallerMetadata.Builder().build(),
339                                     callback));
340         } finally {
341             PhFlagsTestUtil.setIsolatedServiceAllowList(originalIsolatedServiceAllowList);
342         }
343     }
344 
345     @Test
testEnabledGlobalKillSwitchOnRequestSurfacePackage()346     public void testEnabledGlobalKillSwitchOnRequestSurfacePackage() throws Exception {
347         when(mSpyFlags.getGlobalKillSwitch()).thenReturn(true);
348         var callback = new RequestSurfacePackageCallback();
349         assertThrows(
350                 IllegalStateException.class,
351                 () ->
352                         mService.requestSurfacePackage(
353                                 "resultToken",
354                                 new Binder(),
355                                 0,
356                                 100,
357                                 50,
358                                 new CallerMetadata.Builder().build(),
359                                 callback
360                         ));
361     }
362 
363     @Test
testUnsupportedDeviceOnRequestSurfacePackage()364     public void testUnsupportedDeviceOnRequestSurfacePackage() throws Exception {
365         ExtendedMockito.doReturn(false).when(() -> DeviceUtils.isOdpSupported(any()));
366         var callback = new RequestSurfacePackageCallback();
367         assertThrows(
368                 IllegalStateException.class,
369                 () ->
370                         mService.requestSurfacePackage(
371                                 "resultToken",
372                                 new Binder(),
373                                 0,
374                                 100,
375                                 50,
376                                 new CallerMetadata.Builder().build(),
377                                 callback
378                         ));
379     }
380 
381     @Test
testRequestSurfacePackageInvokesRenderFlow()382     public void testRequestSurfacePackageInvokesRenderFlow() throws Exception {
383         var callback = new RequestSurfacePackageCallback();
384         mService.requestSurfacePackage(
385                 "resultToken",
386                 new Binder(),
387                 0,
388                 100,
389                 50,
390                 new CallerMetadata.Builder().build(),
391                 callback);
392         callback.await();
393         assertTrue(callback.mWasInvoked);
394     }
395 
396     @Test
testRequestSurfacePackageThrowsIfSlotResultTokenMissing()397     public void testRequestSurfacePackageThrowsIfSlotResultTokenMissing() throws Exception {
398         var callback = new RequestSurfacePackageCallback();
399         assertThrows(
400                 NullPointerException.class,
401                 () ->
402                         mService.requestSurfacePackage(
403                                 null,
404                                 new Binder(),
405                                 0,
406                                 100,
407                                 50,
408                                 new CallerMetadata.Builder().build(),
409                                 callback));
410     }
411 
412     @Test
testRequestSurfacePackageThrowsIfHostTokenMissing()413     public void testRequestSurfacePackageThrowsIfHostTokenMissing() throws Exception {
414         var callback = new RequestSurfacePackageCallback();
415         assertThrows(
416                 NullPointerException.class,
417                 () ->
418                         mService.requestSurfacePackage(
419                                 "resultToken",
420                                 null,
421                                 0,
422                                 100,
423                                 50,
424                                 new CallerMetadata.Builder().build(),
425                                 callback));
426     }
427 
428     @Test
testRequestSurfacePackageThrowsIfDisplayIdInvalid()429     public void testRequestSurfacePackageThrowsIfDisplayIdInvalid() throws Exception {
430         var callback = new RequestSurfacePackageCallback();
431         assertThrows(
432                 IllegalArgumentException.class,
433                 () ->
434                         mService.requestSurfacePackage(
435                                 "resultToken",
436                                 new Binder(),
437                                 -1,
438                                 100,
439                                 50,
440                                 new CallerMetadata.Builder().build(),
441                                 callback));
442     }
443 
444     @Test
testRequestSurfacePackageThrowsIfWidthInvalid()445     public void testRequestSurfacePackageThrowsIfWidthInvalid() throws Exception {
446         var callback = new RequestSurfacePackageCallback();
447         assertThrows(
448                 IllegalArgumentException.class,
449                 () ->
450                         mService.requestSurfacePackage(
451                                 "resultToken",
452                                 new Binder(),
453                                 0,
454                                 0,
455                                 50,
456                                 new CallerMetadata.Builder().build(),
457                                 callback));
458     }
459 
460     @Test
testRequestSurfacePackageThrowsIfHeightInvalid()461     public void testRequestSurfacePackageThrowsIfHeightInvalid() throws Exception {
462         var callback = new RequestSurfacePackageCallback();
463         assertThrows(
464                 IllegalArgumentException.class,
465                 () ->
466                         mService.requestSurfacePackage(
467                                 "resultToken",
468                                 new Binder(),
469                                 0,
470                                 100,
471                                 0,
472                                 new CallerMetadata.Builder().build(),
473                                 callback));
474     }
475 
476     @Test
testRequestSurfacePackageThrowsIfMetadataMissing()477     public void testRequestSurfacePackageThrowsIfMetadataMissing() throws Exception {
478         var callback = new RequestSurfacePackageCallback();
479         assertThrows(
480                 NullPointerException.class,
481                 () ->
482                         mService.requestSurfacePackage(
483                                 "resultToken",
484                                 new Binder(),
485                                 0,
486                                 100,
487                                 50,
488                                 null,
489                                 callback));
490     }
491 
492     @Test
testRequestSurfacePackageThrowsIfCallbackMissing()493     public void testRequestSurfacePackageThrowsIfCallbackMissing() throws Exception {
494         assertThrows(
495                 NullPointerException.class,
496                 () ->
497                         mService.requestSurfacePackage(
498                                 "resultToken",
499                                 new Binder(),
500                                 0,
501                                 100,
502                                 50,
503                                 new CallerMetadata.Builder().build(),
504                                 null));
505     }
506 
507     @Test
testEnabledGlobalKillSwitchOnRegisterMeasurementEvent()508     public void testEnabledGlobalKillSwitchOnRegisterMeasurementEvent() throws Exception {
509         when(mSpyFlags.getGlobalKillSwitch()).thenReturn(true);
510         assertThrows(
511                 IllegalStateException.class,
512                 () ->
513                         mService.registerMeasurementEvent(
514                                 Constants.MEASUREMENT_EVENT_TYPE_WEB_TRIGGER,
515                                 Bundle.EMPTY,
516                                 new CallerMetadata.Builder().build(),
517                                 new RegisterMeasurementEventCallback()));
518     }
519 
520     @Test
testUnsupportedDeviceOnRegisterMeasurementEvent()521     public void testUnsupportedDeviceOnRegisterMeasurementEvent() throws Exception {
522         ExtendedMockito.doReturn(false).when(() -> DeviceUtils.isOdpSupported(any()));
523         assertThrows(
524                 IllegalStateException.class,
525                 () ->
526                         mService.registerMeasurementEvent(
527                                 Constants.MEASUREMENT_EVENT_TYPE_WEB_TRIGGER,
528                                 Bundle.EMPTY,
529                                 new CallerMetadata.Builder().build(),
530                                 new RegisterMeasurementEventCallback()));
531     }
532 
533     @Test
testRegisterMeasurementEventPermissionDenied()534     public void testRegisterMeasurementEventPermissionDenied() throws Exception {
535         when(mContext.checkCallingPermission(NOTIFY_MEASUREMENT_EVENT))
536                 .thenReturn(PackageManager.PERMISSION_DENIED);
537         assertThrows(
538                 SecurityException.class,
539                 () ->
540                         mService.registerMeasurementEvent(
541                                 Constants.MEASUREMENT_EVENT_TYPE_WEB_TRIGGER,
542                                 Bundle.EMPTY,
543                                 new CallerMetadata.Builder().build(),
544                                 new RegisterMeasurementEventCallback()));
545     }
546 
547     @Test
testRegisterMeasurementEventInvokesWebTriggerFlow()548     public void testRegisterMeasurementEventInvokesWebTriggerFlow() throws Exception {
549         var callback = new RegisterMeasurementEventCallback();
550         mService.registerMeasurementEvent(
551                 Constants.MEASUREMENT_EVENT_TYPE_WEB_TRIGGER,
552                 Bundle.EMPTY,
553                 new CallerMetadata.Builder().build(),
554                 callback);
555         callback.await();
556         assertTrue(callback.mWasInvoked);
557     }
558 
559     @Test
testWithBoundService()560     public void testWithBoundService() throws TimeoutException {
561         Intent serviceIntent = new Intent(mContext,
562                 OnDevicePersonalizationManagingServiceImpl.class);
563         IBinder binder = serviceRule.bindService(serviceIntent);
564         assertTrue(binder instanceof OnDevicePersonalizationManagingServiceDelegate);
565     }
566 
567     @Test
testJobRestoring()568     public void testJobRestoring() {
569         OnDevicePersonalizationManagingServiceImpl service =
570                 new OnDevicePersonalizationManagingServiceImpl(Runnable::run);
571         service.onCreate();
572         Intent serviceIntent =
573                 new Intent(mContext, OnDevicePersonalizationManagingServiceImpl.class);
574         IBinder binder = service.onBind(serviceIntent);
575         assertTrue(binder instanceof OnDevicePersonalizationManagingServiceDelegate);
576         ExtendedMockito.verify(
577                 () -> OnDevicePersonalizationMaintenanceJobService.schedule(any(), anyBoolean()));
578         ExtendedMockito.verify(() -> UserDataCollectionJobService.schedule(any()), times(1));
579         verify(mMockMdd).schedulePeriodicBackgroundTasks();
580     }
581 
createWrappedAppParams()582     private Bundle createWrappedAppParams() throws Exception {
583         Bundle wrappedParams = new Bundle();
584         ByteArrayParceledSlice buffer = new ByteArrayParceledSlice(
585                 PersistableBundleUtils.toByteArray(PersistableBundle.EMPTY));
586         wrappedParams.putParcelable(Constants.EXTRA_APP_PARAMS_SERIALIZED, buffer);
587         return wrappedParams;
588     }
589 
590     static class ExecuteCallback extends IExecuteCallback.Stub {
591         public boolean mWasInvoked = false;
592         public boolean mSuccess = false;
593         public boolean mError = false;
594         public int mErrorCode = 0;
595         public int mIsolatedServiceErrorCode = 0;
596         public String mErrorMessage = null;
597         public String mToken = null;
598         private final CountDownLatch mLatch = new CountDownLatch(1);
599 
600         @Override
onSuccess(Bundle bundle, CalleeMetadata calleeMetadata)601         public void onSuccess(Bundle bundle, CalleeMetadata calleeMetadata) {
602             if (bundle != null) {
603                 mToken = bundle.getString(Constants.EXTRA_SURFACE_PACKAGE_TOKEN_STRING);
604             }
605             mWasInvoked = true;
606             mSuccess = true;
607             mLatch.countDown();
608         }
609 
610         @Override
onError(int errorCode, int isolatedServiceErrorCode, String message, CalleeMetadata calleeMetadata)611         public void onError(int errorCode, int isolatedServiceErrorCode, String message,
612                 CalleeMetadata calleeMetadata) {
613             mWasInvoked = true;
614             mError = true;
615             mErrorCode = errorCode;
616             mIsolatedServiceErrorCode = isolatedServiceErrorCode;
617             mErrorMessage = message;
618             mLatch.countDown();
619         }
620 
await()621         public void await() throws Exception {
622             mLatch.await();
623         }
624     }
625 
626     static class RequestSurfacePackageCallback extends IRequestSurfacePackageCallback.Stub {
627         public boolean mWasInvoked = false;
628         public boolean mSuccess = false;
629         public boolean mError = false;
630         public int mErrorCode = 0;
631         public int mIsolatedServiceErrorCode = 0;
632         public String mErrorMessage = null;
633         private final CountDownLatch mLatch = new CountDownLatch(1);
634 
635         @Override
onSuccess(SurfaceControlViewHost.SurfacePackage s, CalleeMetadata calleeMetadata)636         public void onSuccess(SurfaceControlViewHost.SurfacePackage s,
637                 CalleeMetadata calleeMetadata) {
638             mWasInvoked = true;
639             mSuccess = true;
640             mLatch.countDown();
641         }
642 
643         @Override
onError(int errorCode, int isolatedServiceErrorCode, String message, CalleeMetadata calleeMetadata)644         public void onError(int errorCode, int isolatedServiceErrorCode, String message,
645                 CalleeMetadata calleeMetadata) {
646             mWasInvoked = true;
647             mError = true;
648             mErrorCode = errorCode;
649             mIsolatedServiceErrorCode = isolatedServiceErrorCode;
650             mErrorMessage = message;
651             mLatch.countDown();
652         }
653 
await()654         public void await() throws Exception {
655             mLatch.await();
656         }
657     }
658 
659     static class RegisterMeasurementEventCallback extends IRegisterMeasurementEventCallback.Stub {
660         public boolean mError = false;
661         public boolean mSuccess = false;
662         public boolean mWasInvoked = false;
663         public int mErrorCode = 0;
664         private final CountDownLatch mLatch = new CountDownLatch(1);
665 
666         @Override
onSuccess(CalleeMetadata calleeMetadata)667         public void onSuccess(CalleeMetadata calleeMetadata) {
668             mWasInvoked = true;
669             mSuccess = true;
670             mLatch.countDown();
671         }
672 
673         @Override
onError(int errorCode, CalleeMetadata calleeMetadata)674         public void onError(int errorCode, CalleeMetadata calleeMetadata) {
675             mWasInvoked = true;
676             mError = true;
677             mErrorCode = errorCode;
678             mLatch.countDown();
679         }
680 
await()681         public void await() throws Exception {
682             mLatch.await();
683         }
684     }
685 }
686