Android核心窗口

[复制链接]
发表于 2025-12-11 17:33:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
概述

作甚核心窗口?顾名思义就是有核心窗口,要留意和view的核心概念要做区分,两个不是一个层面上的概念。为什么窗口要拥有核心呢,下面都是我的明白,有不对的地方接待讨论:核心窗口重要利用在InputDispachar分发按键事故——keyevent阶段,在keyevent分发阶段,此时的核心窗口就是该事故应该分发给的窗口。不像触摸事故,在分发过程中可以通过触摸的坐标推断给事故应该分发给谁人窗口,keyeven来自物理按键,没有对应的坐标,只能通过核心窗口确定发送给谁人窗口。
表明完毕核心窗口的作用,在来简朴先容下一种常见的ANR,即no focus anr,这种anr发生就是由于在分发一次keyEvent时,没有找到核心窗口,便开始了anr计时,5s之后,分发事故的过程中发仍旧没有对应的核心窗口,便会发生无核心ANR。
核心窗口的更新流程在Android12之后,涉及到了三个模块:WMS, Surfaceflinger, InputDispachar,下文将会分析具体得人更新核心窗口流程。
起首明白三个概念:
1. 顶部核心屏幕:mTopFocusedDisplayId,这个变量的声明位于窗口的根节点RootWindowContainer中.
这个变量代表了相应没有指明屏幕的key大概pointer范例的event的屏幕的id。
  1. frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
  2. // The ID of the display which is responsible for receiving display-unspecified key and pointer
  3.     // events.
  4.     private int mTopFocusedDisplayId = INVALID_DISPLAY;
复制代码
2. 核心app:mFocusedApp代表了一个DisplayContent上正处于前台的ActivityRecord,一样寻常这个ActivityRecord下的窗口将会成为核心窗口,存在当核心app属于该ActivityRecord,但是核心窗口不属于该ActivityRecord下属的窗口的情况。
  1. frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
  2. /**
  3.      * The foreground app of this display. Windows below this app cannot be the focused window. If
  4.      * the user taps on the area outside of the task of the focused app, we will notify AM about the
  5.      * new task the user wants to interact with.
  6.      */
  7.     ActivityRecord mFocusedApp = null;
复制代码
3. 核心窗口:mCurrentFocus,当前正在与用户交互的窗口。此窗口负责吸取来自用户的键事故和指针事故。
  1. frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
  2. /**
  3.      /**
  4.      * Window that is currently interacting with the user. This window is responsible for receiving
  5.      * key events and pointer events from the user.
  6.      */
  7.     WindowState mCurrentFocus = null;
