Android 12系统源码_窗口管理(五)DisplayContent简介

这篇具有很好参考价值的文章主要介绍了Android 12系统源码_窗口管理(五)DisplayContent简介。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

DisplayContent 用于管理屏幕,一块DisplayContent 对象实例代表一个屏幕设备,这样有多个屏幕的设备就可以创建多个DisplayContent 对象,虽然多数设备只有一个显示屏,但它们同样可以创建多个 DisplayContent 对象,如投屏的时候,可以创建一个虚拟的DisplayContent。

一、DisplayContent 的创建

1、DisplayContent对象实例的创建最早是在SystemServer中被触发的。

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer implements Dumpable {

    private ActivityManagerService mActivityManagerService;

    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    		...代码省略...
            t.traceBegin("SetWindowManagerService");
            mActivityManagerService.setWindowManager(wm);//创建屏幕设备对象
            t.traceEnd();
            ...代码省略...
    }
}

该方法会调用ActivityManagerService的setWindowManager方法。

2、ActivityManagerService的setWindowManager方法如下所示。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
    
    public WindowManagerService mWindowManager;
    public ActivityTaskManagerService mActivityTaskManager;
    
    public void setWindowManager(WindowManagerService wm) {
        synchronized (this) {
            mWindowManager = wm;
            mWmInternal = LocalServices.getService(WindowManagerInternal.class);
            mActivityTaskManager.setWindowManager(wm);//创建屏幕设备对象
        }
    }
}

该方法会调用ActivityTaskManagerService的setWindowManager方法。

3、ActivityTaskManagerService的setWindowManager方法如下所示。

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    RootWindowContainer mRootWindowContainer;

    public void setWindowManager(WindowManagerService wm) {
        synchronized (mGlobalLock) {
            mWindowManager = wm;
            mRootWindowContainer = wm.mRoot;//获取WindowManagerService的RootWindowContainer对象
            mWindowOrganizerController.setWindowManager(wm);
            mTempConfig.setToDefaults();
            mTempConfig.setLocales(LocaleList.getDefault());
            mConfigurationSeq = mTempConfig.seq = 1;
            mRootWindowContainer.onConfigurationChanged(mTempConfig);
            mLockTaskController.setWindowManager(wm);
            mTaskSupervisor.setWindowManager(wm);
            mRootWindowContainer.setWindowManager(wm);//创建屏幕设备对象
        }
    }
 }

该方法会继续调用RootWindowContainer的setWindowManager方法。

4、DisplayContent对象实例就是在RootWindowContainer的setWindowManager方法中创建的。

frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

class RootWindowContainer extends WindowContainer<DisplayContent>
        implements DisplayManager.DisplayListener {

    DisplayManager mDisplayManager;
    /** Reference to default display so we can quickly look it up. */
    private DisplayContent mDefaultDisplay;

    void setWindowManager(WindowManagerService wm) {
        mWindowManager = wm;
        mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
        mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

        final Display[] displays = mDisplayManager.getDisplays();//通过DisplayManager获取屏幕设备信息
        for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {//遍历屏幕设备,为每个设备创建DisplayContent对象
            final Display display = displays[displayNdx];
            final DisplayContent displayContent = new DisplayContent(display, this);//创建屏幕对象DisplayContent实例
            addChild(displayContent, POSITION_BOTTOM);
            if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
                mDefaultDisplay = displayContent;
            }
        }
        calculateDefaultMinimalSizeOfResizeableTasks();

        final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
        defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
        positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
                false /* includingParents */);
    }
    
    //添加新创建的DisplayContent屏幕设备对象,将其存储到父类属性mChildren集合中
    void addChild(E child, int index) {
        if (!child.mReparenting && child.getParent() != null) {
            throw new IllegalArgumentException("addChild: container=" + child.getName()
                    + " is already a child of container=" + child.getParent().getName()
                    + " can't add to container=" + getName()
                    + "\n callers=" + Debug.getCallers(15, "\n"));
        }

        if ((index < 0 && index != POSITION_BOTTOM)
                || (index > mChildren.size() && index != POSITION_TOP)) {
            throw new IllegalArgumentException("addChild: invalid position=" + index
                    + ", children number=" + mChildren.size());
        }

        if (index == POSITION_TOP) {
            index = mChildren.size();
        } else if (index == POSITION_BOTTOM) {
            index = 0;
        }
		//将DisplayContent屏幕设备对象存储到父类属性mChildren集合中
        mChildren.add(index, child);

        // Set the parent after we've actually added a child in case a subclass depends on this.
        child.setParent(this);
    }
}

frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable {
	protected final WindowList<E> mChildren = new WindowList<E>();
}

1)首先通过DisplayManager获取当前存在的屏幕设备信息数组,然后遍历该数组为每个屏幕设备创建对应的DisplayContent对象实例。
2)调用addChild方法依次将创建的DisplayContent对象实例存储到父类的mChildren集合中。

二、DisplayContent类定义

frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java文章来源地址https://www.toymoban.com/news/detail-467817.html

class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {

    /**
     * Create new {@link DisplayContent} instance, add itself to the root window container and
     * initialize direct children.
     * @param display May not be null.
     * @param root {@link RootWindowContainer}
     */
    DisplayContent(Display display, RootWindowContainer root) {
        super(root.mWindowManager, "DisplayContent", FEATURE_ROOT);
        if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) {
            throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
                    + " already exists="
                    + mWmService.mRoot.getDisplayContent(display.getDisplayId())
                    + " new=" + display);
        }

        mRootWindowContainer = root;
        mAtmService = mWmService.mAtmService;
        mDisplay = display;
        mDisplayId = display.getDisplayId();
        mCurrentUniqueDisplayId = display.getUniqueId();
        mOffTokenAcquirer = mRootWindowContainer.mDisplayOffTokenAcquirer;
        mWallpaperController = new WallpaperController(mWmService, this);
        display.getDisplayInfo(mDisplayInfo);
        display.getMetrics(mDisplayMetrics);
        mSystemGestureExclusionLimit = mWmService.mConstants.mSystemGestureExclusionLimitDp
                * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
        isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
        mInsetsStateController = new InsetsStateController(this);
        mDisplayFrames = new DisplayFrames(mDisplayId, mInsetsStateController.getRawInsetsState(),
                mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation),
                calculateRoundedCornersForRotation(mDisplayInfo.rotation),
                calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation));
        initializeDisplayBaseInfo();

        mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
        mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier);
        mAppTransition.registerListenerLocked(mFixedRotationTransitionListener);
        mAppTransitionController = new AppTransitionController(mWmService, this);
        mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);

        final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
                "PointerEventDispatcher" + mDisplayId, mDisplayId);
        mPointerEventDispatcher = new PointerEventDispatcher(inputChannel, this);

        // Tap Listeners are supported for:
        // 1. All physical displays (multi-display).
        // 2. VirtualDisplays on VR, AA (and everything else).
        mTapDetector = new TaskTapPointerEventListener(mWmService, this);
        registerPointerEventListener(mTapDetector);
        registerPointerEventListener(mWmService.mMousePositionTracker);
        if (mWmService.mAtmService.getRecentTasks() != null) {
            registerPointerEventListener(
                    mWmService.mAtmService.getRecentTasks().getInputListener());
        }

        mDisplayPolicy = new DisplayPolicy(mWmService, this);
        mDisplayRotation = new DisplayRotation(mWmService, this);
        mCloseToSquareMaxAspectRatio = mWmService.mContext.getResources().getFloat(
                com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
        if (isDefaultDisplay) {
            // The policy may be invoked right after here, so it requires the necessary default
            // fields of this display content.
            mWmService.mPolicy.setDefaultDisplay(this);
        }
        if (mWmService.mDisplayReady) {
            mDisplayPolicy.onConfigurationChanged();
        }
        if (mWmService.mSystemReady) {
            mDisplayPolicy.systemReady();
        }
        mWindowCornerRadius = mDisplayPolicy.getWindowCornerRadius();
        mDividerControllerLocked = new DockedTaskDividerController(this);
        mPinnedTaskController = new PinnedTaskController(mWmService, this);

        final Transaction pendingTransaction = getPendingTransaction();
        configureSurfaces(pendingTransaction);
        pendingTransaction.apply();

        // Sets the display content for the children.
        onDisplayChanged(this);
        updateDisplayAreaOrganizers();

        mInputMonitor = new InputMonitor(mWmService, this);
        mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this);

        if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display);

        mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
    }
}

