Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher

04-09 阅读 0评论

1 原理说明

开机以后,设备会有一个“android正在启动”这样的弹框,这个界面是一个叫FallbackHome的Activity来展示的。FallbackHome机制是Android系统启动过程中的一种降级处理机制。当系统启动时,如果默认的Launcher应用无法正常加载或出现错误,系统会自动启用FallbackHome来替代默认Launcher。但一般为了改善产品体验,最终决定移除弹窗页面,直接进入默认的Launcher,避免弹窗对用户界面的干扰。具体而言,FallbackHome机制包括以下内容:

Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher,Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,修改,错误,解决方案,第1张
(图片来源网络,侵删)
  • 默认Launcher故障检测:系统会检测默认的Launcher应用是否能够正常加载和运行。如果检测到故障,系统将启动FallbackHome。
  • 解锁过程中的弹窗:在系统解锁之前,可能会出现一个"Android正在启动"的弹窗页面,用于指示系统正在加载和准备。这个弹窗页面通常出现在桌面壁纸上,用户需要等待系统完全解锁后才能进入默认的Launcher。

    去掉FallbackHome的效果实际上是让FallbackHome的view不显示,然后开机启动动画延长一下,直到系统解锁后再停止开机动画,完成这样较为顺滑的过渡。

    2 修改方案(Android Q R S)

    具体修改方案如下(这里以S版本修改为主,Q和R有一些差异但原理不变):

    @1 修改文件为:AOSP/packages/apps/Settings$ vim src/com/android/settings/FallbackHome.java,目的为FallbackHome不显示View,所以注释掉。修改内容为:

    public class FallbackHome extends Activity {
        private static final String TAG = "FallbackHome";
        private static final int PROGRESS_TIMEOUT = 2000;
        private boolean mProvisioned;
        private WallpaperManager mWallManager;
        private final Runnable mProgressTimeoutRunnable = () -> {
            //AGS add start
            //不显示任何内容,如果是黑色衔接,直接改这里就足够了,如果不是则需要 2,3步骤内容的修改
            /*  View v = getLayoutInflater().inflate(
                    R.layout.fallback_home_finishing_boot, null);
            setContentView(v);
            v.setAlpha(0f);
            v.animate()
                    .alpha(1f)
                    .setDuration(500)
                    .setInterpolator(AnimationUtils.loadInterpolator(
                            this, android.R.interpolator.fast_out_slow_in))
                    .start();*/
            //AGS add end
            getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
        };
        //...
    }

    @2 修改文件为:AOSP/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java,目的为播放完开机动画后不退出开机动画,所以注释掉即可。修改内容为:

    public class WindowManagerService extends IWindowManager.Stub
            implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
        //...
        private void performEnableScreen() {
            synchronized (mGlobalLock) {
                ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b"
                                + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b"
                                + " mSystemBooted=%b mOnlyCore=%b. %s", mDisplayEnabled,
                        mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore,
                        new RuntimeException("here").fillInStackTrace());
                if (mDisplayEnabled) {
                    return;
                }
                if (!mSystemBooted && !mShowingBootMessages) {
                    return;
                }
                if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {
                    return;
                }
                // Don't enable the screen until all existing windows have been drawn.
                if (!mForceDisplayEnabled) {
                    if (mBootWaitForWindowsStartTime = 0; i--) {
                        if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) {
                            return;
                        }
                    }
                    long waitTime = SystemClock.elapsedRealtime() - mBootWaitForWindowsStartTime;
                    mBootWaitForWindowsStartTime = -1;
                    if (waitTime > 10) {
                        ProtoLog.i(WM_DEBUG_BOOT,
                                "performEnableScreen: Waited %dms for all windows to be drawn",
                                waitTime);
                    }
                }
    	    //AGS add start
    	    //播放完开机动画后不退出开机动画,注释掉如下代码即可。
    	    /*
                if (!mBootAnimationStopped) {
                    Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
                    // stop boot animation
                    // formerly we would just kill the process, but we now ask it to exit so it
                    // can choose where to stop the animation.
                    SystemProperties.set("service.bootanim.exit", "1");
                    mBootAnimationStopped = true;
                }
                if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
                    ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete");
                    return;
                }
                try {
                    IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                    if (surfaceFlinger != null) {
                        ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                        Parcel data = Parcel.obtain();
                        data.writeInterfaceToken("android.ui.ISurfaceComposer");
                        surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
                                data, null, 0);
                        data.recycle();
                    }
                } catch (RemoteException ex) {
                    ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");
                }
                */
                //AGS add end
                EventLogTags.writeWmBootAnimationDone(SystemClock.uptimeMillis());
                Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
                mDisplayEnabled = true;
                ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!");
                // Enable input dispatch.
                mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled);
            }
            try {
                mActivityManager.bootAnimationComplete();
            } catch (RemoteException e) {
            }
            mPolicy.enableScreenAfterBoot();
    	// Make sure the last requested orientation has been applied.
            updateRotationUnchecked(false, false);
        }
        //...
    }

    @3 修改文件为:AOSP/frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java,目的为解锁后再结束开机动画。修改内容为:

    public final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
    /** Called when the windows associated app window container are drawn. */
        //...
        private void onWindowsDrawn(long timestampNs) {
            if (mPerf != null && perfActivityBoostHandler > 0) {
                mPerf.perfLockReleaseHandler(perfActivityBoostHandler);
                perfActivityBoostHandler = -1;
            } else if (perfActivityBoostHandler > 0) {
                Slog.w(TAG, "activity boost didn't release as expected");
            }
            final TransitionInfoSnapshot info = mTaskSupervisor
                    .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs);
            final boolean validInfo = info != null;
            final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY;
            final @WaitResult.LaunchState int launchState =
                    validInfo ? info.getLaunchState() : WaitResult.LAUNCH_STATE_UNKNOWN;
            // The activity may have been requested to be invisible (another activity has been launched)
            // so there is no valid info. But if it is the current top activity (e.g. sleeping), the
            // invalid state is still reported to make sure the waiting result is notified.
            if (validInfo || this == getDisplayArea().topRunningActivity()) {
                mTaskSupervisor.reportActivityLaunched(false /* timeout */, this,
                        windowsDrawnDelayMs, launchState);
            }
            finishLaunchTickingLocked();
            if (task != null) {
                task.setHasBeenVisible(true);
            }
            //AGS add start
            if (isHomeIntent(intent) && shortComponentName != null && !shortComponentName.contains("FallbackHome")) {
                SystemProperties.set("service.bootanim.exit", "1");
    	    //这里就是将上面注掉的代码copy过来
                try {
                    IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                    if (surfaceFlinger != null) {
                        Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                        Parcel data = Parcel.obtain();
                        data.writeInterfaceToken("android.ui.ISurfaceComposer");
                        surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
                                data, null, 0);
                        data.recycle();
                    }
                } catch (RemoteException ex) {
                    Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
                }
            }
            //AGS add end
            mLaunchRootTask = null;
        }
        //...
    }
    Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher,Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,修改,错误,解决方案,第2张
    (图片来源网络,侵删)
    Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher,Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,修改,错误,解决方案,第3张
    (图片来源网络,侵删)

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]