复制代码
mTopFocusedDisplayId界说在根节点RootWindowContainer中,这表明整个Android体系中只能有一个顶部核心屏幕,mFocusedApp和mCurrentFocus界说在DisplayContent中,表明每个屏幕都有自己的核心app和核心窗口。
在WindowState的构建过程中,会构建出一个范例为InputWindowHandle的对象,该对象的重要作用是生存窗口的一些信息,随后发送给InputDispatcher,InputWindowHandle在input系代表该应用窗口的对象,用于辨认以及分发事故。
先来总结一下核心窗口的产生过程,这个流程筹划到WMS,surfaceflinger,InputDispatcher:核心窗口的天生过程可以说是一个选拔,选送的过程,在窗口发生一些改变的时间会触发到wms去
  1. frameworks/base/services/core/java/com/android/server/wm/WindowState.java
  2. WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
  3.             WindowState parentWindow, int appOp, WindowManager.LayoutParams a, int viewVisibility,
  4.             int ownerId, int showUserId, boolean ownerCanAddInternalSystemWindow,
  5.             PowerManagerWrapper powerManagerWrapper) {
  6.         super(service);
  7.         mTmpTransaction = service.mTransactionFactory.get();
  8.         mSession = s;
  9.         mClient = c;
  10.         mAppOp = appOp;
  11.         mToken = token;
  12.         mActivityRecord = mToken.asActivityRecord();
  13.         mOwnerUid = ownerId;
  14.         mShowUserId = showUserId;
  15.         mOwnerCanAddInternalSystemWindow = ownerCanAddInternalSystemWindow;
  16.         mWindowId = new WindowId(this);
  17.         mAttrs.copyFrom(a);
  18.         mLastSurfaceInsets.set(mAttrs.surfaceInsets);
  19.         mViewVisibility = viewVisibility;
  20.         mPolicy = mWmService.mPolicy;
  21.         mContext = mWmService.mContext;
  22.         DeathRecipient deathRecipient = new DeathRecipient();
  23.         mPowerManagerWrapper = powerManagerWrapper;
  24.         mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
  25.         // 如下:
  26.         mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(
  27.                 mActivityRecord != null
  28.                         ? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
  29.                 getDisplayId()));
  30.         mInputWindowHandle.setOwnerPid(s.mPid);
  31.         mInputWindowHandle.setOwnerUid(s.mUid);
  32.         mInputWindowHandle.setName(getName());
  33.         mInputWindowHandle.setPackageName(mAttrs.packageName);
  34.         mInputWindowHandle.setLayoutParamsType(mAttrs.type);
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/WindowState.java
  2. /**
  3. * Functions as a handle for a window that can receive input.
  4. * Enables the native input dispatcher to refer indirectly to the window manager's window state.
  5. * @hide
  6. */
  7. public final class InputWindowHandle {
  8.     // Pointer to the native input window handle.
  9.     // This field is lazily initialized via JNI.
  10.     @SuppressWarnings("unused")
  11.     private long ptr;
  12.     // The input application handle.
  13.     public InputApplicationHandle inputApplicationHandle;
  14.     // The token associates input data with a window and its input channel. The client input
  15.     // channel and the server input channel will both contain this token.
  16.     public IBinder token;
  17.     // The window name.
  18.     public String name;
  19.     // Window layout params attributes.  (WindowManager.LayoutParams)
  20.     public int layoutParamsFlags;
  21.     public int layoutParamsType;
  22.     // Dispatching timeout.
  23.     public long dispatchingTimeoutMillis;
  24.     // Window frame.
  25.     public int frameLeft;
  26.     public int frameTop;
  27.     public int frameRight;
  28.     public int frameBottom;
  29.     public int surfaceInset;
  30.     // Global scaling factor applied to touch events when they are dispatched
  31.     // to the window
  32.     public float scaleFactor;
复制代码
  1. frameworks/base/core/java/android/view/InputApplicationHandle.java
  2. /**
  3. * Functions as a handle for an application that can receive input.
  4. * Enables the native input dispatcher to refer indirectly to the window manager's
  5. * application window token.
  6. * @hide
  7. */
  8. public final class InputApplicationHandle {
  9.     // Pointer to the native input application handle.
  10.     // This field is lazily initialized via JNI.
  11.     @SuppressWarnings("unused")
  12.     private long ptr;
  13.     // Application name.
  14.     public final @NonNull String name;
  15.     // Dispatching timeout.
  16.     public final long dispatchingTimeoutMillis;
  17.     public final @NonNull IBinder token;
  18.     private native void nativeDispose();
  19.     public InputApplicationHandle(@NonNull IBinder token, @NonNull String name,
  20.             long dispatchingTimeoutMillis) {
  21.         this.token = token;
  22.         this.name = name;
  23.         this.dispatchingTimeoutMillis = dispatchingTimeoutMillis;
  24.     }
  25.     public InputApplicationHandle(InputApplicationHandle handle) {
  26.         this.token = handle.token;
  27.         this.dispatchingTimeoutMillis = handle.dispatchingTimeoutMillis;
  28.         this.name = handle.name;
  29.     }
  30.     @Override
  31.     protected void finalize() throws Throwable {
  32.         try {
  33.             nativeDispose();
  34.         } finally {
  35.             super.finalize();
  36.         }
  37.     }
  38. }
复制代码
一.WMS端革新流程

在framework中,触发核心窗口更新的流程的入口是WMS.updateFocusedWindowLocked,触发该函数的位置在fw中非常的多,比如在窗口布局过程中,窗口添加过程中,窗口的移除过程中:

updateFocusedWindowLocked
可见该函数的参数有两个,第一个参数代表更新核心的场景,如下,共5个场景,可以简朴代表调用updateFocusedWindowLocked的场景,第二个参数代表在更新核心窗口的过程是否顺道更新一下InputWindows信息。
在wms的updateFocusedWindowLocked方法中进一步调用了RootWindowContainer的updateFocusedWindowLocked
  1. frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
  2. static final int UPDATE_FOCUS_NORMAL = 0;
  3. /** Caller will assign layers */
  4. static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
  5. /** Caller is performing surface placement */
  6. static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
  7. /** Caller will performSurfacePlacement */
  8. static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
  9. /** Indicates we are removing the focused window when updating the focus. */
  10. static final int UPDATE_FOCUS_REMOVING_FOCUS = 4;
  11. boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
  12.         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
  13.         boolean changed = mRoot.updateFocusedWindowLocked(mode, updateInputWindows);
  14.         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
  15.         return changed;
  16.     }
