Launcher's detailed analysis of RecentView display TaskView - android framework vehicle-mounted mobile phone system development

Stack call created by TaskView:

Free video tutorial at station b:
https://www.bilibili.com/video/BV1wj411o7A9/
Insert image description here
TaskView creation call stack:
Insert image description here

In fact, the call stack created here is, but the ViewPool method obviously used here is mainly to reduce frequent creation, so we simply cache it in the ViewPool and take it out when needed.

When to get it from ViewPool? The specific acquisition call chain is as follows:

07-29 17:50:08.170  1065  1065 I lsm444  : java.lang.Exception
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.quickstep.views.RecentsView.getTaskViewFromPool(RecentsView.java:2085)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.quickstep.views.RecentsView.applyLoadPlan(RecentsView.java:1443)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.quickstep.views.RecentsView$$ExternalSyntheticLambda19.accept(Unknown Source:4)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.quickstep.RecentTasksList.lambda$getTasks$3$com-android-quickstep-RecentTasksList(RecentTasksList.java:132)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.quickstep.RecentTasksList$$ExternalSyntheticLambda4.run(Unknown Source:6)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at android.os.Looper.loop(Looper.java:288)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at java.lang.reflect.Method.invoke(Native Method)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-29 17:50:08.170  1065  1065 I lsm444  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

It can be seen from the above that it is mainly through the RecentsView.applyLoadPlan method, which is actually called from the getTasks method.

    public synchronized int getTasks(boolean loadKeysOnly,
            Consumer<ArrayList<GroupTask>> callback) {
    
    
      //省略
        UI_HELPER_EXECUTOR.execute(() -> {
    
    
            if (!mResultsBg.isValidForRequest(requestLoadId, loadKeysOnly)) {
    
    
                mResultsBg = loadTasksInBackground(Integer.MAX_VALUE, requestLoadId, loadKeysOnly);
            }
            TaskLoadResult loadResult = mResultsBg;
            mMainThreadExecutor.execute(() -> {
    
    

                if (callback != null) {
    
    
                    ArrayList<GroupTask> result = copyOf(mResultsUi);
                    callback.accept(result);//这里进行的调用applyLoadPlan
                }
            });
        });

        return requestLoadId;
    }

So where is the getTasks method called?
The call chain of getTask is as follows:


07-29 17:50:08.161  1065  1065 I lsm444  : getTasks 
07-29 17:50:08.161  1065  1065 I lsm444  : java.lang.Exception
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.RecentTasksList.getTasks(RecentTasksList.java:119)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.RecentsModel.getTasks(RecentsModel.java:102)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.views.RecentsView.reloadIfNeeded(RecentsView.java:2103)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.views.RecentsView.updateTaskStackListenerState(RecentsView.java:1634)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.views.RecentsView.setOverviewStateEnabled(RecentsView.java:1178)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.views.LauncherRecentsView.setOverviewStateEnabled(LauncherRecentsView.java:133)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.views.LauncherRecentsView.onStateTransitionStart(LauncherRecentsView.java:100)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.quickstep.views.LauncherRecentsView.onStateTransitionStart(LauncherRecentsView.java:49)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.launcher3.statemanager.StateManager.onStateTransitionStart(StateManager.java:353)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.launcher3.statemanager.StateManager.-$$Nest$monStateTransitionStart(Unknown Source:0)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.launcher3.statemanager.StateManager$1.onAnimationStart(StateManager.java:338)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.animation.Animator$AnimatorListener.onAnimationStart(Animator.java:584)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.animation.AnimatorSet.start(AnimatorSet.java:737)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.animation.AnimatorSet.start(AnimatorSet.java:684)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.launcher3.statemanager.StateManager$StartAnimRunnable.run(StateManager.java:503)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.os.Looper.loop(Looper.java:288)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at java.lang.reflect.Method.invoke(Native Method)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-29 17:50:08.161  1065  1065 I lsm444  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

TaskInfo related data loading:

  /**
     * Loads and creates a list of all the recent tasks.
     */
    @VisibleForTesting
    TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
    
    
        int currentUserId = Process.myUserHandle().getIdentifier();
        //调用到sysui端的getRecentTasks
        ArrayList<GroupedRecentTaskInfo> rawTasks =
                mSysUiProxy.getRecentTasks(numTasks, currentUserId);
      //省略

        return allTasks;
    }


Here, sysui's getRecentTasks will actually be called for query.
This is actually a cross-process communication:
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java

 private static class IRecentTasksImpl extends IRecentTasks.Stub {
    
    
       //省略
        @Override
        public GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId)
//省略
这里核心又调用到了controller的getRecentTasks
            executeRemoteCallWithTaskPermission(mController, "getRecentTasks",
                    (controller) -> out[0] = controller.getRecentTasks(maxNum, flags, userId)
                            .toArray(new GroupedRecentTaskInfo[0]),
                    true /* blocking */);
            return out[0];
        }
    }

