1 /* 2 * Copyright (C) 2020 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.app; 18 19 import android.annotation.Nullable; 20 import android.annotation.RequiresPermission; 21 import android.content.ComponentName; 22 import android.content.Intent; 23 import android.content.res.Configuration; 24 import android.content.res.Resources; 25 import android.os.Bundle; 26 import android.os.IBinder; 27 import android.os.IRemoteCallback; 28 import android.os.PersistableBundle; 29 import android.os.RemoteException; 30 import android.util.Singleton; 31 import android.view.RemoteAnimationDefinition; 32 import android.window.SizeConfigurationBuckets; 33 34 import com.android.internal.policy.IKeyguardDismissCallback; 35 36 /** 37 * Provides the activity associated operations that communicate with system. 38 * 39 * @hide 40 */ 41 public class ActivityClient { ActivityClient()42 private ActivityClient() {} 43 44 /** Reports the main thread is idle after the activity is resumed. */ activityIdle(IBinder token, Configuration config, boolean stopProfiling)45 public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 46 try { 47 getActivityClientController().activityIdle(token, config, stopProfiling); 48 } catch (RemoteException e) { 49 e.rethrowFromSystemServer(); 50 } 51 } 52 53 /** Reports {@link Activity#onResume()} is done. */ activityResumed(IBinder token, boolean handleSplashScreenExit)54 public void activityResumed(IBinder token, boolean handleSplashScreenExit) { 55 try { 56 getActivityClientController().activityResumed(token, handleSplashScreenExit); 57 } catch (RemoteException e) { 58 e.rethrowFromSystemServer(); 59 } 60 } 61 62 /** Reports {@link android.app.servertransaction.RefreshCallbackItem} is executed. */ activityRefreshed(IBinder token)63 public void activityRefreshed(IBinder token) { 64 try { 65 getActivityClientController().activityRefreshed(token); 66 } catch (RemoteException e) { 67 e.rethrowFromSystemServer(); 68 } 69 } 70 71 /** 72 * Reports after {@link Activity#onTopResumedActivityChanged(boolean)} is called for losing the 73 * top most position. 74 */ activityTopResumedStateLost()75 public void activityTopResumedStateLost() { 76 try { 77 getActivityClientController().activityTopResumedStateLost(); 78 } catch (RemoteException e) { 79 e.rethrowFromSystemServer(); 80 } 81 } 82 83 /** Reports {@link Activity#onPause()} is done. */ activityPaused(IBinder token)84 public void activityPaused(IBinder token) { 85 try { 86 getActivityClientController().activityPaused(token); 87 } catch (RemoteException e) { 88 e.rethrowFromSystemServer(); 89 } 90 } 91 92 /** Reports {@link Activity#onStop()} is done. */ activityStopped(IBinder token, Bundle state, PersistableBundle persistentState, CharSequence description)93 public void activityStopped(IBinder token, Bundle state, PersistableBundle persistentState, 94 CharSequence description) { 95 try { 96 getActivityClientController().activityStopped(token, state, persistentState, 97 description); 98 } catch (RemoteException e) { 99 e.rethrowFromSystemServer(); 100 } 101 } 102 103 /** Reports {@link Activity#onDestroy()} is done. */ activityDestroyed(IBinder token)104 public void activityDestroyed(IBinder token) { 105 try { 106 getActivityClientController().activityDestroyed(token); 107 } catch (RemoteException e) { 108 e.rethrowFromSystemServer(); 109 } 110 } 111 112 /** Reports the activity starts local relaunch. */ activityLocalRelaunch(IBinder token)113 public void activityLocalRelaunch(IBinder token) { 114 try { 115 getActivityClientController().activityLocalRelaunch(token); 116 } catch (RemoteException e) { 117 e.rethrowFromSystemServer(); 118 } 119 } 120 121 /** Reports the activity has completed relaunched. */ activityRelaunched(IBinder token)122 public void activityRelaunched(IBinder token) { 123 try { 124 getActivityClientController().activityRelaunched(token); 125 } catch (RemoteException e) { 126 e.rethrowFromSystemServer(); 127 } 128 } 129 reportSizeConfigurations(IBinder token, SizeConfigurationBuckets sizeConfigurations)130 void reportSizeConfigurations(IBinder token, SizeConfigurationBuckets sizeConfigurations) { 131 try { 132 getActivityClientController().reportSizeConfigurations(token, sizeConfigurations); 133 } catch (RemoteException e) { 134 e.rethrowFromSystemServer(); 135 } 136 } 137 moveActivityTaskToBack(IBinder token, boolean nonRoot)138 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 139 try { 140 return getActivityClientController().moveActivityTaskToBack(token, nonRoot); 141 } catch (RemoteException e) { 142 throw e.rethrowFromSystemServer(); 143 } 144 } 145 shouldUpRecreateTask(IBinder token, String destAffinity)146 boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 147 try { 148 return getActivityClientController().shouldUpRecreateTask(token, destAffinity); 149 } catch (RemoteException e) { 150 throw e.rethrowFromSystemServer(); 151 } 152 } 153 navigateUpTo(IBinder token, Intent destIntent, String resolvedType, int resultCode, Intent resultData)154 boolean navigateUpTo(IBinder token, Intent destIntent, String resolvedType, int resultCode, 155 Intent resultData) { 156 try { 157 return getActivityClientController().navigateUpTo(token, destIntent, resolvedType, 158 resultCode, resultData); 159 } catch (RemoteException e) { 160 throw e.rethrowFromSystemServer(); 161 } 162 } 163 releaseActivityInstance(IBinder token)164 boolean releaseActivityInstance(IBinder token) { 165 try { 166 return getActivityClientController().releaseActivityInstance(token); 167 } catch (RemoteException e) { 168 throw e.rethrowFromSystemServer(); 169 } 170 } 171 finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)172 public boolean finishActivity(IBinder token, int resultCode, Intent resultData, 173 int finishTask) { 174 try { 175 return getActivityClientController().finishActivity(token, resultCode, resultData, 176 finishTask); 177 } catch (RemoteException e) { 178 throw e.rethrowFromSystemServer(); 179 } 180 } 181 finishActivityAffinity(IBinder token)182 boolean finishActivityAffinity(IBinder token) { 183 try { 184 return getActivityClientController().finishActivityAffinity(token); 185 } catch (RemoteException e) { 186 throw e.rethrowFromSystemServer(); 187 } 188 } 189 finishSubActivity(IBinder token, String resultWho, int requestCode)190 void finishSubActivity(IBinder token, String resultWho, int requestCode) { 191 try { 192 getActivityClientController().finishSubActivity(token, resultWho, requestCode); 193 } catch (RemoteException e) { 194 e.rethrowFromSystemServer(); 195 } 196 } 197 198 @RequiresPermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION) setForceSendResultForMediaProjection(IBinder token)199 void setForceSendResultForMediaProjection(IBinder token) { 200 try { 201 getActivityClientController().setForceSendResultForMediaProjection(token); 202 } catch (RemoteException e) { 203 throw e.rethrowFromSystemServer(); 204 } 205 } 206 isTopOfTask(IBinder token)207 public boolean isTopOfTask(IBinder token) { 208 try { 209 return getActivityClientController().isTopOfTask(token); 210 } catch (RemoteException e) { 211 throw e.rethrowFromSystemServer(); 212 } 213 } 214 willActivityBeVisible(IBinder token)215 boolean willActivityBeVisible(IBinder token) { 216 try { 217 return getActivityClientController().willActivityBeVisible(token); 218 } catch (RemoteException e) { 219 throw e.rethrowFromSystemServer(); 220 } 221 } 222 getDisplayId(IBinder token)223 public int getDisplayId(IBinder token) { 224 try { 225 return getActivityClientController().getDisplayId(token); 226 } catch (RemoteException e) { 227 throw e.rethrowFromSystemServer(); 228 } 229 } 230 getTaskForActivity(IBinder token, boolean onlyRoot)231 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 232 try { 233 return getActivityClientController().getTaskForActivity(token, onlyRoot); 234 } catch (RemoteException e) { 235 throw e.rethrowFromSystemServer(); 236 } 237 } 238 239 /** 240 * Returns the {@link Configuration} of the task which hosts the Activity, or {@code null} if 241 * the task {@link Configuration} cannot be obtained. 242 */ 243 @Nullable getTaskConfiguration(IBinder activityToken)244 public Configuration getTaskConfiguration(IBinder activityToken) { 245 try { 246 return getActivityClientController().getTaskConfiguration(activityToken); 247 } catch (RemoteException e) { 248 throw e.rethrowFromSystemServer(); 249 } 250 } 251 252 /** 253 * Returns the non-finishing activity token below in the same task if it belongs to the same 254 * process. 255 */ 256 @Nullable getActivityTokenBelow(IBinder activityToken)257 public IBinder getActivityTokenBelow(IBinder activityToken) { 258 try { 259 return getActivityClientController().getActivityTokenBelow(activityToken); 260 } catch (RemoteException e) { 261 throw e.rethrowFromSystemServer(); 262 } 263 } 264 getCallingActivity(IBinder token)265 ComponentName getCallingActivity(IBinder token) { 266 try { 267 return getActivityClientController().getCallingActivity(token); 268 } catch (RemoteException e) { 269 throw e.rethrowFromSystemServer(); 270 } 271 } 272 getCallingPackage(IBinder token)273 String getCallingPackage(IBinder token) { 274 try { 275 return getActivityClientController().getCallingPackage(token); 276 } catch (RemoteException e) { 277 throw e.rethrowFromSystemServer(); 278 } 279 } 280 getLaunchedFromUid(IBinder token)281 public int getLaunchedFromUid(IBinder token) { 282 try { 283 return getActivityClientController().getLaunchedFromUid(token); 284 } catch (RemoteException e) { 285 throw e.rethrowFromSystemServer(); 286 } 287 } 288 getLaunchedFromPackage(IBinder token)289 public String getLaunchedFromPackage(IBinder token) { 290 try { 291 return getActivityClientController().getLaunchedFromPackage(token); 292 } catch (RemoteException e) { 293 throw e.rethrowFromSystemServer(); 294 } 295 } 296 setRequestedOrientation(IBinder token, int requestedOrientation)297 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 298 try { 299 getActivityClientController().setRequestedOrientation(token, requestedOrientation); 300 } catch (RemoteException e) { 301 e.rethrowFromSystemServer(); 302 } 303 } 304 getRequestedOrientation(IBinder token)305 int getRequestedOrientation(IBinder token) { 306 try { 307 return getActivityClientController().getRequestedOrientation(token); 308 } catch (RemoteException e) { 309 throw e.rethrowFromSystemServer(); 310 } 311 } 312 convertFromTranslucent(IBinder token)313 boolean convertFromTranslucent(IBinder token) { 314 try { 315 return getActivityClientController().convertFromTranslucent(token); 316 } catch (RemoteException e) { 317 throw e.rethrowFromSystemServer(); 318 } 319 } 320 convertToTranslucent(IBinder token, Bundle options)321 boolean convertToTranslucent(IBinder token, Bundle options) { 322 try { 323 return getActivityClientController().convertToTranslucent(token, options); 324 } catch (RemoteException e) { 325 throw e.rethrowFromSystemServer(); 326 } 327 } 328 reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle)329 void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) { 330 try { 331 getActivityClientController().reportActivityFullyDrawn(token, restoredFromBundle); 332 } catch (RemoteException e) { 333 e.rethrowFromSystemServer(); 334 } 335 } 336 isImmersive(IBinder token)337 boolean isImmersive(IBinder token) { 338 try { 339 return getActivityClientController().isImmersive(token); 340 } catch (RemoteException e) { 341 throw e.rethrowFromSystemServer(); 342 } 343 } 344 setImmersive(IBinder token, boolean immersive)345 void setImmersive(IBinder token, boolean immersive) { 346 try { 347 getActivityClientController().setImmersive(token, immersive); 348 } catch (RemoteException e) { 349 e.rethrowFromSystemServer(); 350 } 351 } 352 enterPictureInPictureMode(IBinder token, PictureInPictureParams params)353 boolean enterPictureInPictureMode(IBinder token, PictureInPictureParams params) { 354 try { 355 return getActivityClientController().enterPictureInPictureMode(token, params); 356 } catch (RemoteException e) { 357 throw e.rethrowFromSystemServer(); 358 } 359 } 360 setPictureInPictureParams(IBinder token, PictureInPictureParams params)361 void setPictureInPictureParams(IBinder token, PictureInPictureParams params) { 362 try { 363 getActivityClientController().setPictureInPictureParams(token, params); 364 } catch (RemoteException e) { 365 e.rethrowFromSystemServer(); 366 } 367 } 368 setShouldDockBigOverlays(IBinder token, boolean shouldDockBigOverlays)369 void setShouldDockBigOverlays(IBinder token, boolean shouldDockBigOverlays) { 370 try { 371 getActivityClientController().setShouldDockBigOverlays(token, shouldDockBigOverlays); 372 } catch (RemoteException e) { 373 e.rethrowFromSystemServer(); 374 } 375 } 376 toggleFreeformWindowingMode(IBinder token)377 void toggleFreeformWindowingMode(IBinder token) { 378 try { 379 getActivityClientController().toggleFreeformWindowingMode(token); 380 } catch (RemoteException e) { 381 e.rethrowFromSystemServer(); 382 } 383 } 384 requestMultiwindowFullscreen(IBinder token, int request, IRemoteCallback callback)385 void requestMultiwindowFullscreen(IBinder token, int request, IRemoteCallback callback) { 386 try { 387 getActivityClientController().requestMultiwindowFullscreen(token, request, callback); 388 } catch (RemoteException e) { 389 e.rethrowFromSystemServer(); 390 } 391 } 392 startLockTaskModeByToken(IBinder token)393 void startLockTaskModeByToken(IBinder token) { 394 try { 395 getActivityClientController().startLockTaskModeByToken(token); 396 } catch (RemoteException e) { 397 e.rethrowFromSystemServer(); 398 } 399 } 400 stopLockTaskModeByToken(IBinder token)401 void stopLockTaskModeByToken(IBinder token) { 402 try { 403 getActivityClientController().stopLockTaskModeByToken(token); 404 } catch (RemoteException e) { 405 e.rethrowFromSystemServer(); 406 } 407 } 408 showLockTaskEscapeMessage(IBinder token)409 void showLockTaskEscapeMessage(IBinder token) { 410 try { 411 getActivityClientController().showLockTaskEscapeMessage(token); 412 } catch (RemoteException e) { 413 e.rethrowFromSystemServer(); 414 } 415 } 416 setTaskDescription(IBinder token, ActivityManager.TaskDescription td)417 void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 418 try { 419 getActivityClientController().setTaskDescription(token, td); 420 } catch (RemoteException e) { 421 e.rethrowFromSystemServer(); 422 } 423 } 424 showAssistFromActivity(IBinder token, Bundle args)425 boolean showAssistFromActivity(IBinder token, Bundle args) { 426 try { 427 return getActivityClientController().showAssistFromActivity(token, args); 428 } catch (RemoteException e) { 429 throw e.rethrowFromSystemServer(); 430 } 431 } 432 isRootVoiceInteraction(IBinder token)433 boolean isRootVoiceInteraction(IBinder token) { 434 try { 435 return getActivityClientController().isRootVoiceInteraction(token); 436 } catch (RemoteException e) { 437 throw e.rethrowFromSystemServer(); 438 } 439 } 440 startLocalVoiceInteraction(IBinder callingActivity, Bundle options)441 void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { 442 try { 443 getActivityClientController().startLocalVoiceInteraction(callingActivity, options); 444 } catch (RemoteException e) { 445 e.rethrowFromSystemServer(); 446 } 447 } 448 stopLocalVoiceInteraction(IBinder callingActivity)449 void stopLocalVoiceInteraction(IBinder callingActivity) { 450 try { 451 getActivityClientController().stopLocalVoiceInteraction(callingActivity); 452 } catch (RemoteException e) { 453 e.rethrowFromSystemServer(); 454 } 455 } 456 setShowWhenLocked(IBinder token, boolean showWhenLocked)457 void setShowWhenLocked(IBinder token, boolean showWhenLocked) { 458 try { 459 getActivityClientController().setShowWhenLocked(token, showWhenLocked); 460 } catch (RemoteException e) { 461 e.rethrowFromSystemServer(); 462 } 463 } 464 setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked)465 void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) { 466 try { 467 getActivityClientController().setInheritShowWhenLocked(token, inheritShowWhenLocked); 468 } catch (RemoteException e) { 469 e.rethrowFromSystemServer(); 470 } 471 } 472 setTurnScreenOn(IBinder token, boolean turnScreenOn)473 void setTurnScreenOn(IBinder token, boolean turnScreenOn) { 474 try { 475 getActivityClientController().setTurnScreenOn(token, turnScreenOn); 476 } catch (RemoteException e) { 477 e.rethrowFromSystemServer(); 478 } 479 } 480 setAllowCrossUidActivitySwitchFromBelow(IBinder token, boolean allowed)481 void setAllowCrossUidActivitySwitchFromBelow(IBinder token, boolean allowed) { 482 try { 483 getActivityClientController().setAllowCrossUidActivitySwitchFromBelow(token, allowed); 484 } catch (RemoteException e) { 485 e.rethrowFromSystemServer(); 486 } 487 } 488 setVrMode(IBinder token, boolean enabled, ComponentName packageName)489 int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { 490 try { 491 return getActivityClientController().setVrMode(token, enabled, packageName); 492 } catch (RemoteException e) { 493 throw e.rethrowFromSystemServer(); 494 } 495 } 496 overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim, int backgroundColor)497 void overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim, 498 int backgroundColor) { 499 try { 500 getActivityClientController().overrideActivityTransition( 501 token, open, enterAnim, exitAnim, backgroundColor); 502 } catch (RemoteException e) { 503 e.rethrowFromSystemServer(); 504 } 505 } 506 clearOverrideActivityTransition(IBinder token, boolean open)507 void clearOverrideActivityTransition(IBinder token, boolean open) { 508 try { 509 getActivityClientController().clearOverrideActivityTransition(token, open); 510 } catch (RemoteException e) { 511 e.rethrowFromSystemServer(); 512 } 513 } 514 overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim, int backgroundColor)515 void overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim, 516 int backgroundColor) { 517 try { 518 getActivityClientController().overridePendingTransition(token, packageName, 519 enterAnim, exitAnim, backgroundColor); 520 } catch (RemoteException e) { 521 e.rethrowFromSystemServer(); 522 } 523 } 524 setRecentsScreenshotEnabled(IBinder token, boolean enabled)525 void setRecentsScreenshotEnabled(IBinder token, boolean enabled) { 526 try { 527 getActivityClientController().setRecentsScreenshotEnabled(token, enabled); 528 } catch (RemoteException e) { 529 e.rethrowFromSystemServer(); 530 } 531 } 532 533 /** 534 * Removes the outdated snapshot of the home task. 535 * 536 * @param homeToken The token of the home task, or null if you have the 537 * {@link android.Manifest.permission#MANAGE_ACTIVITY_TASKS} permission and 538 * want us to find the home task token for you. 539 */ invalidateHomeTaskSnapshot(IBinder homeToken)540 public void invalidateHomeTaskSnapshot(IBinder homeToken) { 541 try { 542 getActivityClientController().invalidateHomeTaskSnapshot(homeToken); 543 } catch (RemoteException e) { 544 e.rethrowFromSystemServer(); 545 } 546 } 547 dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message)548 void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, 549 CharSequence message) { 550 try { 551 getActivityClientController().dismissKeyguard(token, callback, message); 552 } catch (RemoteException e) { 553 e.rethrowFromSystemServer(); 554 } 555 } 556 registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)557 void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { 558 try { 559 getActivityClientController().registerRemoteAnimations(token, definition); 560 } catch (RemoteException e) { 561 e.rethrowFromSystemServer(); 562 } 563 } 564 unregisterRemoteAnimations(IBinder token)565 void unregisterRemoteAnimations(IBinder token) { 566 try { 567 getActivityClientController().unregisterRemoteAnimations(token); 568 } catch (RemoteException e) { 569 e.rethrowFromSystemServer(); 570 } 571 } 572 onBackPressed(IBinder token, IRequestFinishCallback callback)573 void onBackPressed(IBinder token, IRequestFinishCallback callback) { 574 try { 575 getActivityClientController().onBackPressed(token, callback); 576 } catch (RemoteException e) { 577 e.rethrowFromSystemServer(); 578 } 579 } 580 581 /** 582 * Reports the splash screen view has attached to client. 583 */ reportSplashScreenAttached(IBinder token)584 void reportSplashScreenAttached(IBinder token) { 585 try { 586 getActivityClientController().splashScreenAttached(token); 587 } catch (RemoteException e) { 588 e.rethrowFromSystemServer(); 589 } 590 } 591 enableTaskLocaleOverride(IBinder token)592 void enableTaskLocaleOverride(IBinder token) { 593 try { 594 getActivityClientController().enableTaskLocaleOverride(token); 595 } catch (RemoteException e) { 596 e.rethrowFromSystemServer(); 597 } 598 } 599 600 /** 601 * Returns {@code true} if the activity was explicitly requested to be launched in the 602 * TaskFragment. 603 * 604 * @param activityToken The token of the Activity. 605 * @param taskFragmentToken The token of the TaskFragment. 606 */ isRequestedToLaunchInTaskFragment(IBinder activityToken, IBinder taskFragmentToken)607 public boolean isRequestedToLaunchInTaskFragment(IBinder activityToken, 608 IBinder taskFragmentToken) { 609 try { 610 return getActivityClientController().isRequestedToLaunchInTaskFragment(activityToken, 611 taskFragmentToken); 612 } catch (RemoteException e) { 613 throw e.rethrowFromSystemServer(); 614 } 615 } 616 617 /** 618 * Shows or hides a Camera app compat toggle for stretched issues with the requested state. 619 * 620 * @param token The token for the window that needs a control. 621 * @param showControl Whether the control should be shown or hidden. 622 * @param transformationApplied Whether the treatment is already applied. 623 * @param callback The callback executed when the user clicks on a control. 624 */ requestCompatCameraControl(Resources res, IBinder token, boolean showControl, boolean transformationApplied, ICompatCameraControlCallback callback)625 void requestCompatCameraControl(Resources res, IBinder token, boolean showControl, 626 boolean transformationApplied, ICompatCameraControlCallback callback) { 627 if (!res.getBoolean(com.android.internal.R.bool 628 .config_isCameraCompatControlForStretchedIssuesEnabled)) { 629 return; 630 } 631 try { 632 getActivityClientController().requestCompatCameraControl( 633 token, showControl, transformationApplied, callback); 634 } catch (RemoteException e) { 635 e.rethrowFromSystemServer(); 636 } 637 } 638 getInstance()639 public static ActivityClient getInstance() { 640 return sInstance.get(); 641 } 642 643 /** 644 * If system server has passed the controller interface, store it so the subsequent access can 645 * speed up. 646 */ setActivityClientController( IActivityClientController activityClientController)647 public static IActivityClientController setActivityClientController( 648 IActivityClientController activityClientController) { 649 // No lock because it is no harm to encounter race condition. The thread safe Singleton#get 650 // will take over that case. 651 return INTERFACE_SINGLETON.mKnownInstance = activityClientController; 652 } 653 getActivityClientController()654 private static IActivityClientController getActivityClientController() { 655 final IActivityClientController controller = INTERFACE_SINGLETON.mKnownInstance; 656 return controller != null ? controller : INTERFACE_SINGLETON.get(); 657 } 658 659 private static final Singleton<ActivityClient> sInstance = new Singleton<ActivityClient>() { 660 @Override 661 protected ActivityClient create() { 662 return new ActivityClient(); 663 } 664 }; 665 666 private static final ActivityClientControllerSingleton INTERFACE_SINGLETON = 667 new ActivityClientControllerSingleton(); 668 669 private static class ActivityClientControllerSingleton 670 extends Singleton<IActivityClientController> { 671 /** 672 * A quick look up to reduce potential extra binder transactions. E.g. getting activity 673 * task manager from service manager and controller from activity task manager. 674 */ 675 IActivityClientController mKnownInstance; 676 677 @Override create()678 protected IActivityClientController create() { 679 try { 680 return ActivityTaskManager.getService().getActivityClientController(); 681 } catch (RemoteException e) { 682 throw e.rethrowFromSystemServer(); 683 } 684 } 685 } 686 } 687