到了这里,关于Android 12系统源码_窗口管理(五)DisplayContent简介的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 工程管理系统简介 工程管理系统源码 java工程管理系统 工程管理系统功能设计

     鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管理的提升提出了更高

    2024年02月07日
    浏览(54)
  • 【Android 12】认识窗口

    该文章为窗口层级结构系列文章的总结,重新回看这方面内容的时候我自己也有了一些新的感悟,希望通过本次总结能让大家再次对窗口有一个全面的认识。 一般来说,屏幕上最起码包含三个窗口,StatusBar窗口、Activity窗口以及NavigationBar窗口: 我们想要了解窗口,可以按照

    2024年01月17日
    浏览(33)
  • Android 9系统源码_音频管理(一)按键音效源码解析

    当用户点击Android智能设备的按钮的时候,如果伴随有按键音效的话,会给用户更好的交互体验。本期我们将会结合Android系统源码来具体分析一下控件是如何发出按键音效的。 1、在TV版的Android智能设备中,我们可以通过调节设置页面的开关来控制按键音效的有无,该设置页面

    2024年02月09日
    浏览(43)
  • Android12窗口模糊(一)在Activity和Dialog中实现高斯模糊效果

    在 Android 12 中,提供了一些用于实现窗口模糊处理效果(例如背景模糊处理和模糊处理后方屏幕)的公共 API。窗口模糊处理或跨窗口模糊处理用于模糊处理给定窗口后方的屏幕。 有两种窗口模糊处理方式,可用于实现不同的视觉效果: 背景模糊处理(Background blur):可用于

    2023年04月19日
    浏览(80)
  • android源码学习- APP启动流程(android12源码)

    百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分)。所以我结合网上现有的文章,以及源码的阅读和调试,耗费了3整天的时间,力求写出一篇最完整,最详细,最通俗易懂的文章,

    2024年02月11日
    浏览(44)
  • AOSP 源码编译android 12

    目录 一、python安装      a. python2安装     b. python3安装 二、repo管理多个git    a.第一步,   新建一个空白文件夹保存repo引导文件,并包含你的路径    b.下载启动器  c.将git-repo中的repo文件复制到 1 创建的.bin目录中  d.修改权限 e. 执行版本检查 三、初始化工程   a.执行创建文

    2024年01月16日
    浏览(50)
  • 【Linux驱动开发】编译Android12源码

    基于讯为电子rk3568教程 rk_android12.0_sdk_20220720.tar.gz 解压 设置屏幕配置 整体编译 Android 固件 使能编译环境 开始整体编译 rockdev/Image-rk3568_s // 编译成功镜像存放位置 单独编译u-boot (方法一) 编译完成后在 u-boot 目录会生成 rk356x_spl_loader_v1.13.112.bin 文件、uboot.img 文件、 resourc

    2024年02月05日
    浏览(44)
  • Activity启动过程详解(Android 12源码分析)

    启动一个Activity,通常有两种情况,一种是在应用内部启动Activity,另一种是Launcher启动 1、应用内启动 通过startActivity来启动Activity 启动流程: 一、Activity启动的发起 二、Activity的管理——ATMS 三、线程切换即消息处理——mH 四、Activity启动核心实现——初始化及生命周期 2、

    2024年02月13日
    浏览(46)
  • 【毕业设计/课程设计】基于android的订餐系统设计与实现(源码+文章) 含Web管理端 安卓外卖点餐

    1、数据库:MySQL 2、开发工具 安卓端:android studio 管理后端:Idea、Eclipse、MyEclipse等Java开发工具均可 安卓端采用android studio工具开发,管理后端采用Java语言,MySQL数据库,开发框架是SpringBoot+VUE       利用网络管理各行各业的业务操作已经成为必然趋势。菜品通过网络进行销

    2024年02月04日
    浏览(59)
  • 【Android12】Monkey压力测试源码执行流程分析

    Monkey是Android提供的用于应用程序自动化测试、压力测试的测试工具。 其源码路径(Android12)位于 部署形式为Java Binary 通过Monkey,可以模拟用户的Touch(单指、多指、手势)、按键(key)事件等,检测应用程序发生的ANR、Crash事件,并收集相关Debug信息等。 例如测试应用com.packa

    2024年03月22日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包