复制代码
在RootWindowContainer方法中可见随即遍历了每一个DisplayContent,开始选拔每个DisplayContent上的核心窗口:dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
todo 去形貌一下topFocusedDisplayId的革新过程
  1. frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
  2. boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
  3.         mTopFocusedAppByProcess.clear();
  4.         boolean changed = false;
  5.         // 先初始化一下topFocusedDisplayId
  6.         int topFocusedDisplayId = INVALID_DISPLAY;
  7.         遍历RootWindowContainer下的每一个DisplayContent
  8.         for (int i = mChildren.size() - 1; i >= 0; --i) {
  9.             final DisplayContent dc = mChildren.get(i);
  10.             // 调用每一DisplayContent上的updateFocusedWindowLocked,去更新每一个DisplayContent上的焦点窗口
  11.             changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
  12.             final WindowState newFocus = dc.mCurrentFocus;
  13.             if (newFocus != null) {
  14.                 final int pidOfNewFocus = newFocus.mSession.mPid;
  15.                 if (mTopFocusedAppByProcess.get(pidOfNewFocus) == null) {
  16.                     mTopFocusedAppByProcess.put(pidOfNewFocus, newFocus.mActivityRecord);
  17.                 }
  18.                 if (topFocusedDisplayId == INVALID_DISPLAY) {
  19.                     topFocusedDisplayId = dc.getDisplayId();
  20.                 }
  21.             } else if (topFocusedDisplayId == INVALID_DISPLAY && dc.mFocusedApp != null) {
  22.                 // The top-most display that has a focused app should still be the top focused
  23.                 // display even when the app window is not ready yet (process not attached or
  24.                 // window not added yet).
  25.                 topFocusedDisplayId = dc.getDisplayId();
  26.             }
  27.         }
  28.         // 选了一圈下来,如果topFocusedDisplayId == INVALID_DISPLAY,就把topFocusedDisplayId = DEFAULT_DISPLAY
  29.         if (topFocusedDisplayId == INVALID_DISPLAY) {
  30.             topFocusedDisplayId = DEFAULT_DISPLAY;
  31.         }
  32.         if (mTopFocusedDisplayId != topFocusedDisplayId) {
  33.             mTopFocusedDisplayId = topFocusedDisplayId;
  34.             mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
  35.             mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
  36.             ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d", topFocusedDisplayId);
  37.         }
  38.         return changed;
  39.     }
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
  2. /**
  3.      * Update the focused window and make some adjustments if the focus has changed.
  4.      *
  5.      * @param mode Indicates the situation we are in. Possible modes are:
  6.      *             {@link WindowManagerService#UPDATE_FOCUS_NORMAL},
  7.      *             {@link WindowManagerService#UPDATE_FOCUS_PLACING_SURFACES},
  8.      *             {@link WindowManagerService#UPDATE_FOCUS_WILL_PLACE_SURFACES},
  9.      *             {@link WindowManagerService#UPDATE_FOCUS_REMOVING_FOCUS}
  10.      * @param updateInputWindows Whether to sync the window information to the input module.
  11.      * @param topFocusedDisplayId Display id of current top focused display.
  12.      * @return {@code true} if the focused window has changed.
  13.      */
  14.     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
  15.             int topFocusedDisplayId) {
  16.         WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
  17.         if (mCurrentFocus == newFocus) {
  18.             // add by sd. fix not trust virtual display binder leak.
  19.             if (newFocus == null && !isTrusted()) {
  20.                 mWinRemovedSinceNullFocus.clear();
  21.                 mWinAddedSinceNullFocus.clear();
  22.             }
  23.             // end
  24.             return false;
  25.         }
  26.         
  27.         ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
  28.                 mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
  29.         final WindowState oldFocus = mCurrentFocus;
  30.         mCurrentFocus = newFocus;
  31.       
  32.         if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
  33.             // If we defer assigning layers, then the caller is responsible for doing this part.
  34.             getInputMonitor().setInputFocusLw(newFocus, updateInputWindows);
  35.         }
  36.         adjustForImeIfNeeded();
  37.         // We may need to schedule some toast windows to be removed. The toasts for an app that
  38.         // does not have input focus are removed within a timeout to prevent apps to redress
  39.         // other apps' UI.
  40.         scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
  41.         if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
  42.             pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
  43.         }
  44.         // Notify the accessibility manager for the change so it has the windows before the newly
  45.         // focused one starts firing events.
  46.         // TODO(b/151179149) investigate what info accessibility service needs before input can
  47.         // dispatch focus to clients.
  48.         if (mWmService.mAccessibilityController != null) {
  49.             mWmService.mH.sendMessage(PooledLambda.obtainMessage(
  50.                     this::updateAccessibilityOnWindowFocusChanged,
  51.                     mWmService.mAccessibilityController));
  52.         }
  53.         mLastFocus = mCurrentFocus;
  54.         return true;
  55.     }
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
  2. /**
  3.      * Looking for the focused window on this display if the top focused display hasn't been
  4.      * found yet (topFocusedDisplayId is INVALID_DISPLAY) or per-display focused was allowed.
  5.      *
  6.      * @param topFocusedDisplayId Id of the top focused display.
  7.      * @return The focused window or null if there isn't any or no need to seek.
  8.      */
  9.     WindowState findFocusedWindowIfNeeded(int topFocusedDisplayId) {
  10.         return (mWmService.mPerDisplayFocusEnabled || topFocusedDisplayId == INVALID_DISPLAY)
  11.                     ? findFocusedWindow() : null;
  12.     }
  13.     WindowState findFocusedWindow() {
  14.         mTmpWindow = null;
  15.         forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */);
  16.         if (mTmpWindow == null) {
  17.             ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows, display=%d",
  18.                     getDisplayId());
  19.             return null;
  20.         }
  21.         return mTmpWindow;
  22.     }
复制代码
如下会从上到下遍历该DisplayContent上的全部WindowState,如果找到符合条件的窗口,那么该窗口,则将该窗口生存在mTmpWindow,并返回ture。由于是从上往下遍历,以是层级越高的窗口越偶然机成为核心窗口。
起首不满足canReceiveKeys条件的是不能成为核心窗口的.其他成为核心窗口的条件不赘述。
  1. frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
  2. private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
  3.         final ActivityRecord focusedApp = mFocusedApp;
  4.         ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b, reason=%s",
  5.                 w, w.mAttrs.flags, w.canReceiveKeys(),
  6.                 w.canReceiveKeysReason(false /* fromUserTouch */));
  7.         // 焦点窗口首先要满足 canReceiveKeys,否则无法成为焦点窗口。
  8.         if (!w.canReceiveKeys()) {
  9.             return false;
  10.         }
  11.         // 输入法相关,暂时不分析
  12.         if (w.mIsImWindow && w.isChildWindow() && (mImeLayeringTarget == null
  13.                 || !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME))) {
  14.             return false;
  15.         }
  16.         if (w.mAttrs.type == TYPE_INPUT_METHOD_DIALOG && mImeLayeringTarget != null
  17.                 && !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME)
  18.                 && mImeLayeringTarget.isAnimating(PARENTS | TRANSITION,
  19.                 ANIMATION_TYPE_APP_TRANSITION)) {
  20.             return false;
  21.         }
  22.         // 获取当前窗口所属的ActivityRecord
  23.         final ActivityRecord activity = w.mActivityRecord;
  24.         //
  25.         if (focusedApp == null) {
  26.             ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
  27.                     "findFocusedWindow: focusedApp=null using new focus @ %s", w);
  28.             mTmpWindow = w;
  29.             return true;
  30.         }
  31.         if (!focusedApp.windowsAreFocusable()) {
  32.             // Current focused app windows aren't focusable...
  33.             ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: focusedApp windows not"
  34.                     + " focusable using new focus @ %s", w);
  35.             mTmpWindow = w;
  36.             return true;
  37.         }
  38.         // Descend through all of the app tokens and find the first that either matches
  39.         // win.mActivityRecord (return win) or mFocusedApp (return null).
  40.         //如果当前所遍历到的窗口的层级位于focusedApp之下且该窗口属于activity的窗口,则把焦点窗口置为null。然后返回。
  41.         if (activity != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) {
  42.             if (focusedApp.compareTo(activity) > 0) {
  43.                 // App root task below focused app root task. No focus for you!!!
  44.                 ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
  45.                         "findFocusedWindow: Reached focused app=%s", focusedApp);
  46.                 mTmpWindow = null;
  47.                 return true;
  48.             }
  49.         }
  50.         // 以上条件都不符合
  51.         ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: Found new focus @ %s", w);
  52.         mTmpWindow = w;
  53.         return true;
  54.     };
