WMS类图分析-android12

news/2024/5/20 21:20:59/文章来源:https://blog.csdn.net/weixin_42376458/article/details/128425490

为什么要分析类图?

WMS是一个复杂的模块,就像一个很大的家族,里面有各种角色,认识类图就像是认识WMS模块中的各个角色,不先把人认清楚了,怎么更好的理解他们之间的交互?

我觉得,这也是面向对象的语言魅力,面向对象的语言构建了一个小小的世界,每一个类都是其中的一个角色。

首先插一张类图,方便后面的分析

在这里插入图片描述

具体类图小析

ConfigurationContainer

类属性分析

这是WMS模块中的始祖级别的类,WMS中所有的类都继承于它。

ConfigurationContainer类中主要有三个Configuration对象,Configuration 本事就是各种基础参数 mode的记录

mRequestedOverrideConfiguration:当前应用主动请求的Configuration

mResolvedOverrideConfiguration:mRequestedOverrideConfiguration 经过子类的的调整后的对应容器请求的config,子类会重现相关的方法。

mFullConfiguration:当前使用的Configuration。

public abstract class ConfigurationContainer<E extends ConfigurationContainer> {//下面三个Configuration对象是配置相关的基础对象,onfiguration对象本身主要是一些参数的配置。/*** Contains requested override configuration settings applied to this configuration container. 当前应用主动请求的所有config*/private Configuration mRequestedOverrideConfiguration = new Configuration();/*** Contains the requested override configuration with parent and policy constraints applied.* This is the set of overrides that gets applied to the full and merged configurations.为mRequestedOverrideConfiguration 经过子类的的调整后的对应容器请求的config*/private Configuration mResolvedOverrideConfiguration = new Configuration();/*** Contains full configuration applied to this configuration container. Corresponds to full* parent's config with applied {@link #mResolvedOverrideConfiguration}.为父亲的config(mFullConfiguration) 加上自己的mResolvedOverrideConfiguration 组合成自身的mResolvedOverrideConfiguration*/private Configuration mFullConfiguration = new Configuration();//这个是返回的configuration/*** Returns full configuration applied to this configuration container.* This method should be used for getting settings applied in each particular level of the* hierarchy.从getConfiguration函数中可以看出,mFullConfiguration是在使用的congfiguration*/public Configuration getConfiguration() {return mFullConfiguration;}//onConfigurationChanged 当配置发生改变时调用,会在onParentChanged中调用public void onConfigurationChanged(Configuration newParentConfig) {mResolvedTmpConfig.setTo(mResolvedOverrideConfiguration); //先保存mResolvedOverrideConfigurationresolveOverrideConfiguration(newParentConfig);//mResolvedOverrideConfiguration从newParentConfig中算出来mFullConfiguration.setTo(newParentConfig);//mFullConfiguration 设为 newParentConfigmFullConfiguration.updateFrom(mResolvedOverrideConfiguration);//重新计算mFullConfigurationonMergedOverrideConfigurationChanged();if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {// This depends on the assumption that change-listeners don't do// their own override resolution. This way, dependent hierarchies// can stay properly synced-up with a primary hierarchy's constraints.// Since the hierarchies will be merged, this whole thing will go away// before the assumption will be broken.// Inform listeners of the change.for (int i = mChangeListeners.size() - 1; i >= 0; --i) {mChangeListeners.get(i).onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);//通知子节点更新}}for (int i = mChangeListeners.size() - 1; i >= 0; --i) {mChangeListeners.get(i).onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);}for (int i = getChildCount() - 1; i >= 0; --i) {dispatchConfigurationToChild(getChildAt(i), mFullConfiguration);}}//应该是parent发生变化是被调用void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {// Removing parent usually means that we've detached this entity to destroy it or to attach// to another parent. In both cases we don't need to update the configuration now.if (newParent != null) {// Update full configuration of this container and all its children.onConfigurationChanged(newParent.mFullConfiguration);// Update merged override configuration of this container and all its children.onMergedOverrideConfigurationChanged();}}
}

WindowContainer

也是一个子孙很多的类(当前WMS模块的类都是其子类),本身也是一个模板类,模板参数是继承于自己的子类。(这种类真的很绕,因为androd framework层面的有很多类树结构的设计,这种设计便于遍历,从而就需要这种模板类)。

类属性分析

持有DisplayContent、SurfaceControl、SurfaceFreezer对象,以及最重要的WindowManagerService对象,这些对象放在这个类,说明这些对象是每一个WMS模块类都需要的。

