1 APP端建立一个surface空的容器
2 APP通过binder将surface给到WMS,请求填充
3 wms为了填充surface 向SF申请真正的图层
4 sf收到请求后向wms请求分配真正的图层。
5将图层信息handler传递给WMS,回传给app层。
6 APP控制surface利用surfacecontrol与sf通讯。
@Override
public void setAppVisibility(IBinder token, boolean visible) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppVisibility()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
AppWindowToken wtoken;
synchronized(mWindowMap) {
wtoken = findAppWindowToken(token);//通过ActivityRecord:Token找到AppWindowToken,即找到这个token对应的Activity窗口
if (wtoken == null) {
Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
return;
}
if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG_WM, "setAppVisibility(" +
token + ", visible=" + visible + "): " + mAppTransition +
" hidden=" + wtoken.hidden + " hiddenRequested=" +
wtoken.hiddenRequested + " Callers=" + Debug.getCallers(6));
//mOpeningApps是WMS的成员,里面存放所有打开的窗口的AppWindowToken,首先移除,后面根据visible添加
//mClosingApps是WMS的成员,里面存放所有关闭的窗口的AppWindowToken,首先移除,后面根据visible添加
mOpeningApps.remove(wtoken);
mClosingApps.remove(wtoken);
wtoken.waitingToShow = false;
wtoken.hiddenRequested = !visible;
if (!visible) {
// If the app is dead while it was visible, we kept its dead window on screen.
// Now that the app is going invisible, we can remove it. It will be restarted
// if made visible again.died的window的相关数据也要清除
wtoken.removeAllDeadWindows();
wtoken.setVisibleBeforeClientHidden();
} else if (visible) {
if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) {
// Add the app mOpeningApps if transition is unset but ready. This means
// we're doing a screen freeze, and the unfreeze will wait for all opening
// apps to be ready.
mOpeningApps.add(wtoken);
}
wtoken.startingMoved = false;
// If the token is currently hidden (should be the common case), or has been
// stopped, then we need to set up to wait for its windows to be ready.
if (wtoken.hidden || wtoken.mAppStopped) {
wtoken.clearAllDrawn();
//如果hidden的值等于false,说明Activity组件当前是不可见的。又由于上面visible为true,表示Activity将要被设置成可见的,
//因此,这时候就需要将AppWindowToken对象wtoken的成员变量waitingToShow的值设置为true。
// If the app was already visible, don't reset the waitingToShow state.
if (wtoken.hidden) {
wtoken.waitingToShow = true;
}
if (wtoken.clientHidden) {
// In the case where we are making an app visible
// but holding off for a transition, we still need
// to tell the client to make its windows visible so
// they get drawn. Otherwise, we will wait on
// performing the transition until all windows have
// been drawn, they never will be, and we are sad.
wtoken.clientHidden = false;
//通知应用程序进程将参数token所描述的Activity组件设置为true
//sendAppVisibilityToClient/dispatchAppVibility 这两个函数就是通知上层应用窗口可见性发生变化
wtoken.sendAppVisibilityToClients();
}
}
wtoken.requestUpdateWallpaperIfNeeded();
if (DEBUG_ADD_REMOVE) Slog.v(
TAG_WM, "No longer Stopped: " + wtoken);
wtoken.mAppStopped = false;
}
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
//这个if分之在动画设置完成并且屏幕不冻屏,亮屏、Display OK的情况下才会走
if (okToDisplay() && mAppTransition.isTransitionSet()) {
// A dummy animation is a placeholder animation which informs others that an
// animation is going on (in this case an application transition). If the animation
// was transferred from another application/animator, no dummy animator should be
// created since an animation is already in progress.
if (wtoken.mAppAnimator.usingTransferredAnimation
&& wtoken.mAppAnimator.animation == null) {
Slog.wtf(TAG_WM, "Will NOT set dummy animation on: " + wtoken
+ ", using null transfered animation!");
}
if (!wtoken.mAppAnimator.usingTransferredAnimation &&
(!wtoken.startingDisplayed || mSkipAppTransitionAnimation)) {
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG_WM, "Setting dummy animation on: " + wtoken);
设置哑动画,可以理解是一个站位的作用,后面会对它设置真正的动画
wtoken.mAppAnimator.setDummyAnimation();
}
wtoken.inPendingTransaction = true;
if (visible) {
mOpeningApps.add(wtoken);
wtoken.mEnteringAnimation = true;
} else {
mClosingApps.add(wtoken);
wtoken.mEnteringAnimation = false;
}
if (mAppTransition.getAppTransition() == AppTransition.TRANSIT_TASK_OPEN_BEHIND) {
// We're launchingBehind, add the launching activity to mOpeningApps.
final WindowState win =
findFocusedWindowLocked(getDefaultDisplayContentLocked());
if (win != null) {
final AppWindowToken focusedToken = win.mAppToken;
if (focusedToken != null) {
if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, " +
" adding " + focusedToken + " to mOpeningApps");
// Force animation to be loaded.
focusedToken.hidden = true;
mOpeningApps.add(focusedToken);
}
}
}
return;
}
final long origId = Binder.clearCallingIdentity();
wtoken.inPendingTransaction = false;
//将参数token所描述的Activity组件的可见性设置为参数visible所描述的值
setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
true, wtoken.voiceInteraction);
//向WMS服务上报参数token所描述的Activity组件的可见性
wtoken.updateReportedVisibilityLocked();
Binder.restoreCallingIdentity(origId);
}
}