Android修改横屏的默认角度

本文介绍如何在Android系统中调整屏幕默认旋转角度,并解释了通过修改特定布尔值来实现顺时针与逆时针旋转切换的方法。

默认的横屏角度是顺时针90度,修改为顺时针270度,即是逆时针90度。


1.查看相关逻辑,可以看到有个布尔值com.android.internal.R.bool.config_reverseDefaultRotation控制翻转:

frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

  @Override
    public void setInitialDisplaySize(Display display, int width, int height, int density) {
        // This method might be called before the policy has been fully initialized
        // or for other displays we don't care about.
        if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) {
            return;
        }
        mDisplay = display;

        final Resources res = mContext.getResources();
        int shortSize, longSize;
        if (width > height) {
            shortSize = height;
            longSize = width;
            mLandscapeRotation = Surface.ROTATION_0;
            mSeascapeRotation = Surface.ROTATION_180;
            if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
                mPortraitRotation = Surface.ROTATION_90;
                mUpsideDownRotation = Surface.ROTATION_270;
            } else {
                mPortraitRotation = Surface.ROTATION_270;
                mUpsideDownRotation = Surface.ROTATION_90;
            }
        } else {
            shortSize = width;
            longSize = height;
            mPortraitRotation = Surface.ROTATION_0;
            mUpsideDownRotation = Surface.ROTATION_180;
            if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
                mLandscapeRotation = Surface.ROTATION_270;
                mSeascapeRotation = Surface.ROTATION_90;
            } else {
                mLandscapeRotation = Surface.ROTATION_90;
                mSeascapeRotation = Surface.ROTATION_270;
            }
        }

        mStatusBarHeight =
                res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);

        // Height of the navigation bar when presented horizontally at bottom
        mNavigationBarHeightForRotation[mPortraitRotation] =
        mNavigationBarHeightForRotation[mUpsideDownRotation] =
                res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
        mNavigationBarHeightForRotation[mLandscapeRotation] =
        mNavigationBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
                com.android.internal.R.dimen.navigation_bar_height_landscape);

        // Width of the navigation bar when presented vertically along one side
        mNavigationBarWidthForRotation[mPortraitRotation] =
        mNavigationBarWidthForRotation[mUpsideDownRotation] =
        mNavigationBarWidthForRotation[mLandscapeRotation] =
        mNavigationBarWidthForRotation[mSeascapeRotation] =
                res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);

        // SystemUI (status bar) layout policy
        int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
        int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;

        // Allow the navigation bar to move on small devices (phones).
        
        /// M: read the critical dp from mtk resource @{
        //mNavigationBarCanMove = shortSizeDp < 600;
        mNavigationBarCanMove = shortSizeDp < mContext.getResources().getInteger(
            com.mediatek.internal.R.integer.config_dp_for_rotation);
        /// @}
        mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);

        /// M:[SmartBook]Don't show navigation bar if SmartBook plugged in @{
        if (FeatureOption.MTK_SMARTBOOK_SUPPORT) {
            mNavigationBarCanMove = false;
            mHasNavigationBar = mSmartBookPlugIn ? false : mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_showNavigationBar);
            Slog.d(TAG, "mSmartBookPlugIn:" + mSmartBookPlugIn + ", mHasNavigationBar:" + mHasNavigationBar);
        }
        /// @}

        // Allow a system property to override this. Used by the emulator.
        // See also hasNavigationBar().
        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
        if ("1".equals(navBarOverride)) {
            mHasNavigationBar = false;
        } else if ("0".equals(navBarOverride)) {
            mHasNavigationBar = true;
        }

        // For demo purposes, allow the rotation of the HDMI display to be controlled.
        // By default, HDMI locks rotation to landscape.
        if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
            mDemoHdmiRotation = mPortraitRotation;
        } else {
            mDemoHdmiRotation = mLandscapeRotation;
        }
        mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);

        // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
        // http://developer.android.com/guide/practices/screens_support.html#range
        mForceDefaultOrientation = longSizeDp >= 960 && shortSizeDp >= 720 &&
                res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
                // For debug purposes the next line turns this feature off with:
                // $ adb shell setprop config.override_forced_orient true
                // $ adb shell wm size reset
                !"true".equals(SystemProperties.get("config.override_forced_orient"));
    }


修改:frameworks/base/core/res/res/values/config.xml

<!-- If true, the direction rotation is applied to get to an application's requested
         orientation is reversed.  Normally, the model is that landscape is
         clockwise from portrait; thus on a portrait device an app requesting
         landscape will cause a clockwise rotation, and on a landscape device an
         app requesting portrait will cause a counter-clockwise rotation.  Setting
         true here reverses that logic. -->
    <bool name="config_reverseDefaultRotation">true</bool>