@VisibleForTesting
    ArrayList<GroupedRecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
    
    
        // Note: the returned task list is from the most-recent to least-recent order
        //调用到了getRawRecentTasks方法
        final List<ActivityManager.RecentTaskInfo> rawList = getRawRecentTasks(maxNum, flags,
                userId);

        //以下操作主要是为了分屏相关的task可以作为一个整体返回,一般把它们搞成一个gouped,有task1和task2
        
        // Pull out the pairs as we iterate back in the list
        ArrayList<GroupedRecentTaskInfo> recentTasks = new ArrayList<>();
        for (int i = 0; i < rawList.size(); i++) {
    
    
            final ActivityManager.RecentTaskInfo taskInfo = rawList.get(i);
            if (!rawMapping.contains(taskInfo.taskId)) {
    
    
                // If it's not in the mapping, then it was already paired with another task
                continue;
            }

            final int pairedTaskId = mSplitTasks.get(taskInfo.taskId);
            if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains(pairedTaskId)) {
    
    
                final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId);
                rawMapping.remove(pairedTaskId);
                recentTasks.add(new GroupedRecentTaskInfo(taskInfo, pairedTaskInfo,
                        mTaskSplitBoundsMap.get(pairedTaskId)));
            } else {
    
    
                recentTasks.add(new GroupedRecentTaskInfo(taskInfo));
            }
        }
        return recentTasks;
    }
    
   @VisibleForTesting
    List<ActivityManager.RecentTaskInfo> getRawRecentTasks(int maxNum, int flags, int userId) {
    
    
    //本质就是调用到了atms的getRecentTasks方法
        return ActivityTaskManager.getInstance().getRecentTasks(maxNum, flags, userId);
    }

The above acquisition of RecentTask information has been completed. To summarize:
1. The desktop calls sysui to obtain Task information, because sysui actually contains split-screen related TecentTask information.
2. sysui also calls atms to obtain RecentTask information.

Thumbnail setting analysis:

07-30 00:56:38.758  1059  1059 I lsm444  : setThumbnail task = [id=16 windowingMode=0 user=0 lastActiveTime=18031] null thumbnailData = com.android.systemui.shared.recents.model.ThumbnailData@57b6fdb
07-30 00:56:38.758  1059  1059 I lsm444  : java.lang.Exception
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.views.TaskThumbnailView.setThumbnail(TaskThumbnailView.java:150)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.views.TaskThumbnailView.setThumbnail(TaskThumbnailView.java:162)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.views.TaskView.lambda$onTaskListVisibilityChanged$5$com-android-quickstep-views-TaskView(TaskView.java:819)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.views.TaskView$$ExternalSyntheticLambda3.accept(Unknown Source:4)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.TaskThumbnailCache.lambda$updateThumbnailInBackground$1(TaskThumbnailCache.java:147)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.TaskThumbnailCache$$ExternalSyntheticLambda0.accept(Unknown Source:6)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.TaskThumbnailCache$1.handleResult(TaskThumbnailCache.java:173)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.TaskThumbnailCache$1.handleResult(TaskThumbnailCache.java:163)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.util.CancellableTask.lambda$run$0$com-android-quickstep-util-CancellableTask(CancellableTask.java:43)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.quickstep.util.CancellableTask$$ExternalSyntheticLambda0.run(Unknown Source:4)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at android.os.Handler.handleCallback(Handler.java:942)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at android.os.Looper.loopOnce(Looper.java:201)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at android.os.Looper.loop(Looper.java:288)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at android.app.ActivityThread.main(ActivityThread.java:7898)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at java.lang.reflect.Method.invoke(Native Method)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
07-30 00:56:38.758  1059  1059 I lsm444  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

Setting the relevant thumbnail is triggered by the following code:

  public void onTaskListVisibilityChanged(boolean visible, @TaskDataChanges int changes) {
    
    
     
        if (visible) {
    
    
            // These calls are no-ops if the data is already loaded, try and load the high
            // resolution thumbnail if the state permits
            RecentsModel model = RecentsModel.INSTANCE.get(getContext());
            TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
            TaskIconCache iconCache = model.getIconCache();

            if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
    
    
            //这里进行相关加载缩略图加载
                mThumbnailLoadRequest = thumbnailCache.updateThumbnailInBackground(
                        mTask, thumbnail -> {
    
    
                        //加载完成后进行回调
                            mSnapshotView.setThumbnail(mTask, thumbnail);
                        });
            }
           //省略
    }

Next look at the updateThumbnailInBackground method:

    public CancellableTask updateThumbnailInBackground(
            Task task, Consumer<ThumbnailData> callback) {
    
    
        Preconditions.assertUIThread();
//省略
        return updateThumbnailInBackground(task.key, !mHighResLoadingState.isEnabled(), t -> {
    
    
        //加在完成后的回调有
            task.thumbnail = t;
            callback.accept(t);
        });
    }

Let’s take a look at the implementation of the updateThumbnailInBackground method:


    private CancellableTask updateThumbnailInBackground(TaskKey key, boolean lowResolution,
            Consumer<ThumbnailData> callback) {
    
    
        Preconditions.assertUIThread();

        ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
        if (cachedThumbnail != null &&  cachedThumbnail.thumbnail != null
                && (!cachedThumbnail.reducedResolution || lowResolution)) {
    
    
            // Already cached, lets use that thumbnail
            callback.accept(cachedThumbnail);
            return null;
        }

        CancellableTask<ThumbnailData> request = new CancellableTask<ThumbnailData>() {
    
    
            @Override
            public ThumbnailData getResultOnBg() {
    
    
            //最终其实是通过传递taskId到ams中获取对应的缩略图
                return ActivityManagerWrapper.getInstance().getTaskThumbnail(
                        key.id, lowResolution);
            }

            @Override
            public void handleResult(ThumbnailData result) {
    
    
                mCache.put(key, result);
                callback.accept(result);
            }
        };
        mBgExecutor.execute(request);
        return request;
    }

Guess you like

Origin blog.csdn.net/learnframework/article/details/131998148