复制代码
canReceiveKeys == true的条件
  1. frameworks/base/services/core/java/com/android/server/wm/WindowState.java
  2. boolean canReceiveKeys() {
  3.         return canReceiveKeys(false /* fromUserTouch */);
  4.     }
  5.     public String canReceiveKeysReason(boolean fromUserTouch) {
  6.         return "fromTouch= " + fromUserTouch
  7.                 + " isVisibleOrAdding=" + isVisibleOrAdding()
  8.                 + " mViewVisibility=" + mViewVisibility
  9.                 + " mRemoveOnExit=" + mRemoveOnExit
  10.                 + " flags=" + mAttrs.flags
  11.                 + " appWindowsAreFocusable="
  12.                 + (mActivityRecord == null || mActivityRecord.windowsAreFocusable(fromUserTouch))
  13.                 + " canReceiveTouchInput=" + canReceiveTouchInput()
  14.                 + " displayIsOnTop=" + getDisplayContent().isOnTop()
  15.                 + " displayIsTrusted=" + getDisplayContent().isTrusted();
  16.     }
  17.     public boolean canReceiveKeys(boolean fromUserTouch) {
  18.         final boolean canReceiveKeys = isVisibleOrAdding()
  19.                 && (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
  20.                 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
  21.                 && (mActivityRecord == null || mActivityRecord.windowsAreFocusable(fromUserTouch))
  22.                 && canReceiveTouchInput();
  23.         if (!canReceiveKeys) {
  24.             return false;
  25.         }
  26.         // Do not allow untrusted virtual display to receive keys unless user intentionally
  27.         // touches the display.
  28.         return fromUserTouch || getDisplayContent().isOnTop()
  29.                 || getDisplayContent().isTrusted();
  30.     }
  31.     @Override
  32.     public boolean canShowWhenLocked() {
  33.         final boolean showBecauseOfActivity =
  34.                 mActivityRecord != null && mActivityRecord.canShowWhenLocked();
  35.         final boolean showBecauseOfWindow = (getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0;
  36.         return showBecauseOfActivity || showBecauseOfWindow;
  37.     }
  38.     /**
  39.      * @return {@code true} if this window can receive touches based on among other things,
  40.      * windowing state and recents animation state.
  41.      **/
  42.     boolean canReceiveTouchInput() {
  43.         if (mActivityRecord == null  || mActivityRecord.getTask() == null) {
  44.             return true;
  45.         }
  46.         return !mActivityRecord.getTask().getRootTask().shouldIgnoreInput()
  47.                 && mActivityRecord.mVisibleRequested
  48.                 && !isRecentsAnimationConsumingAppInput();
  49.     }
复制代码
回到DisplayCpntent.updateFocusedWindowLocked
  1. frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
  2. /**
  3.      * Update the focused window and make some adjustments if the focus has changed.
  4.      *
  5.      * @param mode Indicates the situation we are in. Possible modes are:
  6.      *             {@link WindowManagerService#UPDATE_FOCUS_NORMAL},
  7.      *             {@link WindowManagerService#UPDATE_FOCUS_PLACING_SURFACES},
  8.      *             {@link WindowManagerService#UPDATE_FOCUS_WILL_PLACE_SURFACES},
  9.      *             {@link WindowManagerService#UPDATE_FOCUS_REMOVING_FOCUS}
  10.      * @param updateInputWindows Whether to sync the window information to the input module.
  11.      * @param topFocusedDisplayId Display id of current top focused display.
  12.      * @return {@code true} if the focused window has changed.
  13.      */
  14.      
  15.     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
  16.             int topFocusedDisplayId) {
  17.         // 此时的newFocus为找到的新焦点窗口
  18.         WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
  19.         // 如该Displaycontent上的焦点窗口没有发生变化,则不用去更新,返回
  20.         if (mCurrentFocus == newFocus) {
  21.             // add by sd. fix not trust virtual display binder leak.
  22.             if (newFocus == null && !isTrusted()) {
  23.                 mWinRemovedSinceNullFocus.clear();
  24.                 mWinAddedSinceNullFocus.clear();
  25.             }
  26.             // end
  27.             return false;
  28.         }
  29.         
  30.         ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
  31.                 mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
  32.         final WindowState oldFocus = mCurrentFocus;
  33.         mCurrentFocus = newFocus;
  34.        // 如果更新模式不是UPDATE_FOCUS_WILL_ASSIGN_LAYERS,则把刚才选举出的焦点窗口设置给getInputMonitor,随后会交给surfaceflinger。
  35.         if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
  36.             // If we defer assigning layers, then the caller is responsible for doing this part.
  37.             getInputMonitor().setInputFocusLw(newFocus, updateInputWindows);
  38.         }
  39.         .....
  40.         mLastFocus = mCurrentFocus;
  41.         return true;
  42.     }
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
  2. void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
  3.         ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Input focus has changed to %s display=%d",
  4.                 newWindow, mDisplayId);
  5.         final IBinder focus = newWindow != null ? newWindow.mInputChannelToken : null;
  6.         // 没有发生改变 返回
  7.         if (focus == mInputFocus) {
  8.             return;
  9.         }
  10.         if (newWindow != null && newWindow.canReceiveKeys()) {
  11.             // Displaying a window implicitly causes dispatching to be unpaused.
  12.             // This is to protect against bugs if someone pauses dispatching but
  13.             // forgets to resume.
  14.             newWindow.mToken.paused = false;
  15.         }
  16.         // 设置 mUpdateInputWindowsNeeded = true;
  17.         setUpdateInputWindowsNeededLw();
  18.         if (updateInputWindows) {
  19.             updateInputWindowsLw(false /*force*/);
  20.         }
  21.     }
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
  2. /* Updates the cached window information provided to the input */
  3. void updateInputWindowsLw(boolean force) {
  4.         if (!force && !mUpdateInputWindowsNeeded) {
  5.             return;
  6.         }
  7.         scheduleUpdateInputWindows();
  8.     }
  9.     private void scheduleUpdateInputWindows() {
  10.         if (mDisplayRemoved) {
  11.             return;
  12.         }
  13.         if (!mUpdateInputWindowsPending) {
  14.             mUpdateInputWindowsPending = true;
  15.             mHandler.post(mUpdateInputWindows);
  16.         }
  17.     }
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
  2. private class UpdateInputWindows implements Runnable {
  3.         @Override
  4.         public void run() {
  5.             synchronized (mService.mGlobalLock) {
  6.                 mUpdateInputWindowsPending = false;
  7.                 mUpdateInputWindowsNeeded = false;
  8.                 if (mDisplayRemoved) {
  9.                     return;
  10.                 }
  11.                 // Populate the input window list with information about all of the windows that
  12.                 // could potentially receive input.
  13.                 // As an optimization, we could try to prune the list of windows but this turns
  14.                 // out to be difficult because only the native code knows for sure which window
  15.                 // currently has touch focus.
  16.                 // If there's a drag in flight, provide a pseudo-window to catch drag input
  17.                 final boolean inDrag = mService.mDragDropController.dragDropActiveLocked();
  18.                 // Add all windows on the default display.
  19.                 mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);
  20.             }
  21.         }
  22.     }