/*** Defines common functionality for classes that can hold windows directly or through their 定义了很多公用函数,可以直接用来管理窗口。* children in a hierarchy form.* The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime* changes are made to this class.*/
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable {/*** The parent of this window container.* For removing or setting new parent {@link #setParent} should be used, because it also // 保存父节点* performs configuration updates based on new parent's settings.*/private WindowContainer<WindowContainer> mParent = null;// List of children for this window container. List is in z-order as the children appear on// screen with the top-most window container at the tail of the list.// 存储子节点WindowContainer的listprotected final WindowList<E> mChildren = new WindowList<E>();// The display this window container is on.//每一个window 都需要在一个display之上protected DisplayContent mDisplayContent;//窗口的内容是绘制在surface上的,SurfaceControl是java层和native层设置surface相关的唯一渠道,所有的surface参数都需要调用SurfaceControl来设置。protected SurfaceControl mSurfaceControl;/*** Windows that clients are waiting to have drawn. 需要等待绘制的窗口List*/final ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();//动效控制对象protected final SurfaceAnimator mSurfaceAnimator;//冻结管理类final SurfaceFreezer mSurfaceFreezer;//窗口管理服务对象,WMS的核心管家,虽然不在WMS类图中。就像一个专业的CEO吧,管理大家族公司WindowManagerService值得单独分析protected final WindowManagerService mWmService;//留下一个监听用的类private final List<WindowContainerListener> mListeners = new ArrayList<>();//配置变换了,要把父节点的配置都改变一下public void onConfigurationChanged(Configuration newParentConfig) {super.onConfigurationChanged(newParentConfig);updateSurfacePositionNonOrganized();scheduleAnimation();}void reparent(WindowContainer newParent, int position) {
...final WindowContainer oldParent = mParent;
...// The display object before reparenting as that might lead to old parent getting removed// from the display if it no longer has any child.final DisplayContent prevDc = oldParent.getDisplayContent();final DisplayContent dc = newParent.getDisplayContent();mReparenting = true;oldParent.removeChild(this);//将当前window从旧的父节点取下来,放到新的父节点里面newParent.addChild(this, position);mReparenting = false;// Relayout display(s)dc.setLayoutNeeded();//因为放了新的window过来,则可能需要重新布局if (prevDc != dc) {onDisplayChanged(dc);//调用自己的displayChanged函数,对surface做一些处理prevDc.setLayoutNeeded();//原理的display也需要重新布局}getDisplayContent().layoutAndAssignWindowLayersIfNeeded();//暂时不知道功能// Send onParentChanged notification here is we disabled sending it in setParent for// reparenting case.onParentChanged(newParent, oldParent);//调用具体的完成surface相关的细节操作onSyncReparent(oldParent, newParent);//同步相关的函数}/** 重写ConfigureContainer 中的函数* Update override configuration and recalculate full config.* @see #mRequestedOverrideConfiguration * @see #mFullConfiguration*/@Overridepublic void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {...}/** 主要是调用子节点的onDisplayChanged方法* Notify that the display this container is on has changed. This could be either this container* is moved to a new display, or some configurations on the display it is on changes.** @param dc The display this container is on after changes.*/void onDisplayChanged(DisplayContent dc) {if (mDisplayContent != null && mDisplayContent.mChangingContainers.remove(this)) {// Cancel any change transition queued-up for this container on the old display.mSurfaceFreezer.unfreeze(getPendingTransaction());}mDisplayContent = dc;if (dc != null && dc != this) {dc.getPendingTransaction().merge(mPendingTransaction);}for (int i = mChildren.size() - 1; i >= 0; --i) {final WindowContainer child = mChildren.get(i);child.onDisplayChanged(dc);}for (int i = mListeners.size() - 1; i >= 0; --i) {mListeners.get(i).onDisplayChanged(dc);}}//这种forAll的方法都是去遍历子节点,使用callBack函数,开闭原则void forAllWindows(Consumer<WindowState> callback, boolean traverseTopToBottom) {ForAllWindowsConsumerWrapper wrapper = obtainConsumerWrapper(callback);forAllWindows(wrapper, traverseTopToBottom);wrapper.release();}boolean forAllActivities(Function<ActivityRecord, Boolean> callback){...};void forAllTasks(Consumer<Task> callback){};/** 比较窗口的Z值顺序* Returns 1, 0, or -1 depending on if this container is greater than, equal to, or lesser than* the input container in terms of z-order.*/@Overridepublic int compareTo(WindowContainer other) {...规则暂时没有理解,感觉有点意思}//动画机制/*** Applies the app transition animation according the given the layout properties in the * window hierarchy.** @param lp The layout parameters of the window. 窗口参数* @param transit The app transition type indicates what kind of transition to be applied. 过渡动画的类型* @param enter Whether the app transition is entering transition or not.* @param isVoiceInteraction Whether the container is participating in voice interaction or not. 这个窗口是否伴有声音交互* @param sources {@link ActivityRecord}s which causes this app transition animation. 谁发起了这个过渡动画** @return {@code true} when the container applied the app transition, {@code false} if the*         app transition is disabled or skipped.** @see #getAnimationAdapter*/boolean applyAnimation(WindowManager.LayoutParams lp, @TransitionOldType int transit,boolean enter, boolean isVoiceInteraction,@Nullable ArrayList<WindowContainer> sources) {... applyAnimationUnchecked(lp, enter, transit, isVoiceInteraction, sources); //这是关键函数,注意这种Unchecked写法,就是表示这个函数的一些前置条件在调用它的函数中已经分析处理了,它只要安心干活就行,不需要考虑太多前置条件。}    protected void applyAnimationUnchecked(WindowManager.LayoutParams lp, boolean enter,@TransitionOldType int transit, boolean isVoiceInteraction,@Nullable ArrayList<WindowContainer> sources) {...final Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp,transit, enter, isVoiceInteraction);//这里用到了适配器设计模式...if (adapter != null) {if (sources != null) {mSurfaceAnimationSources.addAll(sources);//把suorces添加进来}startAnimation(getPendingTransaction(), adapter, !isVisible(),ANIMATION_TYPE_APP_TRANSITION);//开启动画流程if (adapter.getShowWallpaper()) {getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;}if (thumbnailAdapter != null) {mSurfaceFreezer.mSnapshot.startAnimation(getPendingTransaction(),thumbnailAdapter, ANIMATION_TYPE_APP_TRANSITION, (type, anim) -> { });}}}private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,boolean isVoiceInteraction) {//从displayInfo中拿一些尺寸数据,当displayInfo出现问题时,动画可能也会出现问题final DisplayContent displayContent = getDisplayContent();final DisplayInfo displayInfo = displayContent.getDisplayInfo();final int width = displayInfo.appWidth;final int height = displayInfo.appHeight;//开始做更多的具体行动,为开始动画做准备final Configuration displayConfig = displayContent.getConfiguration();final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,surfaceInsets, stableInsets, isVoiceInteraction, inFreeformWindowingMode(), this);}
}

