Reference links: www.jianshu.com/p/b3a1ea792…
1. Window loading the view
1. Understand the overall view relationship
Activity: it is not a window or view itself, but a carrier of a window. On the one hand, it responds to key and touch events, and on the other hand, it conducts unified scheduling of interface life cycle.
Window: An abstract base class for top-level Window viewing and behavior. It is also the original container for loading views, handling some of the logic common to application Windows. It is used with its only implementation class: PhoneWindow. Windows are centrally managed by Windows Manager.
DecorView: a top-level view that typically contains a vertical LinearLayout inside, with the titleBar at the top and the interior bar below. Normally, the layout file we set in our Activity with setContentView is loaded into the FrameLayout column with id Android.R.D.C. Tent.
2. Type of Window
The add window is operated by the Windows ManagerGlobal addView method with three required parameters:
- View: Indicates the view to be displayed. Generally, operations are performed on the context of the view. (the getContext ())
- Display: Indicates the output display device
- Params: type WindowManager. LayoutParams. Represents the layout parameters that the View is to display on the window. (flags, type)
-
Flags: Indicates the Window property:
- FLAG_NOT_FOCUSABLE
- FLAG_NOT_TOUCH_MODEAL
- FLAG_SHOW_WHEN_LOCKED
-
Type: indicates the window type
- The System Window exists independently
- Application Window Indicates the application window
- Sub Windows need to be attached to the parent window and cannot exist independently
Windows are hierarchical, and each Window has a corresponding Z-ordered (z axis, from 1 to 2999) that overrides the smaller ones. In addition, some system-level uses require permissions to be declared.
The token in layoutParms of WindowManager is mainly used to maintain the correspondence between activities and Windows.
3. Create Windows
For window creation, we start with the source code handleLaunchActivity:
frameworks/base/core/java/android/app/ActivityThread.java public Activity handleLaunchActivity(ActivityClientRecord r, 3938 PendingTransactionActions pendingActions, Intent customIntent) { 3939 // If we are getting ready to gc after going to the background, well 3940 // we are back active so skip it. 3941 unscheduleGcIdler(); 3942 mSomeActivitiesChanged = true; 3943 3944 if (r.profilerInfo ! = null) { 3945 mProfiler.setProfiler(r.profilerInfo); 3946 mProfiler.startProfiling(); 3947 } 3948 3949 if (r.mPendingFixedRotationAdjustments ! = null) { 3950 // The rotation adjustments must be applied before handling configuration, so process 3951 // level display metrics can be adjusted. 3952 overrideApplicationDisplayAdjustments(r.token, adjustments -> 3953 adjustments.setFixedRotationAdjustments(r.mPendingFixedRotationAdjustments)); 3954 } 3955 3956 // Make sure we are running with the most recent config. 3957 mConfigurationController.handleConfigurationChanged(null, null); 3958 3959 if (localLOGV) Slog.v( 3960 TAG, "Handling launch of " + r); 3961 3962 // Initialize before creating the activity 3963 if (ThreadedRenderer.sRendererEnabled 3964 && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! = 0) { 3965 HardwareRenderer.preload(); 3966 } 3967 WindowManagerGlobal.initialize(); 3968 3969 // Hint the GraphicsEnvironment that an activity is launching on the process. 3970 GraphicsEnvironment.hintActivityLaunch(); 3971 3972 final Activity a = performLaunchActivity(r, customIntent); 3973 3974 if (a ! = null) { 3975 r.createdConfig = new Configuration(mConfigurationController.getConfiguration()); 3976 reportSizeConfigurations(r); 3977 if (! r.activity.mFinished && pendingActions ! = null) { 3978 pendingActions.setOldState(r.state); 3979 pendingActions.setRestoreInstanceState(true); 3980 pendingActions.setCallOnPostCreate(true); 3981 } 3982 } else { 3983 // If there was an error, for any reason, tell the activity manager to stop us. 3984 ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED, 3985 null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 3986 } 3987 3988 return a; 3989}Copy the code
final Activity a = performLaunchActivity(r, customIntent); Attach method:
final void attach(Context context, ActivityThread aThread, 8507 Instrumentation instr, IBinder token, int ident, 8508 Application application, Intent intent, ActivityInfo info, 8509 CharSequence title, Activity parent, String id, 8510 NonConfigurationInstances lastNonConfigurationInstances, 8511 Configuration config, String referrer, IVoiceInteractor voiceInteractor, 8512 Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken, 8513 IBinder shareableActivityToken) {attachBaseContext(context); 8515 8516 mFragments.attachHost(null /*parent*/); MWindow = new PhoneWindow(this, Window, activityConfigCallback); 8519 mWindow.setWindowControllerCallback(mWindowControllerCallback); 8520 mWindow.setCallback(this); 8521 mWindow.setOnWindowDismissedCallback(this); 8522 mWindow.getLayoutInflater().setPrivateFactory(this); 8523 if (info.softInputMode ! = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { 8524 mWindow.setSoftInputMode(info.softInputMode); 8525 } 8526 if (info.uiOptions ! = 0) { 8527 mWindow.setUiOptions(info.uiOptions); 8528 } 8529 mUiThread = Thread.currentThread(); 8530 8531 mMainThread = aThread; 8532 mInstrumentation = instr; 8533 mToken = token; 8534 mAssistToken = assistToken; 8535 mShareableActivityToken = shareableActivityToken; 8536 mIdent = ident; 8537 mApplication = application; 8538 mIntent = intent; 8539 mReferrer = referrer; 8540 mComponent = intent.getComponent(); 8541 mActivityInfo = info; 8542 mTitle = title; 8543 mParent = parent; 8544 mEmbeddedID = id; 8545 mLastNonConfigurationInstances = lastNonConfigurationInstances; 8546 if (voiceInteractor ! = null) { 8547 if (lastNonConfigurationInstances ! = null) { 8548 mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor; 8549 } else { 8550 mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this, 8551 Looper.myLooper()); 8552} 8553} 8554 // setWindowManager 8555 mwindow.setwindowmanager (8556 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), 8557 mToken, mComponent.flattenToString(), 8558 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! = 0); 8559 if (mParent ! = null) { 8560 mWindow.setContainer(mParent.getWindow()); 8562 mWindowManager = mwindow.getwinDowManager (); WindowManagerImpl 8563 mCurrentConfig = config; 8564 8565 mWindow.setColorMode(info.colorMode); 8566 mWindow.setPreferMinimalPostProcessing( 8567 (info.flags & ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING) ! = 0); 8568 8569 setAutofillOptions(application.getAutofillOptions()); 8570 setContentCaptureOptions(application.getContentCaptureOptions()); 8571 8572 try { 8573 mClipboardManager = new ClipboardManager(context, null); 8574 } catch (Exception e) { 8575 Slog.w(TAG, "ClipboardManager get failed", e); 8576} 8577 8578}Copy the code
This creates a PhoneWindow object and implements the Window’s Callback interface, so that the Activity is associated with the Window and can receive key and touch events through the Callback.
In addition, to initialize and set up a WindowManager, each Activity has a WindowManager object that communicates with the WindowManagerService. It is also key for WindowManagerService to recognize which Activity a View belongs to, passing in an IBinder mToken when it is created.
Starting with the Window setWindowManager method, it is easy to find that the implementation of the WindowManager interface is Windows ManagerImpl.
4. Window Add View process
Although PhoneWindow is more of a container for views, the actual process of adding a View as a window to the WMS is done by WindowManager. And from the creation process above we know that the concrete implementation of WindowManager is WindowManagerImpl.
So let’s continue with the code:
HandleResumeActivity: performLaunchActivity (); handleResumeActivity ();
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest, 5155 boolean isForward, String reason) { 5156 // If we are getting ready to gc after going to the background, well 5157 // we are back active so skip it. 5158 unscheduleGcIdler(); 5159 mSomeActivitiesChanged = true; 5160 5161 // TODO Push resumeArgs into the activity for consideration 5162 // skip below steps for double-resume and r.mFinish = true case. 5163 if (! performResumeActivity(r, finalStateRequest, reason)) { 5164 return; 5165 } 5166 if (mActivitiesToBeDestroyed.containsKey(r.token)) { 5167 // Although the activity is resumed, it is going to be destroyed. So the following 5168 // UI operations are unnecessary and also prevents exception because its token may 5169 // be gone that window manager cannot recognize it. All necessary cleanup actions 5170 // performed below will be done while handling destruction. 5171 return; 5172 } 5173 5174 final Activity a = r.activity; 5175 /** ZTE add for app datacollection begin*/ 5176 if (r.packageInfo ! = null) { 5177 packageName = r.packageInfo.mPackageName; 5178 } 5179 /** ZTE add for app datacollection end*/ 5180 5181 if (localLOGV) { 5182 Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity 5183 + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); 5184 } 5185 5186 final int forwardBit = isForward 5187 ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 5188 5189 // If the window hasn't yet been added to the window manager, 5190 // and this guy didn't finish itself or start another activity, 5191 // then go ahead and add the window. 5192 boolean willBeVisible = ! a.mStartedActivity; 5193 if (! willBeVisible) { 5194 willBeVisible = ActivityClient.getInstance().willActivityBeVisible( 5195 a.getActivityToken()); 5196 } 5197 if (r.window == null && ! a.mFinished && willBeVisible) { 5198 r.window = r.activity.getWindow(); 5199 View decor = r.window.getDecorView(); 5200 decor.setVisibility(View.INVISIBLE); 5201 ViewManager wm = a.getWindowManager(); 5202 WindowManager.LayoutParams l = r.window.getAttributes(); 5203 a.mDecor = decor; 5204 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 5205 l.softInputMode |= forwardBit; 5206 if (r.mPreserveWindow) { 5207 a.mWindowAdded = true; 5208 r.mPreserveWindow = false; 5209 // Normally the ViewRoot sets up callbacks with the Activity 5210 // in addView->ViewRootImpl#setView. If we are instead reusing 5211 // the decor view we have to notify the view root that the 5212 // callbacks may have changed. 5213 ViewRootImpl impl = decor.getViewRootImpl(); 5214 if (impl ! = null) { 5215 impl.notifyChildRebuilt(); 5216 } 5217 } 5218 if (a.mVisibleFromClient) { 5219 if (! a.mWindowAdded) { 5220 a.mWindowAdded = true; 5221 wm.addView(decor, l); 5222} else {5223 // The activity will get a callback for this {@link LayoutParams} change 5224 // earlier. However, at that time the decor will not be set (this is set 5225 // in this method), so no action will be taken. This call ensures the 5226 // callback occurs with the decor set. 5227 a.onWindowAttributesChanged(l); 5228 } 5229 } 5230 5231 // If the window has already been added, but during resume 5232 // we started another activity, then don't yet make the 5233 // window visible. 5234 } else if (! willBeVisible) { 5235 if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set"); 5236 r.hideForNow = true; 5237 } 5238 5239 // Get rid of anything left hanging around. 5240 cleanUpPendingRemoveWindows(r, false /* force */); 5241 5242 // The window is now visible if it has been added, we are not 5243 // simply finishing, and we are not starting another activity. 5244 if (! r.activity.mFinished && willBeVisible && r.activity.mDecor ! = null && ! r.hideForNow) { 5245 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); 5246 ViewRootImpl impl = r.window.getDecorView().getViewRootImpl(); 5247 WindowManager.LayoutParams l = impl ! = null 5248 ? impl.mWindowAttributes : r.window.getAttributes(); 5249 if ((l.softInputMode 5250 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 5251 ! = forwardBit) { 5252 l.softInputMode = (l.softInputMode 5253 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 5254 | forwardBit; 5255 if (r.activity.mVisibleFromClient) { 5256 ViewManager wm = a.getWindowManager(); 5257 View decor = r.window.getDecorView(); 5258 wm.updateViewLayout(decor, l); / / update window state 5259} 5260} 5261 5262 state Richard armitage ctivity. MVisibleFromServer = true; 5263 mNumVisibleActivities++; 5264 the if (state Richard armitage ctivity. MVisibleFromClient) {/ / have been successfully added to the window (drawing and receiving), set to visible 5265 state Richard armitage ctivity. MakeVisible (); 5266 } 5267 } 5268 5269 r.nextIdle = mNewActivities; 5270 mNewActivities = r; 5271 if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r); 5272 Looper.myQueue().addIdleHandler(new Idler()); 5273}Copy the code
The activity getWindowManager() obtains wm from the WindowManagerImpl addView method.
if (! a.mWindowAdded) { 5220 a.mWindowAdded = true; 5221 wm.addView(decor, l); // Add decor to WindowsCopy the code
// WindowManagerImpl.java @Override 131 public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { 132 android.util.SeempLog.record_vg_layout(383,params); 133 applyTokens(params); 134 mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow, 135 mContext.getUserId()); 136}Copy the code
We see another layer of proxy: mGlobal
The previous window type had Windows ManagerGlobal
So the Windows Manager ImpL doesn’t actually do any work. Operations on the Window(or View) are handled by The Windows ManagerGlobal, which provides its own instances in the form of factories. This working mode is bridge mode, delegating all operations to Windows ManagerGlobal.
The Windows ManagerGlobal is initialized in the Global variable of the Windows Manager IMPL in singleton mode, which means that there is only one Windows ManagerGlobal object for a process.
public void addView(View view, ViewGroup.LayoutParams params, 325 Display display, Window parentWindow, int userId) { 326 if (view == null) { 327 throw new IllegalArgumentException("view must not be null"); 328 } 329 if (display == null) { 330 throw new IllegalArgumentException("display must not be null"); 331 } 332 if (! (params instanceof WindowManager.LayoutParams)) { 333 throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); 334 } 335 336 final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params; 337 if (parentWindow ! = null) {/ / adjust layout parameters, and set the token 338 parentWindow adjustLayoutParamsForSubWindow (wparams); 339 } else { 340 // If there's no parent, then hardware acceleration for this view is 341 // set from the application's hardware acceleration setting. 342 final Context context = view.getContext(); 343 if (context ! = null 344 && (context.getApplicationInfo().flags 345 & ApplicationInfo.FLAG_HARDWARE_ACCELERATED) ! = 0) { 346 wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 347 } 348 } 349 350 ViewRootImpl root; 351 View panelParentView = null; 352 353 synchronized (mLock) { 354 // Start watching for system property changes. 355 if (mSystemPropertyUpdater == null) { 356 mSystemPropertyUpdater = new Runnable() { 357 @Override public void run() { 358 synchronized (mLock) { 359 for (int i = mRoots.size() - 1; i >= 0; --i) { 360 mRoots.get(i).loadSystemProperties(); 361} 362} 363} 364}; 365 SystemProperties.addChangeCallback(mSystemPropertyUpdater); 366 } 367 368 int index = findViewLocked(view, false); 369 if (index >= 0) {369 if (mdyingviews. contains(view)) {// If (mdyingviews. contains(view)) {// If (mDyingViews to make it's way through root's queue. 372 mRoots.get(index).doDie(); 373 } else { 374 throw new IllegalStateException("View " + view 375 + " has already been added to the window manager."); 596} 596 // The previous removeView() had not completed.now it has. // If this is a panel window, Then find the window it is being 381 // Attached to for future reference. // If this is a child window (popupWidow), find its parent window // The most essential function is to use the parent window token(viewwrotimpl W class, Namely Iwindow) 382 if (wparams. Type > = WindowManager. LayoutParams. FIRST_SUB_WINDOW && 383 wparams. Type the < = WindowManager.LayoutParams.LAST_SUB_WINDOW) { 384 final int count = mViews.size(); 385 for (int i = 0; i < count; I ++) {386 if (roots.get (I).mwindow.token () == wparams.token) { // In ViewRootImpl, token is used to represent mWindow(class W, 387 panelParentView = mviews.get (I); 392 root = new ViewRootImpl(view.getContext(), display); 392 root = new ViewRootImpl(view.getContext(), display); 393 394 view.setLayoutParams(wparams); 395 396 mViews.add(view); // Add the current view to the mViews collection. MViews store the view corresponding to all Windows. // Add the current ViewRootImpl to mRoots. MRoots stores all ViewRootImpl 398 mparams.add (wparams); // add params to mParams and store layout parameters for all Windows. Add log for tracking mViews. 401 Log.d("WindowClient", "Add to mViews: " + view + ", this = " + this 402 + "mViews.size()=" + mViews.size()); 403 404 if (checkAppShouldExit(view)) { 405 System.exit(0); 406} 407 408 // Do this last because it fires off messages to start doing things 409 try { Finish drawing the View and add it to the window. 410 root.setView(view, wparams, panelParentView, userId); 411 } catch (RuntimeException e) { 412 // BadTokenException or InvalidDisplayException, clean up. 413 Log.d("WindowClient", "get RuntimeException"); 414 index = findViewLocked(view, false); 415 if (index >= 0) { 416 removeViewLocked(index, true); 417 } 418 throw e; 419} 420} 421}Copy the code
Root. setView(View, wparams, panelParentView); The drawing process is triggered and the view is added to the window.
WindowManager and WindowManagerService Binder IPC interfaces
- IWindowSession: application requests to WMS function implementation class: Session
- IWindow: WMS reports back to the client what it wants to confirm implementation class: W
Here’s a look at the setView for ViewRootImpl:
// ViewRootImpl
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
1031 int userId) {
1032 synchronized (this) {
1033 if (mView == null) {
1034 mView = view;
1035
1036 mAttachInfo.mDisplayState = mDisplay.getState();
1037 mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
1038
1039 mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
1040 mFallbackEventHandler.setView(view);
1041 mWindowAttributes.copyFrom(attrs);
1042 if (mWindowAttributes.packageName == null) {
1043 mWindowAttributes.packageName = mBasePackageName;
1044 }
1045 mWindowAttributes.privateFlags |=
1046 WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
1047
1048 attrs = mWindowAttributes;
1049 setTag();
1050
1051 if (DEBUG_KEEP_SCREEN_ON && (mClientWindowLayoutFlags
1052 & WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0
1053 && (attrs.flags&WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) == 0) {
1054 Slog.d(mTag, "setView: FLAG_KEEP_SCREEN_ON changed from true to false!");
1055 }
1056 // Keep track of the actual window flags supplied by the client.
1057 mClientWindowLayoutFlags = attrs.flags;
1058
1059 setAccessibilityFocus(null, null);
1060
1061 if (view instanceof RootViewSurfaceTaker) {
1062 mSurfaceHolderCallback =
1063 ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
1064 if (mSurfaceHolderCallback != null) {
1065 mSurfaceHolder = new TakenSurfaceHolder();
1066 mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
1067 mSurfaceHolder.addCallback(mSurfaceHolderCallback);
1068 }
1069 }
1070
1071 // Compute surface insets required to draw at specified Z value.
1072 // TODO: Use real shadow insets for a constant max Z.
1073 if (!attrs.hasManualSurfaceInsets) {
1074 attrs.setSurfaceInsets(view, false /*manual*/, true /*preservePrevious*/);
1075 }
1076
1077 CompatibilityInfo compatibilityInfo =
1078 mDisplay.getDisplayAdjustments().getCompatibilityInfo();
1079 mTranslator = compatibilityInfo.getTranslator();
1080
1081 // If the application owns the surface, don't enable hardware acceleration
1082 if (mSurfaceHolder == null) {
1083 // While this is supposed to enable only, it can effectively disable
1084 // the acceleration too.
1085 enableHardwareAcceleration(attrs);
1086 final boolean useMTRenderer = MT_RENDERER_AVAILABLE
1087 && mAttachInfo.mThreadedRenderer != null;
1088 if (mUseMTRenderer != useMTRenderer) {
1089 // Shouldn't be resizing, as it's done only in window setup,
1090 // but end just in case.
1091 endDragResizing();
1092 mUseMTRenderer = useMTRenderer;
1093 }
1094 }
1095
1096 boolean restore = false;
1097 if (mTranslator != null) {
1098 mSurface.setCompatibilityTranslator(mTranslator);
1099 restore = true;
1100 attrs.backup();
1101 mTranslator.translateWindowLayout(attrs);
1102 }
1103 if (DEBUG_LAYOUT) Log.d(mTag, "WindowLayout in setView:" + attrs);
1104
1105 if (!compatibilityInfo.supportsScreen()) {
1106 attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
1107 mLastInCompatMode = true;
1108 }
1109
1110 mSoftInputMode = attrs.softInputMode;
1111 mWindowAttributesChanged = true;
1112 mAttachInfo.mRootView = view;
1113 mAttachInfo.mScalingRequired = mTranslator != null;
1114 mAttachInfo.mApplicationScale =
1115 mTranslator == null ? 1.0f : mTranslator.applicationScale;
1116 if (panelParentView != null) {
1117 mAttachInfo.mPanelParentWindowToken
1118 = panelParentView.getApplicationWindowToken();
1119 }
1120 mAdded = true;
1121 int res; /* = WindowManagerImpl.ADD_OKAY; */
1122
1123 if (ActivityThread.ZTE_TRAVERSAL_ACCELERATE_ENABLED) {
1124 // nubia add for app launch traversals accelerate
1125 startAppTraversalsAccelerate(mView);
1126 // nubia add end
1127 }
1128
1129 // Schedule the first layout -before- adding to the window
1130 // manager, to make sure we do the relayout before receiving
1131 // any other events from the system.
// 在Window add 之前调用,确保UI布局完成-->measure, layout , draw
1132 requestLayout(); // View的绘制流程
1133 InputChannel inputChannel = null;
1134 if ((mWindowAttributes.inputFeatures
1135 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
1136 inputChannel = new InputChannel();
1137 }
1138 mForceDecorViewVisibility = (mWindowAttributes.privateFlags
1139 & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
1140
1141 if (mView instanceof RootViewSurfaceTaker) {
1142 PendingInsetsController pendingInsetsController =
1143 ((RootViewSurfaceTaker) mView).providePendingInsetsController();
1144 if (pendingInsetsController != null) {
1145 pendingInsetsController.replayAndAttach(mInsetsController);
1146 }
1147 }
1148
1149 try {
1150 mOrigWindowType = mWindowAttributes.type;
1151 mAttachInfo.mRecomputeGlobalAttributes = true;
1152 collectViewAttributes();
1153 adjustLayoutParamsForCompatibility(mWindowAttributes);
1154 controlInsetsForCompatibility(mWindowAttributes);
1155 res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
1156 getHostVisibility(), mDisplay.getDisplayId(), userId,
1157 mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
1158 mTempControls);
1159 if (mTranslator != null) {
1160 mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
1161 mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
1162 }
1163 } catch (RemoteException e) {
1164 mAdded = false;
1165 mView = null;
1166 mAttachInfo.mRootView = null;
1167 mFallbackEventHandler.setView(null);
1168 unscheduleTraversals();
1169 setAccessibilityFocus(null, null);
1170 throw new RuntimeException("Adding window failed", e);
1171 } finally {
1172 if (restore) {
1173 attrs.restore();
1174 }
1175 }
1176
1177 mAttachInfo.mAlwaysConsumeSystemBars =
1178 (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0;
1179 mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars;
1180 mInsetsController.onStateChanged(mTempInsets);
1181 mInsetsController.onControlsChanged(mTempControls);
1182 computeWindowBounds(mWindowAttributes, mInsetsController.getState(),
1183 getConfiguration().windowConfiguration.getBounds(), mTmpFrames.frame);
1184 setFrame(mTmpFrames.frame);
1185 if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow);
1186 if (res < WindowManagerGlobal.ADD_OKAY) {
1187 mAttachInfo.mRootView = null;
1188 mAdded = false;
1189 mFallbackEventHandler.setView(null);
1190 unscheduleTraversals();
1191 setAccessibilityFocus(null, null);
1192 switch (res) {
1193 case WindowManagerGlobal.ADD_BAD_APP_TOKEN:
1194 case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:
1195 throw new WindowManager.BadTokenException(
1196 "Unable to add window -- token " + attrs.token
1197 + " is not valid; is your activity running?");
1198 case WindowManagerGlobal.ADD_NOT_APP_TOKEN:
1199 throw new WindowManager.BadTokenException(
1200 "Unable to add window -- token " + attrs.token
1201 + " is not for an application");
1202 case WindowManagerGlobal.ADD_APP_EXITING:
1203 throw new WindowManager.BadTokenException(
1204 "Unable to add window -- app for token " + attrs.token
1205 + " is exiting");
1206 case WindowManagerGlobal.ADD_DUPLICATE_ADD:
1207 throw new WindowManager.BadTokenException(
1208 "Unable to add window -- window " + mWindow
1209 + " has already been added");
1210 case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:
1211 // Silently ignore -- we would have just removed it
1212 // right away, anyway.
1213 return;
1214 case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:
1215 throw new WindowManager.BadTokenException("Unable to add window "
1216 + mWindow + " -- another window of type "
1217 + mWindowAttributes.type + " already exists");
1218 case WindowManagerGlobal.ADD_PERMISSION_DENIED:
1219 throw new WindowManager.BadTokenException("Unable to add window "
1220 + mWindow + " -- permission denied for window type "
1221 + mWindowAttributes.type);
1222 case WindowManagerGlobal.ADD_INVALID_DISPLAY:
1223 throw new WindowManager.InvalidDisplayException("Unable to add window "
1224 + mWindow + " -- the specified display can not be found");
1225 case WindowManagerGlobal.ADD_INVALID_TYPE:
1226 throw new WindowManager.InvalidDisplayException("Unable to add window "
1227 + mWindow + " -- the specified window type "
1228 + mWindowAttributes.type + " is not valid");
1229 case WindowManagerGlobal.ADD_INVALID_USER:
1230 throw new WindowManager.BadTokenException("Unable to add Window "
1231 + mWindow + " -- requested userId is not valid");
1232 }
1233 throw new RuntimeException(
1234 "Unable to add window -- unknown error code " + res);
1235 }
1236
1237 if ((res & WindowManagerGlobal.ADD_FLAG_USE_BLAST) != 0) {
1238 mUseBLASTAdapter = true;
1239 }
1240
1241 if (view instanceof RootViewSurfaceTaker) {
1242 mInputQueueCallback =
1243 ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
1244 }
1245 if (inputChannel != null) {
1246 if (mInputQueueCallback != null) {
1247 mInputQueue = new InputQueue();
1248 mInputQueueCallback.onInputQueueCreated(mInputQueue);
1249 }
1250 mInputEventReceiver = new WindowInputEventReceiver(inputChannel,
1251 Looper.myLooper());
1252
1253 if (ENABLE_INPUT_LATENCY_TRACKING && mAttachInfo.mThreadedRenderer != null) {
1254 InputMetricsListener listener = new InputMetricsListener();
1255 mHardwareRendererObserver = new HardwareRendererObserver(
1256 listener, listener.data, mHandler, true /*waitForPresentTime*/);
1257 mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver);
1258 }
1259 }
1260
1261 view.assignParent(this);
1262 mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;
1263 mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;
1264
1265 if (mAccessibilityManager.isEnabled()) {
1266 mAccessibilityInteractionConnectionManager.ensureConnection();
1267 }
1268
1269 if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
1270 view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
1271 }
1272
1273 // Set up the input pipeline.
1274 CharSequence counterSuffix = attrs.getTitle();
1275 mSyntheticInputStage = new SyntheticInputStage();
1276 InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage);
1277 InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,
1278 "aq:native-post-ime:" + counterSuffix);
1279 InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);
1280 InputStage imeStage = new ImeInputStage(earlyPostImeStage,
1281 "aq:ime:" + counterSuffix);
1282 InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage);
1283 InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage,
1284 "aq:native-pre-ime:" + counterSuffix);
1285
1286 mFirstInputStage = nativePreImeStage;
1287 mFirstPostImeInputStage = earlyPostImeStage;
1288 mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;
1289 }
1290 }
1291 }
1292
Copy the code
In the view owl PL setView() method
- Execute requestLayout() to complete the view drawing process.
- The View and InputChannel are added to the WMS via WindowSession to add the View to the Window and receive the touch event, which is an IPC process.
Let’s look at the IPC process
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
1156 getHostVisibility(), mDisplay.getDisplayId(), userId,
1157 mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
1158 mTempControls);
Copy the code
MWindowSession: The type is interface IWindowSession
public static IWindowSession getWindowSession() { 206 synchronized (WindowManagerGlobal.class) { 207 if (sWindowSession == null) { 208 try { 209 // Emulate the legacy behavior. The global instance of InputMethodManager 210 // was instantiated here. 211 // TODO(b/116157766): Remove this hack after cleaning up @UnsupportedAppUsage 212 InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary(); 213 IWindowManager windowManager = getWindowManagerService(); 214 sWindowSession = windowManager.openSession( 215 new IWindowSessionCallback.Stub() { 216 @Override 217 public void onAnimatorScaleChanged(float scale) { 218 ValueAnimator.setDurationScale(scale); 219}} 220); 221 } catch (RemoteException e) { 222 throw e.rethrowFromSystemServer(); 223 } 224 } 225 return sWindowSession; 227 226}}Copy the code
We see getWindowManagerService(); To obtain the WMS, then look at the windowManager. OpenSession the return value is the sWindowSession