复制代码
  1. frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
  2. private void updateInputWindows(boolean inDrag) {
  3.             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");
  4.             mPipInputConsumer = getInputConsumer(INPUT_CONSUMER_PIP);
  5.             mWallpaperInputConsumer = getInputConsumer(INPUT_CONSUMER_WALLPAPER);
  6.             mRecentsAnimationInputConsumer = getInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
  7.             mAddPipInputConsumerHandle = mPipInputConsumer != null;
  8.             mAddWallpaperInputConsumerHandle = mWallpaperInputConsumer != null;
  9.             mAddRecentsAnimationInputConsumerHandle = mRecentsAnimationInputConsumer != null;
  10.             mDisableWallpaperTouchEvents = false;
  11.             mInDrag = inDrag;
  12.             resetInputConsumers(mInputTransaction);
  13.             // 遍历对应屏幕上的所有WindowState,更新他们的InputWindowHandle,随后发送给SurfaceFlinger
  14.             mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */);
  15.             // 更新焦点窗口信息给SurfaceFlinger
  16.             updateInputFocusRequest(mRecentsAnimationInputConsumer);
  17.             if (!mUpdateInputWindowsImmediately) {
  18.                 mDisplayContent.getPendingTransaction().merge(mInputTransaction);
  19.                 mDisplayContent.scheduleAnimation();
  20.             }
  21.             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
  22.         }
复制代码
更新全部窗口的InputWindowHandle信息
  1. public void accept(WindowState w) {
  2.             ......
  3.             if (w.mWinAnimator.hasSurface()) {
  4.                 //更新该窗口的inputWindowHandle信息
  5.                 populateInputWindowHandle(inputWindowHandle, w);
  6.                 // 将更新后的inputWindowHandle发送给Surfaceflinger
  7.                 setInputWindowInfoIfNeeded(mInputTransaction,
  8.                         w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
  9.             }
  10.         }
  11.     }
复制代码
更新全部核心窗口
  1. private void updateInputFocusRequest(InputConsumerImpl recentsAnimationInputConsumer) {
  2.         final WindowState focus = mDisplayContent.mCurrentFocus;
  3.         ......
  4.         requestFocus(focusToken, focus.getName());
  5.     }
  6. }
复制代码
  1. private void requestFocus(IBinder focusToken, String windowName) {
  2.         if (focusToken == mInputFocus) {
  3.             return;
  4.         }
  5.         mInputFocus = focusToken;
  6.         mInputTransaction.setFocusedWindow(mInputFocus, windowName, mDisplayId);
  7.         EventLog.writeEvent(LOGTAG_INPUT_FOCUS, "Focus request " + windowName,
  8.                 "reason=UpdateInputWindows");
  9.         ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Focus requested for window=%s", windowName);
  10.     }
复制代码
二.SurfaceFlinger端革新流程