WindowToken

首先理解一下Token这个词,在framework层,token可以简单理解为一种句柄,通过其可以索引到某个对象。比如将Token作为Map的Key。具体到WindowToken,首先它是相关window的句柄,其次它也可以是app的activity的Token.

类属性分析

持有一个IBinder对象 作为实际的token, 因为IBinder类型可以跨进程通信,持有一个Bundle对象,其实传送数据的载体

/*** Container of a set of related windows in the window manager. Often this is an AppWindowToken,* which is the handle for an Activity that it uses to display windows. For nested windows, there is* a WindowToken created for the parent window to manage its children.*/
//注意WindowToken不是一个模板类,是继承了WindowContainer<WindowState> 这个类,也就是说其继承的WindowContainer中某些模板方法的模板参数已经被具体化成了WindowState
class WindowToken extends WindowContainer<WindowState> {/** The actual token */final IBinder token;//只有IBinder类型才能跨进程通信/*** Options that will be used to determine which {@link RootDisplayArea} this window should be* attached to.//Bundle 是传送数据的载体*/@Nullablefinal Bundle mOptions;/** 这个内部类看起来是和旋转相关的,后面看动画相关也许要回来看,这里先不过多探究* Used to fix the transform of the token to be rotated to a rotation different than it's* display. The window frames and surfaces corresponding to this token will be layouted and* rotated by the given rotated display info, frames and insets.*/private static class FixedRotationTransformState {final DisplayInfo mDisplayInfo;final DisplayFrames mDisplayFrames;final Configuration mRotatedOverrideConfiguration;final SeamlessRotator mRotator;/*** The tokens that share the same transform. Their end time of transform are the same. The* list should at least contain the token who creates this state.*/final ArrayList<WindowToken> mAssociatedTokens = new ArrayList<>(3);final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3);final SparseArray<Rect> mBarContentFrames = new SparseArray<>();boolean mIsTransforming = true;...}}

ActivityRecord

就是表示一个activity,记录了一个activity各种相关参数

final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {final ActivityTaskManagerService mAtmService;final ActivityInfo info; // activity info provided by developer in AndroidManifest 这个info应该是很原始的信息// TODO: rename to mActivityToken //这个Token是个内部类final ActivityRecord.Token appToken;// the intent component, or target of an alias.一个 intent 组间?final ComponentName mActivityComponent;// Input application handle used by the input dispatcher. 输入信息处理者private InputApplicationHandle mInputApplicationHandle;final Intent intent;    // the original intent that generated usprivate Task task;              // the task this is in. task是关键// Last configuration reported to the activity in the client process.private MergedConfiguration mLastReportedConfiguration;CompatibilityInfo compat;// last used compatibility modeActivityRecord resultTo; // who started this entry, so will get our replyActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.WindowProcessController app;      // if non-null, hosting applicationfinal ActivityTaskSupervisor mTaskSupervisor;final RootWindowContainer mRootWindowContainer;/** 在应用旋转场景下提前计算的display大小* The precomputed display insets for resolving configuration. It will be non-null if* {@link #shouldCreateCompatDisplayInsets} returns {@code true}.*/private CompatDisplayInsets mCompatDisplayInsets;// Set to the previous Task parent of the ActivityRecord when it is reparented to a new Task 进入画中画前把父节点保存起来// due to picture-in-picture. This gets cleared whenever this activity or the Task// it references to gets removed. This should also be cleared when we move out of pip.private Task mLastParentBeforePip;

DisplayArea

/*** Container for grouping WindowContainer below DisplayContent.** DisplayAreas are managed by a {@link DisplayAreaPolicy}, and can override configurations and* can be leashed.** DisplayAreas can contain nested DisplayAreas.** DisplayAreas come in three flavors, to ensure that windows have the right Z-Order:* - BELOW_TASKS: Can only contain BELOW_TASK DisplayAreas and WindowTokens that go below tasks.* - ABOVE_TASKS: Can only contain ABOVE_TASK DisplayAreas and WindowTokens that go above tasks.* - ANY: Can contain any kind of DisplayArea, and any kind of WindowToken or the Task container.** @param <T> type of the children of the DisplayArea.*/public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {protected final Type mType;private final String mName;final int mFeatureId;private final DisplayAreaOrganizerController mOrganizerController;IDisplayAreaOrganizer mOrganizer;private final Configuration mTmpConfiguration = new Configuration();/*** Whether this {@link DisplayArea} should ignore fixed-orientation request. If {@code true}, it* can never specify orientation, but shows the fixed-orientation apps below it in the* letterbox; otherwise, it rotates based on the fixed-orientation request.*/protected boolean mIgnoreOrientationRequest;/*** DisplayArea that contains WindowTokens, and orders them according to their type.*/public static class Tokens extends DisplayArea<WindowToken> {...}/*** DisplayArea that can be dimmed.*/static class Dimmable extends DisplayArea<DisplayArea> {...}
}

TaskDisplayArea

类属性分析

和surfaceControl关系有一点紧密,持有ActivityTaskManagerService对象。

/*** {@link DisplayArea} that represents a section of a screen that contains app window containers.  表示包含应用程序窗口容器的屏幕部分** The children can be either {@link Task} or {@link TaskDisplayArea}.*/
final class TaskDisplayArea extends DisplayArea<WindowContainer> {DisplayContent mDisplayContent;/*** A control placed at the appropriate level for transitions to occur.*/private SurfaceControl mAppAnimationLayer;private SurfaceControl mBoostedAppAnimationLayer;private SurfaceControl mHomeAppAnimationLayer;/*** Given that the split-screen divider does not have an AppWindowToken, it* will have to live inside of a "NonAppWindowContainer". However, in visual Z order* it will need to be interleaved with some of our children, appearing on top of* both docked root tasks but underneath any assistant root tasks.** To solve this problem we have this anchor control, which will always exist so* we can always assign it the correct value in our {@link #assignChildLayers}.* Likewise since it always exists, we can always* assign the divider a layer relative to it. This way we prevent linking lifecycle* events between tasks and the divider window.*/ // 看上去 意思是一个分屏线图层private SurfaceControl mSplitScreenDividerAnchor;private ActivityTaskManagerService mAtmService;private RootWindowContainer mRootWindowContainer;
}

Dimmable

static class Dimmable extends DisplayArea<DisplayArea> {private final Dimmer mDimmer = new Dimmer(this);private final Rect mTmpDimBoundsRect = new Rect();}
RootDisplayArea
/*** Root of a {@link DisplayArea} hierarchy. It can be either the {@link DisplayContent} as the root* of the whole logical display, or a {@link DisplayAreaGroup} as the root of a partition of the* logical display.*/class RootDisplayArea extends DisplayArea.Dimmable {/** {@link Feature} that are supported in this {@link DisplayArea} hierarchy. */List<DisplayAreaPolicyBuilder.Feature> mFeatures;/*** Mapping from policy supported {@link Feature} to list of {@link DisplayArea} created to cover* all the window types that the {@link Feature} will be applied to.*/Map<Feature, List<DisplayArea<WindowContainer>>> mFeatureToDisplayAreas;/** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */private DisplayArea.Tokens[] mAreaForLayer;
}
DisplayContent

类属性分析

/*** Utility class for keeping track of the WindowStates and other pertinent contents of a* particular Display.*/
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {final ActivityTaskManagerService mAtmService;/*** Unique logical identifier of this display.** @see DisplayInfo#displayId*/final int mDisplayId;/*** Unique physical identifier of this display. Unlike {@link #mDisplayId} this value can change* at runtime if the underlying physical display changes.** @see DisplayInfo#uniqueId*/@NullableString mCurrentUniqueDisplayId;/*** We organize all top-level Surfaces into the following layer.* It contains a few Surfaces which are always on top of others, and omitted from* Screen-Magnification, for example the strict mode flash or the fullscreen magnification* overlay.*/private SurfaceControl mOverlayLayer;/*** The direct child layer of the display to put all non-overlay windows. This is also used for* screen rotation animation so that there is a parent layer to put the animation leash.*/private final SurfaceControl mWindowingLayer;// Contains all IME window containers. Note that the z-ordering of the IME windows will depend// on the IME target. We mainly have this container grouping so we can keep track of all the IME// window containers together and move them in-sync if/when needed. We use a subclass of// WindowContainer which is omitted from screen magnification, as the IME is never magnified.// TODO(display-area): is "no magnification" in the comment still true?private final ImeContainer mImeWindowsContainer = new ImeContainer(mWmService);final AppTransition mAppTransition;final AppTransitionController mAppTransitionController;final ArraySet<ActivityRecord> mOpeningApps = new ArraySet<>();final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();final ArraySet<WindowContainer> mChangingContainers = new ArraySet<>();// Mapping from a token IBinder to a WindowToken object on this display.private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();DisplayCutout mInitialDisplayCutout; //挖空屏的屏幕信息RoundedCorners mInitialRoundedCorners; // 圆角信息/*** Whether to disable display scaling. This can be set via shell command "adb shell wm scaling".* @see WindowManagerService#setForcedDisplayScalingMode(int, int)*/boolean mDisplayScalingDisabled;final Display mDisplay;private final DisplayInfo mDisplayInfo = new DisplayInfo();private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();private final DisplayPolicy mDisplayPolicy;private final DisplayRotation mDisplayRotation;DisplayFrames mDisplayFrames;WallpaperController mWallpaperController;private final SurfaceSession mSession = new SurfaceSession();/*** Window that is currently interacting with the user. This window is responsible for receiving* key events and pointer events from the user.*/WindowState mCurrentFocus = null;/*** The last focused window that we've notified the client that the focus is changed.*/WindowState mLastFocus = null;/*** The foreground app of this display. Windows below this app cannot be the focused window. If* the user taps on the area outside of the task of the focused app, we will notify AM about the* new task the user wants to interact with.*/ActivityRecord mFocusedApp = null;/*** Container for IME windows.** This has some special behaviors:* - layers assignment is ignored except if setNeedsLayer() has been called before (and no*   layer has been assigned since), to facilitate assigning the layer from the IME target, or*   fall back if there is no target.* - the container doesn't always participate in window traversal, according to*   {@link #skipImeWindowsDuringTraversal()}*/private static class ImeContainer extends DisplayArea.Tokens {...}
}
DisplayAreaGroup
/** The root of a partition of the logical display. */
class DisplayAreaGroup extends RootDisplayArea{}

Task

class Task extends WindowContainer<WindowContainer> {Intent intent;          // The original intent that started the task. Note that this value can be null.ComponentName realActivity; // The actual activity component that started the task./** The process that had previously hosted the root activity of this task.* Used to know that we should try harder to keep this process around, in case the* user wants to return to it. */private WindowProcessController mRootProcess;Task mAdjacentTask; // Task adjacent to this one.int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.Task mPrevAffiliate; // previous task in affiliated chain.int mPrevAffiliateTaskId = INVALID_TASK_ID; // previous id for persistence.Task mNextAffiliate; // next task in affiliated chain.int mNextAffiliateTaskId = INVALID_TASK_ID; // next id for persistence.// For relaunching the task from recents as though it was launched by the original launcher.int mCallingUid;String mCallingPackage;String mCallingFeatureId;// Minimal width and height of this task when it's resizeable. -1 means it should use the// default minimal width/height.int mMinWidth;int mMinHeight;// The surface transition of the target when recents animation is finished.// This is originally introduced to carry out the current surface control position and window// crop when a multi-activity task enters pip with autoEnterPip enabled. In such case,// the surface control of the task will be animated in Launcher and then the top activity is// reparented to pinned root task.// Do not forget to reset this after reparenting.// TODO: remove this once the recents animation is moved to the ShellPictureInPictureSurfaceTransaction mLastRecentsAnimationTransaction;// The content overlay to be applied with mLastRecentsAnimationTransaction// TODO: remove this once the recents animation is moved to the ShellSurfaceControl mLastRecentsAnimationOverlay;final ActivityTaskManagerService mAtmService;final ActivityTaskSupervisor mTaskSupervisor;final RootWindowContainer mRootWindowContainer;/* Unique identifier for this task. */final int mTaskId;/* User for which this task was created. */// TODO: Make finalint mUserId;/*** Display rotation as of the last time {@link #setBounds(Rect)} was called or this task was* moved to a new display.*/@Surface.Rotationprivate int mRotation;private Dimmer mDimmer = new Dimmer(this);private final Rect mTmpDimBoundsRect = new Rect();/** ActivityRecords that are exiting, but still on screen for animations. */final ArrayList<ActivityRecord> mExitingActivities = new ArrayList<>();// When non-null, this is a transaction that will get applied on the next frame returned after// a relayout is requested from the client. While this is only valid on a leaf task; since the// transaction can effect an ancestor task, this also needs to keep track of the ancestor task// that this transaction manipulates because deferUntilFrame acts on individual surfaces.SurfaceControl.Transaction mMainWindowSizeChangeTransaction;Task mMainWindowSizeChangeTask;}

RootWindowContainer

class RootWindowContainer extends WindowContainer<DisplayContent>implements DisplayManager.DisplayListener {private Object mLastWindowFreezeSource = null;private Session mHoldScreen = null;// Following variables are for debugging screen wakelock only.// Last window that requires screen wakelockWindowState mHoldScreenWindow = null;// Last window that obscures all windows belowWindowState mObscuringWindow = null;private final Handler mHandler;// The ID of the display which is responsible for receiving display-unspecified key and pointer// events.private int mTopFocusedDisplayId = INVALID_DISPLAY;// Map from the PID to the top most app which has a focused window of the process.final ArrayMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new ArrayMap<>();// Only a separate transaction until we separate the apply surface changes// transaction from the global transaction.private final SurfaceControl.Transaction mDisplayTransaction;ActivityTaskManagerService mService;ActivityTaskSupervisor mTaskSupervisor;WindowManagerService mWindowManager;DisplayManager mDisplayManager;private DisplayManagerInternal mDisplayManagerInternal;/** Reference to default display so we can quickly look it up. */private DisplayContent mDefaultDisplay;
}

WindowState

class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState,InsetsControlTarget {final WindowManagerPolicy mPolicy;final Context mContext;final Session mSession;final IWindow mClient;WindowToken mToken;ActivityRecord mActivityRecord;final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();final DeathRecipient mDeathRecipient;private RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;/** @see #addEmbeddedDisplayContent(DisplayContent dc) */private final ArraySet<DisplayContent> mEmbeddedDisplayContents = new ArraySet<>();/*** Used to store last reported to client configuration and check if we have newer available.* We'll send configuration to client only if it is different from the last applied one and* client won't perform unnecessary updates.*/private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration();private final Configuration mTempConfiguration = new Configuration();            /*** These are the content insets that were given during layout for* this window, to be applied to windows behind it.*/final Rect mGivenContentInsets = new Rect();/*** These are the visible insets that were given during layout for* this window, to be applied to windows behind it.*/final Rect mGivenVisibleInsets = new Rect();/*** This is the given touchable area relative to the window frame, or null if none.*/final Region mGivenTouchableRegion = new Region();private final WindowFrames mWindowFrames = new WindowFrames();private final ClientWindowFrames mClientWindowFrames = new ClientWindowFrames();/** The frames used to compute a temporal layout appearance. */private WindowFrames mSimulatedWindowFrames;/*** List of rects where system gestures should be ignored.** Coordinates are relative to the window's position.*/private final List<Rect> mExclusionRects = new ArrayList<>();// Input channel and input window handle used by the input dispatcher.final InputWindowHandleWrapper mInputWindowHandle;InputChannel mInputChannel;final WindowStateAnimator mWinAnimator;// If not null, the window that will be used to replace the old one. This is being set when// the window is added and unset when this window reports its first draw.private WindowState mReplacementWindow = null;private final Transaction mTmpTransaction;/*** The insets state of sources provided by windows above the current window.*/final InsetsState mAboveInsetsState = new InsetsState();/*** The insets sources provided by this window.*/final SparseArray<InsetsSource> mProvidedInsetsSources = new SparseArray<>();   /*** A region inside of this window to be excluded from touch.*/private final Region mTapExcludeRegion = new Region();/*** Used for testing because the real PowerManager is final.*/private PowerManagerWrapper mPowerManagerWrapper;/*** Indicates whether we have requested a Dim (in the sense of {@link Dimmer}) from our host* container.*/private boolean mIsDimming = false;private @Nullable InsetsSourceProvider mControllableInsetProvider;private final InsetsState mRequestedInsetsState = new InsetsState();/*** Freeze the insets state in some cases that not necessarily keeps up-to-date to the client.* (e.g app exiting transition)*/private InsetsState mFrozenInsetsState;}

就这样,先大致过一遍各个类及属性,后面分析一些关键流程的时候再仔细看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_239591.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

达梦数据IPO过会:拟募资24亿 光谷“扫地僧”冯裕才将敲钟

雷递网 雷建平 12月23日武汉达梦数据库股份有限公司&#xff08;简称&#xff1a;“达梦数据”&#xff09;日前IPO过会&#xff0c;准备在科创板上市。达梦数据计划募资23.51亿元。其中&#xff0c;3.52亿元用于集群数据库管理系统升级项目&#xff0c;3.43亿元用于高性能分布…

pytorch 多卡运行详细教程

先说明一下背景&#xff0c;目前正在魔改以下这篇论文的代码&#xff1a; https://github.com/QipengGuo/GraphWriter-DGLgithub.com 由于每次完成实验需要5个小时&#xff08;baseline&#xff09;&#xff0c;自己的模型需要更久&#xff08;2倍&#xff09;&#xff0c;非…

2022星空创造营应用创新大赛圆满落幕,获奖名单出炉!

​12月22日&#xff0c;2022星空创造营应用创新大赛在2022手机创新周暨第十届手机设计大赛颁奖典礼上作为特别专场正式公布获奖名单。2022星空创造营应用创新大赛由联通在线、手机设计大赛天鹅奖组委会联合主办&#xff0c;联通在线音乐公司及工信部赛迪研究院共同承办&#xf…

小学生C++编程基础 课程10

938.最小公倍数的简单方法 &#xff08;课程A&#xff09; 难度&#xff1a;1 登录 939.最大公约数的简单方法 ( 课程A&#xff09; 难度&#xff1a;1 登录 940.韩信点兵 &#xff08;课程A&#xff09; 难度&#xff1a;1 登录 941.求123…N的和 &#xff08;课程A&#x…

Spring MVC【返回数据与请求转发和重定向】

Spring MVC【返回数据与请求转发和重定向】&#x1f34e;一. 返回数据&#x1f352;1.1 返回静态页面&#x1f352;1.2 返回一个非静态页面&#x1f352;1.3 返回text/html类型页面&#x1f352;1.4 返回JSON对象&#x1f352;1.5 实现计算器功能&#x1f352;1.6 使用ajax方式…

【算法】P1 算法简介

算法什么是算法正确与错误的算法算法可以解决什么问题本专栏有哪些算法什么是算法 算法 (Algorithm) 取某个值或集合作为 输入&#xff0c;并产生某个值或集合作为 输出。算法就是把输入转换为输出的计算&#xff0c;描述这个计算的过程来实现输入与输出的关系。 正确与错误的…

股票量化分析工具QTYX使用攻略——实盘交易信号监控(更新2.5.7)

搭建自己的量化系统如果要长期在市场中立于不败之地&#xff01;必须要形成一套自己的交易系统。如何学会搭建自己的量化交易系统&#xff1f;边学习边实战&#xff0c;在实战中学习才是最有效地方式。于是我们分享一个即可以用于学习&#xff0c;也可以用于实战炒股分析的量化…

插值算法基本原理

插值&#xff1a;数据处理的手段 将缺失数据补全处理 线性内插 拉格朗日插值法 牛顿插值 拟合&#xff1a;预测&#xff0c;寻找规律的手段 是插值的外延 插值算法&#xff1a;使用在现有的数据极少&#xff0c;不足以支撑分析的进行&#xff0c;这时就需要使用一些数学方法…

【Vue】Vue重写教室管理系统的前端网页V1(前后端分离)--20221222

项目说明 目的 练习并熟悉Vue2 的API&#xff0c;来为Vue项目做准备&#xff1a; 插值语法插槽props和data父子组件通信Ajax异步请求数据生命周期函数methods方法computed属性vue-router、路由守卫、query/params传参、编程函数式路由模拟后端服务器传送数据打包项目 需要加…

Python正在消亡?致命弱点是否会让Python被新语言取代?

被业界称为“瑞士军刀”的编程语言&#xff0c;可能会被更适合该任务的其他语言取代吗&#xff1f; 自从1990年代初Python发布以来&#xff0c;它引起了很多热议。当然&#xff0c;编程社区花了至少20年的时间才逐渐注意到它的存在&#xff0c;而当它一旦开始流行起来&#xf…

Apache DolphinScheduler 发布 3.1.2 版本,Python API 实现优化

点亮 ⭐️ Star 照亮开源之路https://github.com/apache/dolphinscheduler近日&#xff0c;Apache DolphinScheduler 发布了 3.1.2 版本。此版本主要基于 3.1.1 版本进行了 6 处 Python API 优化&#xff0c;19 处 Bug 修复&#xff0c;并更新了 4 个文档。其中较为重要的 Bug…

Doo Prime 提供高达 1000 倍杠杆,助您撬动无限机遇

2022 年 11 月 19 日&#xff0c;Doo Prime 正式将全部账户类型的可选杠杆从 1:500 上调至 1:1000 倍&#xff0c;提供更灵活的杠杆选择&#xff0c;让全球客户有机会以更少的资金撬动更高的潜在利润&#xff0c;进一步拓展投资机遇。 *备注&#xff1a;杠杆调整详情请参阅下文…

JavaDS1-时间复杂度空间复杂度

目录 1.算法效率 1.1.时间效率&#xff08;时间复杂度&#xff09;——衡量算法运行速度 1.2.空间效率&#xff08;空间复杂度&#xff09;——衡量算法所需额外空间&#xff08;如今不再特别关注&#xff09; 2.时间复杂度 2.1.概念 2.2.大O的渐进表示法 2.2.1.O(F(n))…

学到羊之Kafka

1 kafka 是啥 Kafka 是一款开源的消息引擎系统&#xff0c;用来实现解耦的异步式数据传递。即系统 A 发消息给到 消息引擎系统&#xff0c;系统 B 通过消息引擎系统读取 A 发送的消息&#xff0c;在大数据场景下&#xff0c;能达到削峰填谷的效果。 2 Kafka 术语 Kafka 中的分…

day28【代码随想录】回溯之组合、组合总和|||、电话号码的字母组合

文章目录前言一、组合&#xff08;力扣77&#xff09;剪枝优化二、组合总和 III&#xff08;力扣216&#xff09;剪枝优化三、电话号码的字母组合&#xff08;力扣17&#xff09;总结前言 1、组合 2、组合总和||| 3、电话号码的字母组合 一、组合&#xff08;力扣77&#xff0…

解析 Navicat 最受欢迎的功能 | SQL 查询编辑器与 SQL 创建工具

近期发起的线上投票调查中&#xff0c;我们很高兴地看到&#xff1a;SQL 查询编辑器、SQL 创建工具已成为用户最常用的功能之一&#xff0c;并且深受用户欢迎&#xff01;在人类社会发展的历史长河中&#xff0c;离不开工具的演进与发展。而 Navicat 作为领先的数据库管理开发工…

【Pandas入门教程】如何读取和写入表格数据

如何读取和写入表格数据 来源&#xff1a;Pandas官网&#xff1a;https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html 文章目录如何读取和写入表格数据导包【1】如何读取和写入表格数据【2】小结导包 import pandas as pd数据介绍&#xff1a; 使用存…

python--可重用的登录注册系统(上)

文章目录预期目标一、基本逻辑设计数据库模型二、前端界面设计与优化完善登录的视图函数三、session会话与登录的视图函数四、将项目上传到远程仓库预期目标 实现注册&#xff08;邮箱、手机、qq、微信&#xff09; 登录 注销等功能 路由配置 视图配置 数据库模型 模板&#xf…

【云服务器 ECS 实战】一文掌握弹性伸缩服务原理及配置方法

1. 弹性伸缩概述2. 实现模式3. 基于 GRE 实现 VPC 的互联4. 弹性伸缩服务的配置使用4.1 创建伸缩组4.2 伸缩配置4.3 创建伸缩规则1. 弹性伸缩概述 弹性伸缩&#xff08;Auto Scaling&#xff09;就是自动为我们调整弹性计算资源大小&#xff0c;以满足业务需求的变化&#xff…

机器学习之回归

回归算法 线性回归 求解线性回归方法 正规方程梯度下降 迭代 API sklearn.linear_model.LinearRegression 正规方程优化fit_intercept 是否计算偏置量&#xff0c;没有的化经过原点属性 coef_ 回归系数intercept_ 偏置量 sklearn.linear_model.SGDRegressor 使用随机梯度…