<think>我们正在处理一个关于在RK Android 13设备上设置默认横屏的问题。根据提供的引用,我们可以从两个角度考虑: 引用[1]提到了在recovery_ui/screen_ui.cpp中修改代码,通过检测DP状态来设置横屏(ROTATION_RIGHT)。但这是在Recovery模式下的修改。 引用[2]提到在Android 11.0上,在SurfaceFlinger的构造函数中修改,这属于系统框架层的修改。 由于用户要求的是Android 13,我们可能需要从系统框架层入手。在Android中,屏幕旋转的设置通常涉及以下几个部分: 1. 系统属性(ro.surface_flinger.primary_display_orientation)可以设置默认方向。 2. 在SurfaceFlinger中设置初始方向。 但是,Android 13可能有一些变化,我们需要确认当前版本的最佳实践。 根据引用[2]的做法,在SurfaceFlinger的构造函数中设置默认方向。我们可以尝试类似的方法。 步骤: 1. 在SurfaceFlinger的构造函数中,设置默认方向为横屏(例如,ROTATION_90或ROTATION_270)。 2. 或者通过系统属性设置。 具体方法: 方法一:通过系统属性(推荐,因为可以避免修改代码重新编译系统) 在设备对应的system.prop或者build.prop中添加: ro.surface_flinger.primary_display_orientation=Orientation.ROTATION_90 但是,根据Android文档,这个属性在Android 11之后可能不再使用。我们需要确认。 方法二:修改SurfaceFlinger的代码。 在SurfaceFlinger的初始化过程中,设置初始方向。我们可以参考引用[2]的做法,在SurfaceFlinger的构造函数中修改。 具体代码位置(以Android 13代码为例): frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 在SurfaceFlinger的构造函数中,我们可以尝试设置默认方向。 但是,请注意,在Android 13中,屏幕方向的设置可能已经改变。我们可以查找SurfaceFlinger中设置屏幕方向的地方。 另一种常见做法是修改DisplayDevice的创建过程,因为DisplayDevice会设置初始方向。 在SurfaceFlinger.cpp中,创建主显示设备时,会使用一个初始方向。这个初始方向通常是从配置中读取的,如果没有配置则使用默认值(ROTATION_0)。 我们可以尝试修改这个初始方向: 查找代码中创建主显示设备的地方,通常是在`SurfaceFlinger::init()`方法中,调用`setupNewDisplayDeviceInternal`函数时,会传递一个初始的显示状态,其中包含方向。 但是,为了更准确地修改,我们可以考虑在设备树中覆盖默认方向。在设备树文件中,设置默认方向。 然而,RK平台可能提供了自己的设置方式。我们可以参考RK的文档或现有设备的配置。 根据经验,RK平台在Android 11之后,可以通过以下方式设置: 在device/rockchip/common/device.mk中,添加系统属性: PRODUCT_PROPERTY_OVERRIDES += ro.sf.default_rotation=1 其中,ro.sf.default_rotation的值含义: 0:竖屏(Portrait) 1:横屏(Landscape),即旋转90度 2:倒屏(Portrait upside down) 3:另一个横屏(Landscape,旋转270度) 所以,设置为1或3都可以是横屏。 但是,在Android 13中,这个属性可能仍然有效。 如果上述属性无效,我们可以尝试修改SurfaceFlinger的代码。 修改SurfaceFlinger.cpp(以Android 13为例): 在SurfaceFlinger::initializeDisplays()函数中,我们可以找到设置初始方向的代码。 例如,在initializeDisplays()中,会创建一个DisplayState对象,并设置其方向。我们可以修改横屏方向。 但是,请注意,这个函数可能会被多次调用,我们需要确保在设置主显示时使用我们想要的方向。 具体代码修改示例(需要根据实际代码调整): 在`SurfaceFlinger::initializeDisplays()`函数中,找到设置主显示状态的部分,例如: ```cpp // set the initial display state sp<IBinder> token = new BBinder(); DisplayState state; state.what = DisplayState::eDisplayProjectionChanged | DisplayState::eLayerStackChanged; state.layerStack = ui::DEFAULT_LAYER_STACK; state.orientation = ui::ROTATION_0; // 这里修改为ui::ROTATION_90 state.frame = Rect(displayWidth, displayHeight); state.viewport = Rect(displayWidth, displayHeight); state.width = displayWidth; state.height = displayHeight; ``` 将state.orientation修改为ui::ROTATION_90(横屏)。 但是,需要注意的是,displayWidth和displayHeight的值可能也需要根据方向调整。因为横屏时,宽高需要交换。 但是,在初始化时,displayWidth和displayHeight是从显示设备获取的物理宽高(通常是竖屏的宽高)。如果我们设置方向为横屏,那么实际上显示的画面会旋转90度,因此我们需要确保宽高值正确。 实际上,在创建DisplayDevice时,会根据方向调整宽高。所以,我们只需要修改方向即可。 然而,这种方法需要修改系统服务,并且需要重新编译系统。 考虑到用户可能希望避免重新编译系统,我们首先建议尝试系统属性。 总结: 建议尝试以下步骤: 1. 在设备的system.prop中添加: ro.sf.default_rotation=1 # 或者3,取决于需要横屏的方向 或者 ro.surface_flinger.primary_display_orientation=90 # 或者270 2. 如果上述属性无效,则修改SurfaceFlinger的代码,在initializeDisplays()中设置初始方向为ROTATION_90(或ROTATION_270)。 3. 重新编译系统并刷机。 注意:由于Android 13可能变化,以上方法需要根据实际情况调整。 另外,引用[1]中Recovery模式的修改方法(screen_ui.cpp)是针对Recovery界面的,如果用户也需要Recovery界面横屏,则需要修改Recovery的代码。 因此,我们分两部分: - 正常系统:修改系统属性或SurfaceFlinger - Recovery:修改recovery_ui/screen_ui.cpp(如引用[1]所示) 下面,我们针对正常系统给出两种具体方法(以属性方式优先)。 方法一(属性方式): 在设备mk文件中(例如device/rockchip/rk3568/system.prop)添加: ro.sf.default_rotation=1 方法二(代码修改): 修改frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp中的initializeDisplays函数,将初始方向设置为ROTATION_90。 由于我们无法确定用户设备的具体情况,这里提供两种方法供选择。 相关问题: 1. 如何修改Android设备的默认屏幕方向? 2.Android 13中,ro.sf.default_rotation属性是否仍然有效? 3. 如何为RK设备的Recovery模式设置横屏? 4. 修改SurfaceFlinger代码后如何重新编译并刷机? 5. 如何验证默认屏幕方向设置成功?</think>在 RK Android 13 设备上设置默认横屏,可通过修改系统属性和底层代码实现。以下是具体方法: ### 方法一:通过系统属性设置(推荐) 在设备的 `system.prop` 或 `build.prop` 中添加以下属性: ```properties # 设置默认横屏(ROTATION_RIGHT 表示向右旋转90度) ro.surface_flinger.primary_display_orientation=ROTATION_RIGHT ``` **操作步骤**: 1. 解压设备镜像,定位到 `device/rockchip/common/` 目录下的 `system.prop` 文件 2. 添加上述属性行 3. 重新编译系统并刷机 ### 方法二:修改 SurfaceFlinger 代码 在系统框架层修改显示方向(参考引用[2]): 1. 修改文件: `frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp` 2. 在 `SurfaceFlinger::SurfaceFlinger()` 构造函数中初始化显示方向: ```cpp SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) { // 添加默认横屏设置 mPrimaryDisplayOrientation = DisplayState::eOrientation90; // 90度横屏 } ``` ### 方法三:动态检测显示状态(针对特殊场景) 若需根据外接显示设备状态动态调整(参考引用[1]): ```cpp // 在显示初始化代码中添加检测逻辑 char dp_status[128] = "disconnected"; int fd = open("/sys/class/drm/card0-eDP-1/status", O_RDONLY); if (fd != -1) { read(fd, dp_status, sizeof(dp_status)); close(fd); if (strncmp(dp_status, "connected", 9) == 0) { setDisplayOrientation(ROTATION_RIGHT); // 强制横屏 } } ``` ### 验证方法 刷机后通过 ADB 检查当前显示方向: ```bash adb shell dumpsys display | grep mOrientation # 输出应为:mOrientation=ROTATION_90 ``` ### 注意事项 1. **横屏方向值**: - `ROTATION_0`:竖屏 - `ROTATION_90`:向右横屏(常用) - `ROTATION_270`:向左横屏 2. **兼容性**:RK3568/RK3588 等平台需确认显示接口路径(如 `/sys/class/drm/card0-HDMI-A-1/status`) 3. **Recovery模式**:需单独修改 `recovery_ui/screen_ui.cpp`(如引用[1]所示) > 建议优先使用方法一,通过系统属性实现更安全。若需深度定制再考虑代码修改[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值