SurfaceFlinger中省略了处置处罚Trasnaction的流程,直接分析SurfaceFlinger向InputDispatcher更新layer的信息和核心信息.
1.网络windowInfos 遍历SurfaceFlinger 当前绘制的Layer聚集mDrawingState,当对应的layer有inputChannel时把该layer的 信息封装后 生存在 windowInfos. 网络 全部的display信息,添加到 displayInfos中.
2.更新 WindowInfo等信息 到相干的监听,InputDispatcher 便是此中的监听之一
3.更新 FocusedWindow信息至 inputFlinger.
  1. void SurfaceFlinger::updateInputFlinger() {
  2.     ATRACE_CALL();
  3.     if (!mInputFlinger) {
  4.         return;
  5.     }
  6.     std::vector<WindowInfo> windowInfos;
  7.     std::vector<DisplayInfo> displayInfos;
  8.     bool updateWindowInfo = false;
  9.     // 只有当有mVisibleRegionsDirty || mInputInfoChanged变化的之后才去收集   windowInfos 和displayInfos
  10.     if (mVisibleRegionsDirty || mInputInfoChanged) {
  11.         mInputInfoChanged = false;
  12.         updateWindowInfo = true;
  13.         // 1.收集windowInfos 遍历SurfaceFlinger 当前绘制的Layer集合mDrawingState,当对应的layer有inputChannel时
  14.         // 把该layer的 信息封装后 保存在 windowInfos
  15.         // 2.收集 所有的display信息,添加到 displayInfos中
  16.         buildWindowInfos(windowInfos, displayInfos);
  17.     }
  18.     // 当 上层 有请求 焦点窗口时, mInputWindowCommands 不为空
  19.     if (!updateWindowInfo && mInputWindowCommands.empty()) {
  20.         return;
  21.     }
  22.     BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo,
  23.                                                       windowInfos = std::move(windowInfos),
  24.                                                       displayInfos = std::move(displayInfos),
  25.                                                       inputWindowCommands =
  26.                                                               std::move(mInputWindowCommands),
  27.                                                       inputFlinger = mInputFlinger, this]() {
  28.         ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
  29.         if (updateWindowInfo) {
  30.             // 更新 WindowInfo等信息 到相关的监听,InputDispatcher 便是其中的监听之一
  31.             mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
  32.                                                             inputWindowCommands.syncInputWindows);
  33.         } else if (inputWindowCommands.syncInputWindows) { // syncInputWindows 在特殊情况下为 false,普通更新信息 都为false
  34.             // If the caller requested to sync input windows, but there are no
  35.             // changes to input windows, notify immediately.
  36.             windowInfosReported();
  37.         }
  38.         // 更新 FocusedWindow信息至 inputFlinger,当上层有请求新的焦点窗口时 inputWindowCommands.focusRequests 就有值
  39.         for (const auto& focusRequest : inputWindowCommands.focusRequests) {
  40.             inputFlinger->setFocusedWindow(focusRequest);
  41.         }
  42.     }});
  43.     mInputWindowCommands.clear();
  44. }
复制代码
至此Surfaceflinger的相干分析完毕.
三.InputFlinger端核心革新流程

1.更新InputFlinger端的InputWindowInfo信息

1.更新Display信息到 mDisplayInfos
2.更新 WindowInfoHandle 到 mWindowHandlesByDisplay中
  1. frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
  2. void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
  3.     // The listener sends the windows as a flattened array. Separate the windows by display for
  4.     // more convenient parsing.
  5.     std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
  6.     for (const auto& info : update.windowInfos) {
  7.         handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
  8.         handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
  9.     }
  10.     { // acquire lock
  11.         std::scoped_lock _l(mLock);
  12.         // Ensure that we have an entry created for all existing displays so that if a displayId has
  13.         // no windows, we can tell that the windows were removed from the display.
  14.         for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
  15.             handlesPerDisplay[displayId];
  16.         }
  17.                
  18.                
  19.                 // 更新Display信息到 mDisplayInfos
  20.         mDisplayInfos.clear();
  21.         for (const auto& displayInfo : update.displayInfos) {
  22.             mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
  23.         }
  24.         
  25.         // 将会更新 WindowInfoHandle 到 mWindowHandlesByDisplay中
  26.         for (const auto& [displayId, handles] : handlesPerDisplay) {
  27.             setInputWindowsLocked(handles, displayId);
  28.         }
  29.         if (update.vsyncId < mWindowInfosVsyncId) {
  30.             ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
  31.                   ", current update vsync id: %" PRId64,
  32.                   mWindowInfosVsyncId, update.vsyncId);
  33.         }
  34.         mWindowInfosVsyncId = update.vsyncId;
  35.     }
  36.     // Wake up poll loop since it may need to make new input dispatching choices.
  37.     mLooper->wake();
  38. }
复制代码
2.更新InputFlinger端的核心信息点窗口:

该过程中重要做了两件事:

  • 在更新 屏幕–核心map,返回更新结果的布局体,struct FocusChanges {       sp<IBinder> oldFocus;       sp<IBinder> newFocus;       int32_t displayId;       std::string reason;
    可见该布局体包罗原始核心信息,更新的核心窗口信息,屏幕id,核心改变缘故起因。
  • 把更新结果关照到窗口端
  1. frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
  2. void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
  3.     { // acquire lock
  4.         std::scoped_lock _l(mLock);
  5.         // 去更新对应屏幕上的焦点信息,并返回更新结果的结构体
  6.         std::optional<FocusResolver::FocusChanges> changes =
  7.                 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
  8.         // change不为空,说明更新成功,接下把更新结果通知到窗口端
  9.         if (changes) {
  10.             onFocusChangedLocked(*changes);
  11.         }
  12.     } // release lock
  13.     // Wake up poll loop since it may need to make new input dispatching choices.
  14.     mLooper->wake();
  15. }
