• Android 14 transtion 动画流程


    1.接口

    shell入口通过TransitionPlayerImpl与wm core 通信

    1. @BinderThread
    2. private class TransitionPlayerImpl extends ITransitionPlayer.Stub {
    3. @Override
    4. public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo,
    5. SurfaceControl.Transaction t, SurfaceControl.Transaction finishT)
    6. throws RemoteException {
    7. mMainExecutor.execute(() -> Transitions.this.onTransitionReady(
    8. iBinder, transitionInfo, t, finishT));
    9. }
    10. @Override
    11. public void requestStartTransition(IBinder iBinder,
    12. TransitionRequestInfo request) throws RemoteException {
    13. mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request));
    14. }
    15. }
    16. }
    1. 分为
    2. 1. requestStartTransition
    3. 2.onTransitionReady
    4. 两个阶段
    5. 1.requestStartTransition
    6. wm services
    7. new 一个动画放进mActiveSyncs中
    8. 04-23 18:43:25.195 2077 4588 D jinyanmeiainima: BLASTSyncEngine startSyncSet s.mSyncId:6
    9. 04-23 18:43:25.195 2077 4588 D jinyanmeiainima: BLASTSyncEngine startSyncSet s:com.android.server.wm.BLASTSyncEngine$SyncGroup@3ee8531
    10. 04-23 18:43:25.195 2077 4588 D jinyanmeiainima: BLASTSyncEngine startSyncSet mActiveSyncs++++:0
    11. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: BLASTSyncEngine startSyncSet mActiveSyncs---:1
    12. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: java.lang.RuntimeException: jinyanmeiainima
    13. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine.startSyncSet(BLASTSyncEngine.java:327)
    14. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine.startSyncSet(BLASTSyncEngine.java:305)
    15. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.Transition.startCollecting(Transition.java:422)
    16. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.TransitionController.moveToCollecting(TransitionController.java:222)
    17. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.TransitionController.moveToCollecting(TransitionController.java:203)
    18. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.TransitionController.createTransition(TransitionController.java:197)
    19. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.TransitionController.createTransition(TransitionController.java:179)
    20. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskSupervisor.findTaskToMoveToFront(ActivityTaskSupervisor.java:1577)
    21. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskManagerService.moveTaskToFrontLocked(ActivityTaskManagerService.java:2497)
    22. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskSupervisor.startActivityFromRecents(ActivityTaskSupervisor.java:3034)
    23. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskManagerService.startActivityFromRecents(ActivityTaskManagerService.java:1918)
    24. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1434)
    25. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5840)
    26. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at android.os.Binder.execTransactInternal(Binder.java:1348)
    27. 04-23 18:43:25.196 2077 4588 D jinyanmeiainima: at android.os.Binder.execTransact(Binder.java:1279)
    28. new出来后调用task.mTransitionController.collect(task);
    29. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: ChangeInfo 111111111 this:Task{fa5361 #69 type=standard A=10143:comgallery.home}
    30. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: ChangeInfo 111111111 mVisible:true
    31. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: ChangeInfo 111111111 mWindowingMode:5
    32. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: java.lang.RuntimeException: jinyanmeiani
    33. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.Transition$ChangeInfo.(Transition.java:2258)
    34. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.Transition.collect(Transition.java:492)
    35. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.TransitionController.collect(TransitionController.java:568)
    36. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.ActivityTaskSupervisor.findTaskToMoveToFront(ActivityTaskSupervisor.java:1529)
    37. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.ActivityTaskManagerService.moveTaskToFrontLocked(ActivityTaskManagerService.java:2464)
    38. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.ActivityTaskSupervisor.startActivityFromRecents(ActivityTaskSupervisor.java:2901)
    39. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.ActivityTaskManagerService.startActivityFromRecents(ActivityTaskManagerService.java:1931)
    40. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1430)
    41. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5786)
    42. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at android.os.Binder.execTransactInternal(Binder.java:1348)
    43. 04-24 16:06:47.682 1815 2160 D jinyanmeiani: at android.os.Binder.execTransact(Binder.java:1279)
    1. /** @see Transition#collect */
    2. void collect(@NonNull WindowContainer wc) {
    3. if (mCollectingTransition == null) return;
    4. mCollectingTransition.collect(wc);
    5. }

    计算所有的到mChanges

    根据WindowContainer new 一个ChangeInfo

    1. ChangeInfo(@NonNull WindowContainer origState) {
    2. mContainer = origState;
    3. mVisible = origState.isVisibleRequested();
    4. mWindowingMode = origState.getWindowingMode();
    5. mAbsoluteBounds.set(origState.getBounds());
    6. mShowWallpaper = origState.showWallpaper();
    7. mRotation = origState.getWindowConfiguration().getRotation();
    8. mStartParent = origState.getParent();
    9. }

    把changeinfo放入mChanges

    mChanges是一个map

    key:WindowContainer

    value:由key:WindowContainer构成的ChangeInfo

    此列表在开始做动画时候会判断里面的key,value是否满足做动画的条件

    1. void collect(@NonNull WindowContainer wc) {
    2. if (mState < STATE_COLLECTING) {
    3. throw new IllegalStateException("Transition hasn't started collecting.");
    4. }
    5. if (!isCollecting()) {
    6. // Too late, transition already started playing, so don't collect.
    7. return;
    8. }
    9. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Collecting in transition %d: %s",
    10. mSyncId, wc);
    11. // "snapshot" all parents (as potential promotion targets). Do this before checking
    12. // if this is already a participant in case it has since been re-parented.
    13. for (WindowContainer curr = getAnimatableParent(wc);
    14. curr != null && !mChanges.containsKey(curr);
    15. curr = getAnimatableParent(curr)) {
    16. mChanges.put(curr, new ChangeInfo(curr)); // 放入队列中
    17. if (isReadyGroup(curr)) {
    18. mReadyTracker.addGroup(curr);
    19. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " Creating Ready-group for"
    20. + " Transition %d with root=%s", mSyncId, curr);
    21. }
    22. }
    23. if (mParticipants.contains(wc)) return;
    24. // Wallpaper is like in a static drawn state unless display may have changes, so exclude
    25. // the case to reduce transition latency waiting for the unchanged wallpaper to redraw.
    26. final boolean needSyncDraw = !isWallpaper(wc) || mParticipants.contains(wc.mDisplayContent);
    27. if (needSyncDraw) {
    28. mSyncEngine.addToSyncSet(mSyncId, wc);
    29. }
    30. ChangeInfo info = mChanges.get(wc);
    31. if (info == null) {
    32. info = new ChangeInfo(wc);
    33. Slog.d("jinyanmeiainima","collect wc:" + wc );
    34. Slog.d("jinyanmeiainima","collect info:" + info );
    35. Slog.d("jinyanmeiainima","collect mChanges.size()+++:" + mChanges.size() );
    36. mChanges.put(wc, info);
    37. Slog.d("jinyanmeiainima","collect mChanges.size()---:" + mChanges.size() );
    38. }
    39. mParticipants.add(wc);
    40. if (wc.getDisplayContent() != null && !mTargetDisplays.contains(wc.getDisplayContent())) {
    41. mTargetDisplays.add(wc.getDisplayContent());
    42. }
    43. if (info.mShowWallpaper) {
    44. // Collect the wallpaper token (for isWallpaper(wc)) so it is part of the sync set.
    45. final WindowState wallpaper =
    46. wc.getDisplayContent().mWallpaperController.getTopVisibleWallpaper();
    47. if (wallpaper != null) {
    48. collect(wallpaper.mToken);
    49. }
    50. }
    51. }
    1. new出来的动画申请开始动画requestStartTransition
    2. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: requestStartTransition displayChange:
    3. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: java.lang.RuntimeException: jinyanmeiainima
    4. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at com.android.server.wm.TransitionController.requestStartTransition(TransitionController.java:548)
    5. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskSupervisor.findTaskToMoveToFront(ActivityTaskSupervisor.java:1622)
    6. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskManagerService.moveTaskToFrontLocked(ActivityTaskManagerService.java:2497)
    7. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskSupervisor.startActivityFromRecents(ActivityTaskSupervisor.java:3034)
    8. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskManagerService.startActivityFromRecents(ActivityTaskManagerService.java:1918)
    9. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1434)
    10. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5840)
    11. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at android.os.Binder.execTransactInternal(Binder.java:1348)
    12. 04-23 18:43:25.211 2077 4588 D jinyanmeiainima: at android.os.Binder.execTransact(Binder.java:1279)
    1. Transition requestStartTransition(@NonNull Transition transition, @Nullable Task startTask,
    2. @Nullable RemoteTransition remoteTransition,
    3. @Nullable TransitionRequestInfo.DisplayChange displayChange) {
    4. Slog.d("jinyanmeiainima","requestStartTransition transition:" + transition );
    5. Slog.d("jinyanmeiainima","requestStartTransition startTask:" + startTask );
    6. Slog.d("jinyanmeiainima","requestStartTransition remoteTransition:" + remoteTransition );
    7. Slog.d("jinyanmeiainima","requestStartTransition displayChange:" + displayChange );
    8. if (mIsWaitingForDisplayEnabled) {
    9. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Disabling player for transition"
    10. + " #%d because display isn't enabled yet", transition.getSyncId());
    11. transition.mIsPlayerEnabled = false;
    12. transition.mLogger.mRequestTimeNs = SystemClock.uptimeNanos();
    13. mAtm.mH.post(() -> mAtm.mWindowOrganizerController.startTransition(
    14. transition.getToken(), null));
    15. return transition;
    16. }
    17. if (mTransitionPlayer == null || transition.isAborted()) {
    18. // Apparently, some tests will kill(and restart) systemui, so there is a chance that
    19. // the player might be transiently null.
    20. if (transition.isCollecting()) {
    21. transition.abort();
    22. }
    23. return transition;
    24. }
    25. try {
    26. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
    27. "Requesting StartTransition: %s", transition);
    28. ActivityManager.RunningTaskInfo info = null;
    29. if (startTask != null) {
    30. info = new ActivityManager.RunningTaskInfo();
    31. startTask.fillTaskInfo(info);
    32. }
    33. final TransitionRequestInfo request = new TransitionRequestInfo(
    34. transition.mType, info, remoteTransition, displayChange);
    35. transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos();
    36. transition.mLogger.mRequest = request;
    37. Slog.d("jinyanmeiainima","requestStartTransition transition.getToken():" + transition.getToken() );
    38. Slog.d("jinyanmeiainima","requestStartTransition request:" + request);
    39. Slog.d("jinyanmeiainima","requestStartTransition displayChange:" , new RuntimeException("jinyanmeiainima") );
    40. mTransitionPlayer.requestStartTransition(transition.getToken(), request);
    41. transition.setRemoteTransition(remoteTransition);
    42. } catch (RemoteException e) {
    43. Slog.e(TAG, "Error requesting transition", e);
    44. transition.start();
    45. }
    46. return transition;
    47. }

    转到shell:

    Transition requestStartTransition(@NonNull Transition transition, @Nullable Task startTask,

    1. requestStartTransition
    2. mTransitionPlayer.requestStartTransition(transition.getToken(), request);
    3. transition.setRemoteTransition(remoteTransition);

    shell

    1. @BinderThread
    2. private class TransitionPlayerImpl extends ITransitionPlayer.Stub {
    3. @Override
    4. public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo,
    5. SurfaceControl.Transaction t, SurfaceControl.Transaction finishT)
    6. throws RemoteException {
    7. mMainExecutor.execute(() -> Transitions.this.onTransitionReady(
    8. iBinder, transitionInfo, t, finishT));
    9. }
    10. @Override
    11. public void requestStartTransition(IBinder iBinder,
    12. TransitionRequestInfo request) throws RemoteException {
    13. mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request));
    14. }
    15. }
    16. }
    1. void requestStartTransition(@NonNull IBinder transitionToken,
    2. @Nullable TransitionRequestInfo request) {
    3. ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition requested: %s %s",
    4. transitionToken, request);
    5. if (isTransitionKnown(transitionToken)) {
    6. throw new RuntimeException("Transition already started " + transitionToken);
    7. }
    8. final ActiveTransition active = new ActiveTransition();
    9. WindowContainerTransaction wct = null;
    10. // If we have sleep, we use a special handler and we try to finish everything ASAP.
    11. if (request.getType() == TRANSIT_SLEEP) {
    12. mSleepHandler.handleRequest(transitionToken, request);
    13. active.mHandler = mSleepHandler;
    14. } else {
    15. for (int i = mHandlers.size() - 1; i >= 0; --i) {
    16. wct = mHandlers.get(i).handleRequest(transitionToken, request);
    17. if (wct != null) {
    18. active.mHandler = mHandlers.get(i);
    19. break;
    20. }
    21. }
    22. if (request.getDisplayChange() != null) {
    23. TransitionRequestInfo.DisplayChange change = request.getDisplayChange();
    24. if (change.getEndRotation() != change.getStartRotation()) {
    25. // Is a rotation, so dispatch to all displayChange listeners
    26. if (wct == null) {
    27. wct = new WindowContainerTransaction();
    28. }
    29. mDisplayController.getChangeController().dispatchOnDisplayChange(wct,
    30. change.getDisplayId(), change.getStartRotation(),
    31. change.getEndRotation(), null /* newDisplayAreaInfo */);
    32. }
    33. }
    34. }
    35. mOrganizer.startTransition(transitionToken, wct != null && wct.isEmpty() ? null : wct);
    36. active.mToken = transitionToken;
    37. // Currently, WMCore only does one transition at a time. If it makes a requestStart, it
    38. // is already collecting that transition on core-side, so it will be the next one to
    39. // become ready. There may already be pending transitions added as part of direct
    40. // `startNewTransition` but if we have a request now, it means WM created the request
    41. // transition before it acknowledged any of the pending `startNew` transitions. So, insert
    42. // it at the front.
    43. mPendingTransitions.add(0, active); // 添加到mPendingTransitions
    44. }
    1. private static final class ActiveTransition {
    2. IBinder mToken;
    3. TransitionHandler mHandler;
    4. boolean mAborted;
    5. TransitionInfo mInfo;
    6. SurfaceControl.Transaction mStartT;
    7. SurfaceControl.Transaction mFinishT;
    8. /** Ordered list of transitions which have been merged into this one. */
    9. private ArrayList mMerged;
    10. }
    1. 转到wm core
    2. 04-23 18:43:22.342 2980 3221 D jinyanmeiainima: WindowOrganizer transitionToken transitionToken:android.os.BinderProxy@3268f3
    3. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: WindowOrganizer startTransition t:null
    4. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: java.lang.RuntimeException: jinyanmeiainima
    5. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at android.window.WindowOrganizer.startTransition(WindowOrganizer.java:112)
    6. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions.requestStartTransition(Transitions.java:891)
    7. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions$TransitionPlayerImpl.lambda$requestStartTransition$1(Transitions.java:1129)
    8. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions$TransitionPlayerImpl.$r8$lambda$FkH1M0vUh3zDx8R5iMruInPEXLI(Unknown Source:0)
    9. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions$TransitionPlayerImpl$$ExternalSyntheticLambda1.run(Unknown Source:6)
    10. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at android.os.Handler.handleCallback(Handler.java:958)
    11. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at android.os.Handler.dispatchMessage(Handler.java:99)
    12. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at android.os.Looper.loopOnce(Looper.java:216)
    13. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at android.os.Looper.loop(Looper.java:305)
    14. 04-23 18:43:22.343 2980 3221 D jinyanmeiainima: at android.os.HandlerThread.run(HandlerThread.java:67)
    1. WindowOrganizer.java
    2. @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
    3. public void startTransition(@NonNull IBinder transitionToken,
    4. @Nullable WindowContainerTransaction t) {
    5. try {
    6. getWindowOrganizerController().startTransition(transitionToken, t);
    7. } catch (RemoteException e) {
    8. throw e.rethrowFromSystemServer();
    9. }
    10. }
    转到 wm services
    WindowOrganizerController
    1. WindowOrganizerController.java
    2. private IBinder startTransition(@WindowManager.TransitionType int type,
    3. @Nullable IBinder transitionToken, @Nullable WindowContainerTransaction t) {
    4. enforceTaskPermission("startTransition()");
    5. final CallerInfo caller = new CallerInfo();
    6. final long ident = Binder.clearCallingIdentity();
    7. try {
    8. synchronized (mGlobalLock) {
    9. Transition transition = Transition.fromBinder(transitionToken);
    10. if (mTransitionController.getTransitionPlayer() == null && transition == null) {
    11. Slog.w(TAG, "Using shell transitions API for legacy transitions.");
    12. if (t == null) {
    13. throw new IllegalArgumentException("Can't use legacy transitions in"
    14. + " compatibility mode with no WCT.");
    15. }
    16. applyTransaction(t, -1 /* syncId */, null, caller);
    17. return null;
    18. }
    19. // In cases where transition is already provided, the "readiness lifecycle" of the
    20. // transition is determined outside of this transaction. However, if this is a
    21. // direct call from shell, the entire transition lifecycle is contained in the
    22. // provided transaction and thus we can setReady immediately after apply.
    23. final boolean needsSetReady = transition == null && t != null;
    24. final WindowContainerTransaction wct =
    25. t != null ? t : new WindowContainerTransaction();
    26. if (transition == null) {
    27. if (type < 0) {
    28. throw new IllegalArgumentException("Can't create transition with no type");
    29. }
    30. // If there is already a collecting transition, queue up a new transition and
    31. // return that. The actual start and apply will then be deferred until that
    32. // transition starts collecting. This should almost never happen except during
    33. // tests.
    34. if (mService.mWindowManager.mSyncEngine.hasActiveSync()) {
    35. Slog.w(TAG, "startTransition() while one is already collecting.");
    36. final Transition nextTransition = new Transition(type, 0 /* flags */,
    37. mTransitionController, mService.mWindowManager.mSyncEngine);
    38. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
    39. "Creating Pending Transition: %s", nextTransition);
    40. mService.mWindowManager.mSyncEngine.queueSyncSet(
    41. // Make sure to collect immediately to prevent another transition
    42. // from sneaking in before it. Note: moveToCollecting internally
    43. // calls startSyncSet.
    44. () -> mTransitionController.moveToCollecting(nextTransition),
    45. () -> {
    46. nextTransition.start();
    47. applyTransaction(wct, -1 /*syncId*/, nextTransition, caller);
    48. if (needsSetReady) {
    49. nextTransition.setAllReady();
    50. }
    51. });
    52. return nextTransition.getToken();
    53. }
    54. transition = mTransitionController.createTransition(type);
    55. }
    56. if (!transition.isCollecting() && !transition.isForcePlaying()) {
    57. Slog.e(TAG, "Trying to start a transition that isn't collecting. This probably"
    58. + " means Shell took too long to respond to a request. WM State may be"
    59. + " incorrect now, please file a bug");
    60. applyTransaction(wct, -1 /*syncId*/, null /*transition*/, caller);
    61. return transition.getToken();
    62. }
    63. transition.start(); /到这里
    64. transition.mLogger.mStartWCT = wct;
    65. applyTransaction(wct, -1 /*syncId*/, transition, caller);
    66. if (needsSetReady) {
    67. transition.setAllReady();
    68. }
    69. return transition.getToken();
    70. }
    71. } finally {
    72. Binder.restoreCallingIdentity(ident);
    73. }
    74. }

    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: BLASTSyncEngine setReady ready:true
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: java.lang.RuntimeException: setReady
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine$SyncGroup.setReady(BLASTSyncEngine.java:240)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine$SyncGroup.-$$Nest$msetReady(Unknown Source:0)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine.setReady(BLASTSyncEngine.java:356)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.Transition.applyReady(Transition.java:657)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.Transition.start(Transition.java:446)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.WindowOrganizerController.startTransition(WindowOrganizerController.java:335)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.WindowOrganizerController.startTransition(WindowOrganizerController.java:267)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at android.window.IWindowOrganizerController$Stub.onTransact(IWindowOrganizerController.java:264)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at com.android.server.wm.WindowOrganizerController.onTransact(WindowOrganizerController.java:185)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at android.os.Binder.execTransactInternal(Binder.java:1343)
    04-23 18:44:02.186 2107 2323 D jinyanmeiainima: at android.os.Binder.execTransact(Binder.java:1279)

    然后调用到BLASTSyncEngine setReady 将动画状态置为ready

    开始刷新

    1. BLASTSyncEngine.java
    2. private void setReady(boolean ready) {
    3. if (mReady == ready) {
    4. return;
    5. }
    6. Slog.d("jinyanmeiainima","BLASTSyncEngine setReady ready:" + ready, new RuntimeException("setReady"));
    7. ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "SyncGroup %d: Set ready", mSyncId);
    8. mReady = ready;
    9. if (!ready) return;
    10. mWm.mWindowPlacerLocked.requestTraversal();
    11. }
    1. private static final class ActiveTransition {
    2. IBinder mToken;
    3. TransitionHandler mHandler;
    4. boolean mAborted;
    5. TransitionInfo mInfo;
    6. SurfaceControl.Transaction mStartT;
    7. SurfaceControl.Transaction mFinishT;
    8. /** Ordered list of transitions which have been merged into this one. */
    9. private ArrayList mMerged;
    10. }

    onTransactionReady阶段

    2.1 数据准备,筛选要做动画的对象

    刷新时调用到 wm services. onTransactionReady 

    1. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: Transition onTransactionReady mToken:Token{a674b32 TransitionRecord{d9c7094 id=6 type=TO_FRONT flags=0}}
    2. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: Transition onTransactionReady info:{t=TO_FRONT f=0x0 ro=Point(0, 0) c=[{WCT{RemoteToken{2a5ead1 Task{c299c5e #39 type=standard A=10245:com..notes}}} m=SHOW f=TRANSLUCENT leash=Surface(name=Task=39)/@0x2c4c3d4 sb=Rect(0, 0 - 1800, 2880) eb=Rect(799, 141 - 1759, 1848) eo=Point(799, 141)}]}
    3. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: Transition onTransactionReady transaction:android.view.SurfaceControl$Transaction@65dbba
    4. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: Transition onTransactionReady mFinishTransaction:android.view.SurfaceControl$Transaction@2d6a6b
    5. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: java.lang.RuntimeException: jinyanmeiainima
    6. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.Transition.onTransactionReady(Transition.java:1215)
    7. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine$SyncGroup.finishNow(BLASTSyncEngine.java:206) //这里会从队列移除
    8. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine$SyncGroup.onSurfacePlacement(BLASTSyncEngine.java:148)
    9. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine$SyncGroup.-$$Nest$monSurfacePlacement(Unknown Source:0)
    10. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.BLASTSyncEngine.onSurfacePlacement(BLASTSyncEngine.java:382)
    11. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:893)
    12. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:836)
    13. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:200)
    14. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:149)
    15. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:138)
    16. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:80)
    17. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at android.os.Handler.handleCallback(Handler.java:958)
    18. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at android.os.Handler.dispatchMessage(Handler.java:99)
    19. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at android.os.Looper.loopOnce(Looper.java:216)
    20. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at android.os.Looper.loop(Looper.java:305)
    21. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at android.os.HandlerThread.run(HandlerThread.java:67)
    22. 04-23 18:43:22.529 2073 2100 D jinyanmeiainima: at com.android.server.ServiceThread.run(ServiceThread.java:46)
    1. BLASTSyncEngine.java
    2. private void finishNow() {
    3. mActiveSyncs.remove(mSyncId); //从队列移除
    4. }

    Transition.onTransactionReady

    mTargets = calculateTargets(mParticipants, mChanges); //计算mTargets

    根据target 计算info
    final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, transaction);

    1. Transition.java
    2. public void onTransactionReady(int syncId, SurfaceControl.Transaction transaction) {
    3. final ArrayMap mChanges = new ArrayMap<>(); //这里的mChanges 也是一个map
    4. mTargets = calculateTargets(mParticipants, mChanges);
    5. final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, transaction);
    6. mController.getTransitionPlayer().onTransitionReady(
    7. mToken, info, transaction, mFinishTransaction);
    8. if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
    9. Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, TRACE_NAME_PLAY_TRANSITION,
    10. }

    wm.services.Transition.calculateTargets

    两个条件不添加动画:

    1:!wc.isAttached()

    2:!changeInfo.hasChanged()

    将符合条件的changeInfo添加到targets 返回

    1. @VisibleForTesting
    2. @NonNull
    3. static ArrayList calculateTargets(ArraySet participants,
    4. ArrayMap changes) {
    5. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
    6. "Start calculating TransitionInfo based on participants: %s", participants);
    7. // Add all valid participants to the target container.
    8. final Targets targets = new Targets();
    9. for (int i = participants.size() - 1; i >= 0; --i) {
    10. final WindowContainer wc = participants.valueAt(i);
    11. if (!wc.isAttached()) {
    12. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
    13. " Rejecting as detached: %s", wc);
    14. continue;
    15. }
    16. // The level of transition target should be at least window token.
    17. if (wc.asWindowState() != null) continue;
    18. final ChangeInfo changeInfo = changes.get(wc); // changes即mChanges,由onTransitionReady时添加到changes 的map //这里的changeInfo 与TransitionInfo不是一个
    19. // Reject no-ops
    20. if (!changeInfo.hasChanged()) {
    21. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
    22. " Rejecting as no-op: %s", wc);
    23. continue;
    24. }
    25. targets.add(changeInfo);
    26. }
    27. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " Initial targets: %s",
    28. targets.mArray);
    29. // Combine the targets from bottom to top if possible.
    30. tryPromote(targets, changes);
    31. // Establish the relationship between the targets and their top changes.
    32. populateParentChanges(targets, changes);
    33. final ArrayList targetList = targets.getListSortedByZ();
    34. ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " Final targets: %s", targetList);
    35. return targetList;
    36. }
    1. boolean hasChanged() {
    2. // the task including transient launch must promote to root task
    3. if ((mFlags & ChangeInfo.FLAG_TRANSIENT_LAUNCH) != 0
    4. || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) {
    5. return true;
    6. }
    7. // If it's invisible and hasn't changed visibility, always return false since even if
    8. // something changed, it wouldn't be a visible change.
    9. final boolean currVisible = mContainer.isVisibleRequested();
    10. if (currVisible == mVisible && !mVisible) return false;
    11. return currVisible != mVisible
    12. || mKnownConfigChanges != 0
    13. // if mWindowingMode is 0, this container wasn't attached at collect time, so
    14. // assume no change in windowing-mode.
    15. || (mWindowingMode != 0 && mContainer.getWindowingMode() != mWindowingMode)
    16. || !mContainer.getBounds().equals(mAbsoluteBounds)
    17. || mRotation != mContainer.getWindowConfiguration().getRotation();
    18. }

    根据上步计算出来的sortedTargets计算要做的动画TransitionInfo

    TransitionInfo中有个mChanges

    1. public final class TransitionInfo implements Parcelable {
    2. /**
    3. * Modes are only a sub-set of all the transit-types since they are per-container
    4. * @hide
    5. */
    6. @IntDef(prefix = { "TRANSIT_" }, value = {
    7. TRANSIT_NONE,
    8. TRANSIT_OPEN,
    9. TRANSIT_CLOSE,
    10. // Note: to_front/to_back really mean show/hide respectively at the container level.
    11. TRANSIT_TO_FRONT,
    12. TRANSIT_TO_BACK,
    13. TRANSIT_CHANGE
    14. })
    15. public @interface TransitionMode {}
    16. private final ArrayList mChanges = new ArrayList<>();
    1. public static final class Change implements Parcelable {
    2. private final WindowContainerToken mContainer;
    3. private WindowContainerToken mParent;
    4. private WindowContainerToken mLastParent;
    5. private final SurfaceControl mLeash;
    6. private @TransitionMode int mMode = TRANSIT_NONE;
    7. private @ChangeFlags int mFlags = FLAG_NONE;
    8. private final Rect mStartAbsBounds = new Rect();
    9. private final Rect mEndAbsBounds = new Rect();
    10. private final Point mEndRelOffset = new Point();
    11. private ActivityManager.RunningTaskInfo mTaskInfo = null;
    12. private boolean mAllowEnterPip;
    13. private @Surface.Rotation int mStartRotation = ROTATION_UNDEFINED;
    14. private @Surface.Rotation int mEndRotation = ROTATION_UNDEFINED;
    15. /**
    16. * The end rotation of the top activity after fixed rotation is finished. If the top
    17. * activity is not in fixed rotation, it will be {@link ROTATION_UNDEFINED}.
    18. */
    19. private @Surface.Rotation int mEndFixedRotation = ROTATION_UNDEFINED;
    20. private int mRotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
    21. private @ColorInt int mBackgroundColor;
    22. private SurfaceControl mSnapshot = null;
    23. private float mSnapshotLuma;
    1. static TransitionInfo calculateTransitionInfo(@TransitionType int type, int flags,
    2. ArrayList sortedTargets,
    3. @Nullable SurfaceControl.Transaction startT) {
    4. final TransitionInfo out = new TransitionInfo(type, flags); //根据type 和flags 构建新的TransitionInfo 对象
    5. WindowContainer topApp = null;
    6. for (int i = 0; i < sortedTargets.size(); i++) {
    7. final WindowContainer wc = sortedTargets.get(i).mContainer;
    8. if (!isWallpaper(wc)) {
    9. topApp = wc;
    10. break;
    11. }
    12. }
    13. if (topApp == null) {
    14. out.setRootLeash(new SurfaceControl(), 0, 0);
    15. return out;
    16. }
    17. WindowContainer ancestor = findCommonAncestor(sortedTargets, topApp);
    18. // Make leash based on highest (z-order) direct child of ancestor with a participant.
    19. // TODO(b/261418859): Handle the case when the target contains window containers which
    20. // belong to a different display. As a workaround we use topApp, from which wallpaper
    21. // window container is removed, instead of sortedTargets here.
    22. WindowContainer leashReference = topApp;
    23. while (leashReference.getParent() != ancestor) {
    24. leashReference = leashReference.getParent();
    25. }
    26. final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName(
    27. "Transition Root: " + leashReference.getName()).build();
    28. startT.setLayer(rootLeash, leashReference.getLastLayer()); // 设置layer
    29. out.setRootLeash(rootLeash, ancestor.getBounds().left, ancestor.getBounds().top); //设置leash
    30. // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order.
    31. final int count = sortedTargets.size(); //遍历上一步筛选出来的sortedTargets
    32. for (int i = 0; i < count; ++i) {
    33. final ChangeInfo info = sortedTargets.get(i);
    34. final WindowContainer target = info.mContainer;
    35. final TransitionInfo.Change change = new TransitionInfo.Change(
    36. target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken() //根据windwoContainer的成员变量mWindowContainerToken 构建一个change所以每个windwoContainer都有一个change
    37. : null, getLeashSurface(target, startT));
    38. // TODO(shell-transitions): Use leash for non-organized windows.
    39. if (info.mEndParent != null) {
    40. change.setParent(info.mEndParent.mRemoteToken.toWindowContainerToken());
    41. }
    42. if (info.mStartParent != null && info.mStartParent.mRemoteToken != null
    43. && target.getParent() != info.mStartParent) {
    44. change.setLastParent(info.mStartParent.mRemoteToken.toWindowContainerToken());
    45. }
    46. change.setMode(info.getTransitMode(target));
    47. change.setStartAbsBounds(info.mAbsoluteBounds);
    48. change.setFlags(info.getChangeFlags(target));
    49. final Task task = target.asTask();
    50. final TaskFragment taskFragment = target.asTaskFragment();
    51. final ActivityRecord activityRecord = target.asActivityRecord();
    52. if (task != null) {
    53. final ActivityManager.RunningTaskInfo tinfo = new ActivityManager.RunningTaskInfo();
    54. task.fillTaskInfo(tinfo);
    55. change.setTaskInfo(tinfo);
    56. change.setRotationAnimation(getTaskRotationAnimation(task));
    57. final ActivityRecord topMostActivity = task.getTopMostActivity();
    58. change.setAllowEnterPip(topMostActivity != null
    59. && topMostActivity.checkEnterPictureInPictureAppOpsState());
    60. final ActivityRecord topRunningActivity = task.topRunningActivity();
    61. if (topRunningActivity != null && task.mDisplayContent != null
    62. // Display won't be rotated for multi window Task, so the fixed rotation
    63. // won't be applied. This can happen when the windowing mode is changed
    64. // before the previous fixed rotation is applied.
    65. && !task.inMultiWindowMode()) {
    66. // If Activity is in fixed rotation, its will be applied with the next rotation,
    67. // when the Task is still in the previous rotation.
    68. final int taskRotation = task.getWindowConfiguration().getDisplayRotation();
    69. final int activityRotation = topRunningActivity.getWindowConfiguration()
    70. .getDisplayRotation();
    71. if (taskRotation != activityRotation) {
    72. change.setEndFixedRotation(activityRotation);
    73. }
    74. }
    75. } else if ((info.mFlags & ChangeInfo.FLAG_SEAMLESS_ROTATION) != 0) {
    76. change.setRotationAnimation(ROTATION_ANIMATION_SEAMLESS);
    77. }
    78. final WindowContainer parent = target.getParent();
    79. final Rect bounds = target.getBounds();
    80. final Rect parentBounds = parent.getBounds();
    81. change.setEndRelOffset(bounds.left - parentBounds.left,
    82. bounds.top - parentBounds.top);
    83. int endRotation = target.getWindowConfiguration().getRotation();
    84. if (activityRecord != null) {
    85. // TODO(b/227427984): Shell needs to aware letterbox.
    86. // Always use parent bounds of activity because letterbox area (e.g. fixed aspect
    87. // ratio or size compat mode) should be included in the animation.
    88. change.setEndAbsBounds(parentBounds);
    89. if (activityRecord.getRelativeDisplayRotation() != 0
    90. && !activityRecord.mTransitionController.useShellTransitionsRotation()) {
    91. // Use parent rotation because shell doesn't know the surface is rotated.
    92. endRotation = parent.getWindowConfiguration().getRotation();
    93. }
    94. } else {
    95. change.setEndAbsBounds(bounds);
    96. }
    97. if (activityRecord != null || (taskFragment != null && taskFragment.isEmbedded())) {
    98. final int backgroundColor;
    99. final TaskFragment organizedTf = activityRecord != null
    100. ? activityRecord.getOrganizedTaskFragment()
    101. : taskFragment.getOrganizedTaskFragment();
    102. if (organizedTf != null && organizedTf.getAnimationParams()
    103. .getAnimationBackgroundColor() != DEFAULT_ANIMATION_BACKGROUND_COLOR) {
    104. // This window is embedded and has an animation background color set on the
    105. // TaskFragment. Pass this color with this window, so the handler can use it as
    106. // the animation background color if needed,
    107. backgroundColor = organizedTf.getAnimationParams()
    108. .getAnimationBackgroundColor();
    109. } else {
    110. // Set background color to Task theme color for activity and embedded
    111. // TaskFragment in case we want to show background during the animation.
    112. final Task parentTask = activityRecord != null
    113. ? activityRecord.getTask()
    114. : taskFragment.getTask();
    115. backgroundColor = parentTask.getTaskDescription().getBackgroundColor();
    116. }
    117. // Set to opaque for animation background to prevent it from exposing the blank
    118. // background or content below.
    119. change.setBackgroundColor(ColorUtils.setAlphaComponent(backgroundColor, 255));
    120. }
    121. change.setRotation(info.mRotation, endRotation);
    122. if (info.mSnapshot != null) {
    123. change.setSnapshot(info.mSnapshot, info.mSnapshotLuma);
    124. }
    125. out.addChange(change); //最后把widowContainer的change放入mChanger中out(TransitionInfo)中
    126. }
    127. TransitionInfo.AnimationOptions animOptions = null;
    128. if (topApp.asActivityRecord() != null) {
    129. final ActivityRecord topActivity = topApp.asActivityRecord();
    130. animOptions = addCustomActivityTransition(topActivity, true/* open */, null);
    131. animOptions = addCustomActivityTransition(topActivity, false/* open */, animOptions);
    132. }
    133. final WindowManager.LayoutParams animLp =
    134. getLayoutParamsForAnimationsStyle(type, sortedTargets);
    135. if (animLp != null && animLp.type != TYPE_APPLICATION_STARTING
    136. && animLp.windowAnimations != 0) {
    137. // Don't send animation options if no windowAnimations have been set or if the we are
    138. // running an app starting animation, in which case we don't want the app to be able to
    139. // change its animation directly.
    140. if (animOptions != null) {
    141. animOptions.addOptionsFromLayoutParameters(animLp);
    142. } else {
    143. animOptions = TransitionInfo.AnimationOptions
    144. .makeAnimOptionsFromLayoutParameters(animLp);
    145. }
    146. }
    147. if (animOptions != null) {
    148. out.setAnimationOptions(animOptions);
    149. }
    150. return out;
    151. }

    2.2 开始动画

    到shell.onTransitionReady

    1. @BinderThread
    2. private class TransitionPlayerImpl extends ITransitionPlayer.Stub {
    3. @Override
    4. public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo,
    5. SurfaceControl.Transaction t, SurfaceControl.Transaction finishT)
    6. throws RemoteException {
    7. mMainExecutor.execute(() -> Transitions.this.onTransitionReady(
    8. iBinder, transitionInfo, t, finishT));
    9. }
    10. @Override
    11. public void requestStartTransition(IBinder iBinder,
    12. TransitionRequestInfo request) throws RemoteException {
    13. mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request));
    14. }
    15. }
    1. void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
    2. @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
    3. ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady %s: %s",
    4. transitionToken, info);
    5. final int activeIdx = findByToken(mPendingTransitions, transitionToken);
    6. if (activeIdx < 0) {
    7. throw new IllegalStateException("Got transitionReady for non-pending transition "
    8. + transitionToken + ". expecting one of "
    9. + Arrays.toString(mPendingTransitions.stream().map(
    10. activeTransition -> activeTransition.mToken).toArray()));
    11. }
    12. if (activeIdx > 0) {
    13. Log.e(TAG, "Transition became ready out-of-order " + transitionToken + ". Expected"
    14. + " order: " + Arrays.toString(mPendingTransitions.stream().map(
    15. activeTransition -> activeTransition.mToken).toArray()));
    16. }
    17. // Move from pending to ready
    18. final ActiveTransition active = mPendingTransitions.remove(activeIdx);//从 mPendingTransitions 移除
    19. mReadyTransitions.add(active); //添加至 mReadyTransitions
    20. active.mInfo = info;
    21. active.mStartT = t;
    22. active.mFinishT = finishT;
    23. for (int i = 0; i < mObservers.size(); ++i) {
    24. mObservers.get(i).onTransitionReady(transitionToken, info, t, finishT);
    25. }
    26. if (info.getType() == TRANSIT_SLEEP) {
    27. if (activeIdx > 0) {
    28. if (!info.getRootLeash().isValid()) {
    29. // Shell has some debug settings which makes calling binders with invalid
    30. // surfaces crash, so replace it with a "real" one.
    31. info.setRootLeash(new SurfaceControl.Builder().setName("Invalid")
    32. .setContainerLayer().build(), 0, 0);
    33. }
    34. // Sleep starts a process of forcing all prior transitions to finish immediately
    35. finishForSleep(null /* forceFinish */);
    36. return;
    37. }
    38. }
    39. // Allow to notify keyguard un-occluding state to KeyguardService, which can happen while
    40. // screen-off, so there might no visibility change involved.
    41. if (!info.getRootLeash().isValid() && info.getType() != TRANSIT_KEYGUARD_UNOCCLUDE) {
    42. // Invalid root-leash implies that the transition is empty/no-op, so just do
    43. // housekeeping and return.
    44. ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Invalid root leash (%s): %s",
    45. transitionToken, info);
    46. onAbort(active);
    47. return;
    48. }
    49. final int changeSize = info.getChanges().size(); //找到带有change的info
    50. boolean taskChange = false;
    51. boolean transferStartingWindow = false;
    52. boolean allOccluded = changeSize > 0;
    53. for (int i = changeSize - 1; i >= 0; --i) {
    54. final TransitionInfo.Change change = info.getChanges().get(i);
    55. taskChange |= change.getTaskInfo() != null;
    56. transferStartingWindow |= change.hasFlags(FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT);
    57. if (!change.hasFlags(FLAG_IS_OCCLUDED)) {
    58. allOccluded = false;
    59. }
    60. }
    61. // There does not need animation when:
    62. // A. Transfer starting window. Apply transfer starting window directly if there is no other
    63. // task change. Since this is an activity->activity situation, we can detect it by selecting
    64. // transitions with only 2 changes where neither are tasks and one is a starting-window
    65. // recipient.
    66. if (!taskChange && transferStartingWindow && changeSize == 2
    67. // B. It's visibility change if the TRANSIT_TO_BACK/TO_FRONT happened when all
    68. // changes are underneath another change.
    69. || ((info.getType() == TRANSIT_TO_BACK || info.getType() == TRANSIT_TO_FRONT)
    70. && allOccluded)) {
    71. // Treat this as an abort since we are bypassing any merge logic and effectively
    72. // finishing immediately.
    73. onAbort(active);
    74. return;
    75. }
    76. setupStartState(active.mInfo, active.mStartT, active.mFinishT); //开始置状态
    77. if (mReadyTransitions.size() > 1) {
    78. // There are already transitions waiting in the queue, so just return.
    79. return;
    80. }
    81. processReadyQueue(); //开始动画
    82. }
    1. 04-23 18:44:02.339 2107 2246 D jinyanmeiainima: BLASTSyncEngine finishNow s.mSyncId:5
    2. 04-23 18:44:02.339 2107 2246 D jinyanmeiainima: BLASTSyncEngine finishNow mActiveSyncs++++:1
    3. 04-23 18:44:02.339 2107 2246 D jinyanmeiainima: BLASTSyncEngine finishNow s.mSyncId:5
    4. 04-23 18:44:02.339 2107 2246 D jinyanmeiainima: BLASTSyncEngine finishNow mActiveSyncs++++:0
    5. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: startAnimation TRANSIT_CHANGE:
    6. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: java.lang.RuntimeException: jinyanmeiainima
    7. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions.dispatchTransition(Transitions.java:708)
    8. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions.playTransition(Transitions.java:693)
    9. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions.processReadyQueue(Transitions.java:627)
    10. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions.onTransitionReady(Transitions.java:600)
    11. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions$TransitionPlayerImpl.lambda$onTransitionReady$0(Transitions.java:1122)
    12. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions$TransitionPlayerImpl.$r8$lambda$qsRfWn1ItrZqnFeABBdxU50jPc4(Unknown Source:0)
    13. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at com.android.wm.shell.transition.Transitions$TransitionPlayerImpl$$ExternalSyntheticLambda0.run(Unknown Source:10)
    14. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at android.os.Handler.handleCallback(Handler.java:958)
    15. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at android.os.Handler.dispatchMessage(Handler.java:99)
    16. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at android.os.Looper.loopOnce(Looper.java:216)
    17. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at android.os.Looper.loop(Looper.java:305)
    18. 04-23 18:44:02.347 3002 3197 D jinyanmeiainima: at android.os.HandlerThread.run(HandlerThread.java:67)

    然后各个继承于

    implements Transitions.TransitionHandler 的对象都会调用到startAnimation

    走各个业务动画逻辑

  • 相关阅读:
    ChatGPT与音乐领域的新篇章
    【网络协议】TCP报文格式
    蓝桥杯打卡Day6
    CSS 01
    julia笔记:字符和字符串
    在Jetson Nano上安装MNN深度学习框架
    15. 三数之和
    Vulkan API的性能及兼容性
    期末前端web大作业——我的家乡陕西介绍网页制作源码HTML+CSS+JavaScript
    bug是测不完的,根本测不完
  • 原文地址:https://blog.csdn.net/u012627628/article/details/138159610