Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换

这篇具有很好参考价值的文章主要介绍了Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 桌面壁纸

先看桌面情况下壁纸,这个情况应该属于我们最为熟悉的,那么就不用多说,大概就是因为桌面Activity的配置主题xml设置一个类似showallpaper的属性既可以,就可以让桌面后面显示壁纸了
Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换

2 aosp编译后版本锁屏后点亮屏幕也可以看到桌面壁纸(注意这里还不是专门锁屏壁纸)
大家发现锁屏点亮后确实看到的壁纸和桌面的壁纸一模一样
Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换

3 疑惑

这里是不是大家就开始比较疑惑了,请问普通Activity是通过属性配置的,而且壁纸窗口又是在wms属于最底层的状态,他依附于桌面这个可以理解,但是为啥锁屏时候又可以看到壁纸呢?锁屏理论上也只是一个window盖在最顶层,理论即使这个锁屏window透明,那么透看到的也是有桌面Activity的情况,但现实情况是我们只看到了壁纸,并没有看到桌面

针对以上的疑惑,那接下来我们就需要去解答这个疑惑。
首先我们知道壁纸属于系统中一个特殊窗口,一直处于系统最底层。这个窗口在系统中有专门类进行他的显示情况,那就我们的WallpaperController类
这个WallpaperController.java中有log打印,但需要我们将对应标志位给设置一下:

if (DEBUG_WALLPAPER) {
    Slog.v(TAG, "Wallpaper visibility: " + visible + " at display "
            + mDisplayContent.getDisplayId());
}

这里我们把DEBUG_WALLPAPER就可以把log打开了

10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{60c77f1 u0 ScreenDecorOverlayBottom}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{df0a78b u0 ScreenDecorOverlay}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{b7a35a u0 NavigationBar0}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{3cd76e8 u0 NotificationShade}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Found wallpaper target: Window{3cd76e8 u0 NotificationShade}
10-23 22:55:41.115  5313  6475 V WindowManager: New wallpaper target: Window{3cd76e8 u0 NotificationShade} prevTarget: null
10-23 22:55:41.116  5313  6475 V WindowManager: Report new wp offset Window{803c2b8 u0 com.android.systemui.ImageWallpaper} x=0.0 y=0.5 zoom=0.0
10-23 22:55:41.116  5313  6475 V WindowManager: Wallpaper visibility: true at display 0
10-23 22:55:41.116  5313  6475 D WindowManager: Wallpaper token android.os.Binder@3a6eda2 visible=true
10-23 22:55:41.118  5313  6475 D WindowManager: New wallpaper: target=Window{3cd76e8 u0 NotificationShade} prev=null
10-23 22:55:41.163  5313  5313 D WindowManager: powerPress: eventTime=118823847 interactive=true count=0 beganFromNonInteractive=true mShortPressOnPowerBehavior=1