复制代码
2.1 在更新 屏幕–核心map,返回更新结果的布局体
  1. frameworks/native/services/inputflinger/dispatcher/FocusResolver.cpp
  2. std::optional<FocusResolver::FocusChanges> FocusResolver::setFocusedWindow(
  3.         const FocusRequest& request, const std::vector<sp<InputWindowHandle>>& windows) {
  4.     const int32_t displayId = request.displayId;
  5.     const sp<IBinder> currentFocus = getFocusedWindowToken(displayId);
  6.     if (currentFocus == request.token) {
  7.         ALOGD_IF(DEBUG_FOCUS,
  8.                  "setFocusedWindow %s on display %" PRId32 " ignored, reason: already focused",
  9.                  request.windowName.c_str(), displayId);
  10.         return std::nullopt;
  11.     }
  12.     // request.focusedToken 一般为null,跳过
  13.     if (request.focusedToken) {
  14.         if (currentFocus != request.focusedToken) {
  15.             ALOGW("setFocusedWindow %s on display %" PRId32
  16.                   " ignored, reason: focusedToken %s is not focused",
  17.                   request.windowName.c_str(), displayId, request.focusedWindowName.c_str());
  18.             return std::nullopt;
  19.         }
  20.         // 判断新请求的窗口是否可以成为焦点窗口
  21.         Focusability result = isTokenFocusable(request.token, windows);
  22.         if (result == Focusability::OK) {
  23.             return updateFocusedWindow(displayId, "setFocusedWindow with focus check",
  24.                                        request.token, request.windowName);
  25.         }
  26.         ALOGW("setFocusedWindow %s on display %" PRId32 " ignored, reason: %s",
  27.               request.windowName.c_str(), displayId, NamedEnum::string(result).c_str());
  28.         return std::nullopt;
  29.     }
  30.     Focusability result = isTokenFocusable(request.token, windows);
  31.     // Update focus request. The focus resolver will always try to handle this request if there is
  32.     // no focused window on the display.
  33.     mFocusRequestByDisplay[displayId] = request;
  34.     mLastFocusResultByDisplay[displayId] = result;
  35.     if (result == Focusability::OK) {
  36.         return updateFocusedWindow(displayId, "setFocusedWindow", request.token,
  37.                                    request.windowName);
  38.     }
  39.     // The requested window is not currently focusable. Wait for the window to become focusable
  40.     // but remove focus from the current window so that input events can go into a pending queue
  41.     // and be sent to the window when it becomes focused.
  42.     return updateFocusedWindow(displayId, "Waiting for window because " + NamedEnum::string(result),
  43.                                nullptr);
  44. }
复制代码
如下将会更新对应屏幕上的核心窗口:
在更新完 屏幕–核心map后,返回更新结果的布局体,struct FocusChanges {         sp<IBinder> oldFocus;         sp<IBinder> newFocus;         int32_t displayId;         std::string reason;
可见该布局体包罗原始核心信息,更新的核心窗口信息,屏幕id,核心改变缘故起因。
  1. frameworks/native/services/inputflinger/dispatcher/FocusResolver.cpp
  2. std::optional<FocusResolver::FocusChanges> FocusResolver::updateFocusedWindow(
  3.         int32_t displayId, const std::string& reason, const sp<IBinder>& newFocus,
  4.         const std::string& tokenName) {
  5.     //获取对应屏幕上的旧的焦点信息
  6.     sp<IBinder> oldFocus = getFocusedWindowToken(displayId);
  7.     // 没有发生变化 返回
  8.     if (newFocus == oldFocus) {
  9.         return std::nullopt;
  10.     }
  11.     if (newFocus) {
  12.         // 如果设置的新焦点不为空,则更新 屏幕--焦点map
  13.         mFocusedWindowTokenByDisplay[displayId] = {tokenName, newFocus};
  14.     } else {
  15.         // 如果设置的新焦点为空,则删除屏幕--焦点map中该屏幕的焦点信息
  16.         mFocusedWindowTokenByDisplay.erase(displayId);
  17.     }
  18.     /* 返回struct FocusChanges {
  19.         sp<IBinder> oldFocus;
  20.         sp<IBinder> newFocus;
  21.         int32_t displayId;
  22.         std::string reason;
  23.     };结构体*/
  24.     return {{oldFocus, newFocus, displayId, reason}};
  25. }
复制代码
2.2 把更新结果关照到窗口端

如被骗InputFlinger的核心窗口完成改变时将会调用到该函数:

  • 天生核心脱离旧的核心窗口的天生,随后该事故会发给旧的核心窗口。
  • 天生核心进入新的窗口的事故,这个事故稍后会发送给新的核心窗口。
  1. frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
  2. void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
  3.     if (changes.oldFocus) {
  4.         // 如果旧的焦点窗口的InputChannel还可用
  5.         std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
  6.         if (focusedInputChannel) {
  7.             CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
  8.                                        "focus left window");
  9.             synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
  10.             // 入队一个 焦点从旧的窗口撤出的事件,这个事件稍后会发送给旧的焦点窗口
  11.             enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
  12.         }
  13.     }
  14.     if (changes.newFocus) {
  15.         // 新的焦点窗口不为空,入队一个 焦点进入新的窗口的事件,这个事件稍后会发送给新的焦点窗口
  16.         enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
  17.     }
