Android 14 transtion 动画流程

打印 上一主题 下一主题

主题 818|帖子 818|积分 2454

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.<init>(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<ActiveTransition> 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.    }
复制代码
  1. 转到 wm services
  2. 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<ActiveTransition> 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.             
  4. final ArrayMap<WindowContainer, ChangeInfo> mChanges = new ArrayMap<>(); //这里的mChanges 也是一个map
  5.         mTargets = calculateTargets(mParticipants, mChanges);
  6.         final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, transaction);
  7.         
  8.                 mController.getTransitionPlayer().onTransitionReady(
  9.                         mToken, info, transaction, mFinishTransaction);
  10.                 if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
  11.                     Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, TRACE_NAME_PLAY_TRANSITION,
  12.             
  13.     }
复制代码
wm.services.Transition.calculateTargets
两个条件不添加动画:
1:!wc.isAttached()
2:!changeInfo.hasChanged()
将符合条件的changeInfo添加到targets 返回
  1. @VisibleForTesting
  2. @NonNull
  3. static ArrayList<ChangeInfo> calculateTargets(ArraySet<WindowContainer> participants,
  4.         ArrayMap<WindowContainer, ChangeInfo> 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<ChangeInfo> 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<Change> 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<ChangeInfo> 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)
复制代码
然后各个继承于
  1. implements Transitions.TransitionHandler 的对象都会调用到startAnimation
复制代码
走各个业务动画逻辑

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表