当前位置:网站首页>Window management learn more about windowmanagerservice
Window management learn more about windowmanagerservice
2022-06-11 10:32:00 【Smile and see the exit】
I have already introduced WindowManage( To understand all aspects WindowManager), Today let's get to know WindowManager The manager of WMS, stay Android In the system , Managing all windows in the system is a window management service WindowManagerService Responsibility for .
You can know App From Startup to main window display , Main needs App、ActivityManagerService、WindowManagerService and SurfaceFlinger Wait for these modules to cooperate with each other .
Among these App Mainly responsible for business logic , Draw view ,AMS Responsible for managing component and process information and stack information ,WMS Responsible for managing the Activity Windows, sub windows and system windows ,SF Is used to manage the graphics buffer , Render the screen . This analysis is based on Android 10.0 On .
One 、WMS The birth of
just as AMS equally ,WMS Also in SystemServer Of main() Born in :
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
......
// Opening service .
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
......
}
As can be seen from the above , Created a SystemServer Object will be called run Method . Three types of system services will be enabled in the method , They are guided services , Core services and other services , and WMS It is a kind of other services .
Then let's take a look WMS stay startOtherService How to produce :
private void startOtherServices() {
......
// Code 1
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
traceEnd();
traceBeginAndSlog("SetWindowManagerService");
// Code 2
mActivityManagerService.setWindowManager(wm);
traceEnd();
traceBeginAndSlog("WindowManagerServiceOnInitReady");
// Code 3
wm.onInitReady();
......
// Code 4
try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
}
......
// Code 5
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
}
In the code 1 It's about , call WindowManagerServiice.main() establish wms object , And add the object to ServiceManager in , Code 2 It's about , by AMS Set up wms, Then in the code 3 And code 4 Initialize the display information in , In the code 5 Chu Hong ou, come and beat up your senses wms, The initialization of the system has been completed , Internally it will call mPolicy.systemReady Method .
As you can see from the above, when wms Of main Method time , Will create wms Examples come out :
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm) {
return main(context, im, showBootMsgs, onlyCore, policy, atm,
SurfaceControl.Transaction::new);
}
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
atm, transactionFactory), 0);
return sInstance;
}
stay main In the method , Will use DisplayThread.getHandle Of runWithSciissors Method , explain WMS The creation of is run on android.display In the thread .
DisplayThread A thread is a system foreground thread , It is used to perform some operations on the display with a very small delay
stay Handle Of runWithScissors In the method :
public final boolean runWithScissors(final Runnable r, long timeout) {
......
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
Here we will judge whether it is current looper, there looper It also means whether you are in android.display in . When if not , Will be runnable The incoming to BlockingRunnable, And implement postAndWait Method .
private static final class BlockingRunnable implements Runnable {
private final Runnable mTask;
private boolean mDone;
public BlockingRunnable(Runnable task) {
mTask = task;
}
@Override
public void run() {
try {
mTask.run();
} finally {
synchronized (this) {
mDone = true;
notifyAll();
}
}
}
public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {
return false;
}
synchronized (this) {
if (timeout > 0) {
final long expirationTime = SystemClock.uptimeMillis() + timeout;
while (!mDone) {
long delay = expirationTime - SystemClock.uptimeMillis();
if (delay <= 0) {
return false; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
}
}
stay postAndWait In the method , stay mDone Not set to trrue when , It keeps the thread waiting , until run Method is executed . Love will be set up at this time mDone by true, And at the same time notifyAll Wake up the thread . It can also be seen from here wms The priority of creating will be higher .
Then it will be executed to wms Construction method of , The construction method is very long, so we intercept some key points :
private WindowManagerService(Context context, InputManagerService inputManager,
boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
......
// Code 1
mPolicy = policy;
// Code 2
mAnimator = new WindowAnimator(this);
mRoot = new RootWindowContainer(this);
mWindowPlacerLocked = new WindowSurfacePlacer(this);
mTaskSnapshotController = new TaskSnapshotController(this);
mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
Choreographer.getInstance());
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
......
// Code 3
mActivityManager = ActivityManager.getService();
mActivityTaskManager = ActivityTaskManager.getService();
}
In the code 1 It's about ,mPolicy The object is wms It plays a very important role in , It's an interface ,WMS The operations in are wmp What to do with . And its real implementation class is PhoneWindowManager,PhoneWindowManager The processing thread is in ui In the thread .
Two 、WMS Key members
| name | meaning |
|---|---|
| mPolicy: WiindoowMangerPolicy | Is the interface class of window management policy , It is used to define the general specification to be followed by a window |
| mSessions: ArraySet | It is mainly used for inter process communication , Other application processes need to work with WMS Process communication needs to go through Session, Each application process corresponds to a Session, To save it is to record all the records to WMS The client of window management service is proposed . |
| mWindowMap:WindowHashMap | key The corresponding value is IBinder,value The corresponding value is WindowState.Window Is a window in window management |
| mAnimator:WindowAnimator | windowAnimatoor Variable of type , Used to manage window animation and special effects animation |
| mH:H | Systematic Handler, Used to add tasks to the message queue of the main thread |
3、 ... and 、WMS The process of adding
From above ViewRootImpl Calling setView Method addToDisplay Method , It will be called internally again WMS Of addWindow Method and put itself, that is Session It's coming in , Let's go straight to WindowManagerService Of addWindow Method :
public int addWindow(Session session, IWindow client, int seq,
LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
InsetsState outInsetsState) {
......
synchronized (mGlobalLock) {
//WindowToken Convert to... Specific to the application window AppWindowToken
AppWindowToken atoken = null;
// Use the existing parent password card for the child window , Because they have the same token as the parent window , So we can apply the same strategy to them
WindowToken token = displayContent.getWindowToken(
hasParent ? parentWindow.mAttrs.token : attrs.token);
// If it doesn't exist token
if (token == null) {
// If it is Appliation Type of window , Don't allow WindowToken by null
if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
Slog.w(TAG_WM, "Attempted to add application window with unknown token "
+ attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
.......
}
// establish WindowState
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);
// establish InputChanel, be used for Input Reception and transmission of information
final boolean openInputChannels = (outInputChannel != null
&& (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
if (openInputChannels) {
win.openInputChannel(outInputChannel);
}
// take WindowState Add to windowMap in
win.attach();
mWindowMap.put(client.asBinder(), win);
win.initAppOpsState();
// take WindowState Object added to WindowToken in ,WindowToken Will serve as a WindowState Parent container of
win.mToken.addWindow(win);
.....
// Create window animation
final WindowStateAnimator winAnimator = win.mWinAnimator;
winAnimator.mEnterAnimationPending = true;
winAnimator.mEnteringAnimation = true;
// If you can get the focus , Update the focus window
boolean focusChanged = false;
if (win.canReceiveKeys()) {
focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
false /*updateInputWindows*/);
if (focusChanged) {
imMayMove = false;
}
}
// Update input Window
if (focusChanged) {
displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus,
false /*updateInputWindows*/);
}
displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);
......
// If the direction is updated , Update the global configuration
if (win.isVisibleOrAdding() && displayContent.updateOrientationFromAppTokens()) {
reportNewConfig = true;
}
......
}
}
stay addWindow A lot of checks have been done in the , The main work is as follows :
- Check all window types , If you are not satisfied, you will not carry out
- Yes
windowTokenTrace processing , If not, a new one will be createdWindowToken - establish
windowStateobject , And with WindowToken Related to , Give Way WindowToken Become WindowStae Object's parent container - Update focus window and update
InputWindow
3.1 WindowToken establish
WindowToken The role in it is as WindowState Parent container of , Responsible for managing a group of Window. Its construction method is as follows :
WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
DisplayContent dc, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) {
super(service);
// assignment IBinder object
token = _token;
// Window type
windowType = type;
// Whether it is explicitly added WindowToken
mPersistOnEmpty = persistOnEmpty;
mOwnerCanManageAppTokens = ownerCanManageAppTokens;
mRoundedCornerOverlay = roundedCornerOverlay;
onDisplayChanged(dc);
}
void onDisplayChanged(DisplayContent dc) {
// Add the object to DisplayContent in
dc.reParentWindowToken(this);
super.onDisplayChanged(dc);
}
After doing some property initialization , take WindowToken Passed on to DisplayContent, Finally put token Saved to DisplayContent#mToken in .
//DisplayContent.java
void reParentWindowToken(WindowToken token) {
final DisplayContent prevDc = token.getDisplayContent();
if (prevDc == this) {
return;
}
......
addWindowToken(token.token, token);
}
private void addWindowToken(IBinder binder, WindowToken token) {
// If it's time to WindowToken Has been associated with DisplayContent object , You can no longer associate other DisplayContent object
final DisplayContent dc = mWmService.mRoot.getWindowTokenDisplay(token);
if (dc != null) {
// We currently don't support adding a window token to the display if the display
// already has the binder mapped to another token. If there is a use case for supporting
// this moving forward we will either need to merge the WindowTokens some how or have
// the binder map to a list of window tokens.
throw new IllegalArgumentException("Can't map token=" + token + " to display="
+ getName() + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
}
if (binder == null) {
throw new IllegalArgumentException("Can't map token=" + token + " to display="
+ getName() + " binder is null");
}
if (token == null) {
throw new IllegalArgumentException("Can't map null token to display="
+ getName() + " binder=" + binder);
}
// take WindowToken Add to DisplayContent Of TokenMap in
mTokenMap.put(binder, token);
// For not Activity Type of window , Will be based on Window Type is added to the corresponding three container China
if (token.asAppWindowToken() == null) {
switch (token.windowType) {
case TYPE_WALLPAPER:
mBelowAppWindowsContainers.addChild(token);
break;
case TYPE_INPUT_METHOD:
case TYPE_INPUT_METHOD_DIALOG:
mImeWindowsContainers.addChild(token);
break;
default:
mAboveAppWindowsContainers.addChild(token);
break;
}
}
}
Come here WindowToken The object is created .
3.2 WindowState establish
WindowToken Manages the windowState, Every WindowState Represents a specific Window, Add one at a time Window The corresponding one will be created windowState, Its construction method is as follows :
//WindowStae
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow,
PowerManagerWrapper powerManagerWrapper) {
super(service);
mSession = s;
mClient = c;
mAppOp = appOp;
mToken = token;
mAppToken = mToken.asAppWindowToken();
......
mWinAnimator = new WindowStateAnimator(this);
mWinAnimator.mAlpha = a.alpha;
mRequestedWidth = 0;
mRequestedHeight = 0;
mLastRequestedWidth = 0;
mLastRequestedHeight = 0;
mLayer = 0;
mInputWindowHandle = new InputWindowHandle(
mAppToken != null ? mAppToken.mInputApplicationHandle : null, c,
getDisplayId());
}
It creates WindowStateAnimator, Actually used for WindowState Object to animate and Surface Transformation related operations , In the process of drawing , Animation status and surface The status of the object will be recorded by the object .
from addWindow Methods we learned that WMS Yes 3 Two important classes are WindowToken、WindowState and DisplayContent
Four 、 Summary
stay WMS in ,WindowState Represents a window ,WIndowToken As WIndowState Parent container of , Managing a set of windows . Through wms Of addWindow After the method , You create a relative to system_server Window management object of .
Reference resources
Android analysis WindowManagerService( One )WMS The birth of
边栏推荐
猜你喜欢

Use of kingbasees UDP monitoring tool for gold warehouse database

微信小程序之点餐系统附源码

金仓数据库KingbaseES中的PL/SQL 编译检查

白屏时间、首屏时间

金仓数据KingbaseES 批量创建数据库对象

MXNet对AlexNet模型的构建与实现(与LeNet的对比)

安全相关网站推荐

Mouse click coordinate transformation generation

Arbitrum infrastructure: a quick start

Circuit board made of real gold -- golden finger
随机推荐
本人书签常存的地址
pyspark案例系列4-dataframe输出到单个文件夹的解决方案
Common techniques for handling dates
Mysql-- index
Explain the physical layer consistency test of 2.5g/5g/10g Base-T Ethernet interface in detail!
Finite cyclic group
NFT 2.0: 下一代的NFT将是精简且值得信赖的NFT
MD5学习
Development and source code construction of digital collection system
【机器学习理论】True Positive, True Negative, False Positive, False Negative概念
Wechat applet ordering system with source code
Use of kingbasees UDP monitoring tool for gold warehouse database
FPGA infrastructure [reference ug998]
Mouse click coordinate transformation generation
金仓数据KingbaseES 批量创建数据库对象
Use bat to write to the first line of the file
[machine learning theory] true positive, true negative, false positive, false negative concept
Ngui, floating blood
Habitable planet
Dotween usage