复制代码
发送InputDiapatchar端核心改变的事故给应用端,紧接着会打印对应的event log:
核心撤出: input_focus: [Focus leaving 7d52ce4 NotificationShade (server),reason=setFocusedWindow]
核心进入: input_foc: [Focus entering 106fc21 com.android.settings/com.android.settings.Settings$ConnectedDeviceDashboardActivity (server),reason=setFocusedWind
  1. frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
  2. void InputDispatcher::(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
  3.     std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
  4.     if (channel == nullptr) {
  5.         return; // Window has gone away
  6.     }
  7.     InputTarget target;
  8.     target.inputChannel = channel;
  9.     target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
  10.     entry->dispatchInProgress = true;
  11.     std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
  12.             channel->getName();
  13.     std::string reason = std::string("reason=").append(entry->reason);
  14.     // 打印event log
  15.     android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
  16.     // 分发焦点事件
  17.     dispatchEventLocked(currentTime, entry, {target});
  18. }
复制代码
至此 ,分析完毕
增补更新核心app的流程
  1. 解锁时:
  2. newFocus:ActivityRecord{807c8eb u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t7}
  3. java.lang.Exception
  4.         at com.android.server.wm.DisplayContent.setFocusedApp(DisplayContent.java:3848)
  5.         at com.android.server.wm.ActivityTaskManagerService.setLastResumedActivityUncheckLocked(ActivityTaskManagerService.java:
  6.         at com.android.server.wm.ActivityTaskSupervisor.updateTopResumedActivityIfNeeded(ActivityTaskSupervisor.java:2130)
  7.         at com.android.server.wm.TaskFragment.setResumedActivity(TaskFragment.java:520)
  8.         at com.android.server.wm.TaskFragment.onActivityStateChanged(TaskFragment.java:816)
  9.         at com.android.server.wm.ActivityRecord.setState(ActivityRecord.java:5639)
  10.         at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1421)
  11.         at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5017)
  12.         at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4947)
  13.         at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4966)
  14.         at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4998)
  15.         at com.android.server.wm.RootWindowContainer.lambda$applySleepTokens$20(RootWindowContainer.java:2369)
  16.         at com.android.server.wm.RootWindowContainer.$r8$lambda$95qC-1ZUnz4HFKq9TM8jsgele88(Unknown Source:0)
  17.         at com.android.server.wm.RootWindowContainer$$ExternalSyntheticLambda18.accept(Unknown Source:8)
  18.         at com.android.server.wm.Task.forAllRootTasks(Task.java:3182)
  19.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2066)
  20.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2066)
  21.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2066)
  22.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2066)
  23.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2066)
  24.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2066)
  25.         at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2059)
  26.         at com.android.server.wm.RootWindowContainer.applySleepTokens(RootWindowContainer.java:2354)
  27.         at com.android.server.wm.ActivityTaskManagerService.updateSleepIfNeededLocked(ActivityTaskManagerService.java:4787)
  28.         at com.android.server.wm.RootWindowContainer.removeSleepToken(RootWindowContainer.java:2624)
  29.         at com.android.server.wm.ActivityTaskManagerService$SleepTokenAcquirerImpl.release(ActivityTaskManagerService.java:4762)
  30.         at com.android.server.wm.KeyguardController.updateKeyguardSleepToken(KeyguardController.java:518)
  31.         at com.android.server.wm.KeyguardController.updateKeyguardSleepToken(KeyguardController.java:509)
  32.         at com.android.server.wm.KeyguardController.keyguardGoingAway(KeyguardController.java:270)
  33.         at com.android.server.wm.ActivityTaskManagerService.lambda$keyguardGoingAway$4(ActivityTaskManagerService.java:3479)
  34.         at com.android.server.wm.ActivityTaskManagerService.$r8$lambda$3ir4F8YeWgNCplL0b7P4iAJf_NI(Unknown Source:0)
  35.         at com.android.server.wm.ActivityTaskManagerService$$ExternalSyntheticLambda1.accept(Unknown Source:6)
  36.         at com.android.server.wm.RootWindowContainer.forAllDisplays(RootWindowContainer.java:1258)
  37.         at com.android.server.wm.ActivityTaskManagerService.keyguardGoingAway(ActivityTaskManagerService.java:3478)
  38.         at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1721)
  39.         at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5335)
  40.         at android.os.Binder.execTransactInternal(Binder.java:1280)
  41.         at android.os.Binder.execTransact(Binder.java:1244)
复制代码
冷启动应用时:
  1. newFocus:ActivityRecord{39b5e82 u0 com.android.settings/.Settings} t8}
  2. java.lang.Exception
  3.         at com.android.server.wm.DisplayContent.setFocusedApp(DisplayContent.java:3848)
  4.         at com.android.server.wm.ActivityTaskManagerService.setLastResumedActivityUncheckLocked(ActivityTaskManagerService.java:4716)
  5.         at com.android.server.wm.ActivityTaskSupervisor.updateTopResumedActivityIfNeeded(ActivityTaskSupervisor.java:2130)
  6.         at com.android.server.wm.TaskFragment.setResumedActivity(TaskFragment.java:520)
  7.         at com.android.server.wm.TaskFragment.onActivityStateChanged(TaskFragment.java:816)
  8.         at com.android.server.wm.ActivityRecord.setState(ActivityRecord.java:5639)
  9.         at com.android.server.wm.Task.minimalResumeActivityLocked(Task.java:4760)
  10.         at com.android.server.wm.ActivityTaskSupervisor.realStartActivityLocked(ActivityTaskSupervisor.java:981)
  11.         at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:1048)
  12.         at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1542)
  13.         at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5017)
  14.         at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4947)
  15.         at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2281)
  16.         at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2267)
  17.         at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1800)
  18.         at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:6243)
  19.         at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:190)
  20.         at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:609)
  21.         at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:127)
  22.         at android.os.Binder.execTransactInternal(Binder.java:1280)
  23.         at android.os.Binder.execTransact(Binder.java:1244)
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表