打开后我们点亮锁屏和在桌面锁屏发现都有类似以下打印
WindowManager: Found wallpaper target: Window{3cd76e8 u0 NotificationShade}
看名字大家大概就知道这个log是在寻找一个wallpaper target:,而且找到的是NotificationShade即锁屏窗口
前面疑惑中就写到正常应该是桌面
10-24 00:18:50.543 10429 10450 V WindowManager: Found wallpaper target: Window{8d79f3 u0 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher}
这日志其实就可以给我们非常重要线索,可以找出对应代码在哪

 private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
        if ((w.mAttrs.type == TYPE_WALLPAPER)) {
            if (mFindResults.topWallpaper == null || mFindResults.resetTopWallpaper) {
                mFindResults.setTopWallpaper(w);
                mFindResults.resetTopWallpaper = false;
            }
            return false;
        }

        mFindResults.resetTopWallpaper = true;
        if (mService.mAtmService.getTransitionController().getTransitionPlayer() == null) {
            if (w.mActivityRecord != null && !w.mActivityRecord.isVisible()
                    && !w.mActivityRecord.isAnimating(TRANSITION | PARENTS)) {
                // If this window's app token is hidden and not animating, it is of no interest.
                if (DEBUG_WALLPAPER) Slog.v(TAG, "Skipping hidden and not animating token: " + w);
                return false;
            }
        } else {
            if (w.mActivityRecord != null && !w.mActivityRecord.isVisibleRequested()) {
                // An activity that is not going to remain visible shouldn't be the target.
                return false;
            }
        }
        if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()
                + " mDrawState=" + w.mWinAnimator.mDrawState + " w.mWillReplaceWindow = " + w.mWillReplaceWindow);
        if (w.toString().contains("NotificationShade")) {
            Slog.v(TAG, "1111 Win " + w + ": isOnScreen=" + w.isOnScreen()
                    + " mDrawState=" + w.mWinAnimator.mDrawState + " w.mWillReplaceWindow = " + w.mWillReplaceWindow);
        }
        if (w.mWillReplaceWindow && mWallpaperTarget == null
                && !mFindResults.useTopWallpaperAsTarget) {
            // When we are replacing a window and there was wallpaper before replacement, we want to
            // keep the window until the new windows fully appear and can determine the visibility,
            // to avoid flickering.
            mFindResults.setUseTopWallpaperAsTarget(true);
        }

        final WindowContainer animatingContainer = w.mActivityRecord != null
                ? w.mActivityRecord.getAnimatingContainer() : null;
        final boolean keyguardGoingAwayWithWallpaper = (animatingContainer != null
                && animatingContainer.isAnimating(TRANSITION | PARENTS)
                && AppTransition.isKeyguardGoingAwayTransitOld(animatingContainer.mTransit)
                && (animatingContainer.mTransitFlags
                & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);

        boolean needsShowWhenLockedWallpaper = false;
        if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
                && mService.mPolicy.isKeyguardLocked()
                && (mService.mPolicy.isKeyguardOccluded()
                || mService.mPolicy.isKeyguardUnoccluding())) {
            // The lowest show when locked window decides whether we need to put the wallpaper
            // behind.
            needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
                    || (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());
        }

        if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
            // Keep the wallpaper during Keyguard exit but also when it's needed for a
            // non-fullscreen show when locked activity.
            mFindResults.setUseTopWallpaperAsTarget(true);
        }

        final RecentsAnimationController recentsAnimationController =
                mService.getRecentsAnimationController();
        final boolean animationWallpaper = animatingContainer != null
                && animatingContainer.getAnimation() != null
                && animatingContainer.getAnimation().getShowWallpaper();
        final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
        final boolean isRecentsTransitionTarget = (recentsAnimationController != null
                && recentsAnimationController.isWallpaperVisible(w));
        if (isRecentsTransitionTarget) {
            if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
            mFindResults.setWallpaperTarget(w);
            return true;
        } else if (hasWallpaper && w.isOnScreen()
                && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
            if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
            mFindResults.setWallpaperTarget(w);
            if (w == mWallpaperTarget && w.isAnimating(TRANSITION | PARENTS)) {
                // The current wallpaper target is animating, so we'll look behind it for
                // another possible target and figure out what is going on later.
                if (DEBUG_WALLPAPER) Slog.v(TAG,
                        "Win " + w + ": token animating, looking behind.");
            }
            // Found a target! End search.
            return true;
        }
        return false;
    };

上面最关键判断代码:

if (hasWallpaper && w.isOnScreen()
                && (mWallpaperTarget == w || w.isDrawFinishedLw()))

这里的 hasWallpaper非常关键

final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;

主要调用是WindowState的方法

boolean hasWallpaper() {
    return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
            || (mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox());
}

这里其实也就是判断window中是否有FLAG_SHOW_WALLPAPER属性,而且经过额外加log打印发现hasWallpaper值变化在锁屏window解锁前后

