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