那么其实我们可以猜测是不是锁屏window会去动态改变自己的FLAG_SHOW_WALLPAPER属性,在有桌面显示时候锁屏的window实际是没有这个属性,在锁屏状态下是有这个属性。根据猜想去systemui代码中grep相关FLAG_SHOW_WALLPAPER关键字
果然发现有如下:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java

   private void applyKeyguardFlags(State state) {
        final boolean scrimsOccludingWallpaper =
                state.mScrimsVisibility == ScrimController.OPAQUE || state.mLightRevealScrimOpaque;
        final boolean keyguardOrAod = state.mKeyguardShowing
                || (state.mDozing && mDozeParameters.getAlwaysOn());
        if ((keyguardOrAod && !state.mBackdropShowing && !scrimsOccludingWallpaper)
                || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()) {
            // Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a
            // solid backdrop or scrim. Also, show it if we are currently animating between the
            // keyguard and the surface behind the keyguard - we want to use the wallpaper as a
            // backdrop for this animation.
            mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;
        } else {
            mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;
        }

这里其实就是代表有锁屏时候需要有 mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;
锁屏退出时清除锁屏的FLAG_SHOW_WALLPAPER
mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;文章来源地址https://www.toymoban.com/news/detail-418584.html

到了这里,关于Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 视频动态壁纸 Dynamic Wallpaper for Mac中文

    Dynamic Wallpaper是一款Mac平台上的动态壁纸应用程序,它可以根据时间等因素动态切换壁纸,提供更加生动和多样化的桌面体验。 Dynamic Wallpaper包含了多个动态壁纸,用户可以根据自己的喜好选择和切换。这些动态壁纸可以根据时间等因素进行自动切换,也可以手动进行切换。

    2024年02月10日
    浏览(64)
  • Dynamic Wallpaper for Mac:动态壁纸让桌面更生动

    Dynamic Wallpaper for Mac是一款为苹果电脑用户精心设计的动态壁纸软件,它以其丰富的功能和精美的壁纸库,为用户带来了更加生动和个性化的桌面体验。 Dynamic Wallpaper for Mac v17.8中文版下载 这款软件支持多种动态壁纸,用户可以根据自己的喜好选择和切换。这些壁纸不仅可以根

    2024年04月22日
    浏览(33)
  • Android 12.0Launcher3 去掉workspace长按弹出壁纸弹窗

    在12.0的系统开发中,在Launcher3开发中,在长按屏幕的时候,会弹出窗口,修改主屏幕配置,壁纸,等信息,由于要默认设置一些配置 不想让用户修改相关配置,这时候就需要去掉长按弹窗功能了,禁止修改相关配置 下面来分析下workspace相关长按事件的功能实现 先看workspac

    2024年02月07日
    浏览(69)
  • Android 10.0 SystemUI定制之通过系统属性控制锁屏页面通知栏显示与隐藏功能实现

    在10.0的系统产品开发中,在一些SystemUI的系统定制化开发中,在对锁屏页面的通知栏在某些情况下不需要显示通知栏,所以就需要 在systemui的通知栏布局页面中,通过属性来控制是否在锁屏页面的时候显示通知,具体就分析下systemui然后开发相关功能 在systemui系统中最主要的

    2024年02月04日
    浏览(58)
  • Android学习之路(12) setContentView详解

    setContentView我们在Activity中经常见到,它的作用就是把我们的布局文件放在Activity中显示,下面我们根据源码分析setContentView是如何做到的 注意Activity的setContentView和AppCompatActivity的setContentView是有一些区别的,所以我们要分析两钟setContentView,下面先分析Activity的 (1).从Activity的

    2024年01月17日
    浏览(38)
  • Activity启动过程详解(Android 12源码分析)

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

    2024年02月13日
    浏览(45)
  • MTK Android 14 锁屏通知栏与相机预览界面重叠

    设置为滑动解锁 支持双击power按键跳转相机功能 反复亮灭屏,并通过双击power按键唤醒相机就有几率触发此问题 keyguard壁纸图层消失,显示出了底下的camera预览界面,且当前keyguard时序错乱,解锁流程异常 因为是静态壁纸,所以最早的考虑可能和Systemui的LockscreenWallpaper.java 和

    2024年02月22日
    浏览(59)
  • Android12系统环境变量设置

    最近在移植百度Apollo Cyber通信框架至安卓系统中,发现Cyber本身依赖于环境变量来实现服务的初始化配置。相应地,我也需要在安卓系统中引入这些环境变量,并确保在Native服务启动时这些环境变量已经准备就绪。 由于此前我对环境变量的了解并不多,于是研究学习了一下

    2024年02月20日
    浏览(32)
  • Android 11.0 systemui锁屏页面时钟显示样式的定制功能实现

      在11.0的系统ROM定制化开发中,在进行systemui的相关开发中,当开机完成后在锁屏页面就会显示时间日期的功能,由于 开发产品的需求要求时间显示周几上午下午接下来就需要对锁屏显示时间日期的相关布局进行分析,然后实现相关功能 效果图如图: SystemUI作为整个系统的基

    2024年02月04日
    浏览(83)
  • android 12.0 屏蔽系统所有通知

    在12.0的产品开发中最近公司项目要求 屏蔽系统所有通知 不需要在下拉状态栏显示通知功能实现 要控制系统通知的开关功能,需要屏蔽系统通知,而系统通知都是由NoticationManagerServices.java来管理的, 这个NMS服务管理通知就需要在NotificationManagerService.java 来实现需求 在系统中,

    2024年02月06日
    浏览(63)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包