RK3288 android7.1.2 使UI 界面旋转任意角度

本文详细介绍了如何在RK3288设备上,基于android7.1.2系统实现UI界面旋转30度。涉及从Java层到C++层的多个关键文件修改,包括添加30度旋转选项、调整WindowManagerService、PhoneWindowManager等核心组件代码,以及SurfaceFlinger和InputManagerService等相关服务的更新。
摘要由CSDN通过智能技术生成

 

以旋转30度为例,从app 开始修改:

java层:

1.添加30度变量

路径:frameworks\base\core\java\android\view\Surface.java

    /** @hide */
    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Rotation {}

    /**
     * Rotation constant: 0 degree rotation (natural orientation)
     */
    public static final int ROTATION_0 = 0;

    /**
     * Rotation constant: 90 degree rotation.
     */
    public static final int ROTATION_90 = 1;

    /**
     * Rotation constant: 180 degree rotation.
     */
    public static final int ROTATION_180 = 2;

    /**
     * Rotation constant: 270 degree rotation.
     */
    public static final int ROTATION_270 = 3;

        /**
     * Rotation constant: any degree rotation.
     */
    /* navy */
    public static final int ROTATION_30 = 8;


    /**
     * Returns a human readable representation of a rotation.
     *
     * @param rotation The rotation.
     * @return The rotation symbolic name.
     *
     * @hide
     */
    public static String rotationToString(int rotation) {
        switch (rotation) {
            case Surface.ROTATION_0: {
                return "ROTATION_0";
            }
            case Surface.ROTATION_90: {
                return "ROATATION_90";
            }
            case Surface.ROTATION_180: {
                return "ROATATION_180";
            }
            case Surface.ROTATION_270: {
                return "ROATATION_270";
            /* navy */
            }case Surface.ROTATION_30: {
                return "ROATATION_30";
            }
            default: {
                throw new IllegalArgumentException("Invalid rotation: " + rotation);
            }
        }
    }





2.添加30度菜单选项

UI:Settings->Display->HDMI->HDMI Rotation

1)路径:packages\apps\Settings\res\values\arrays.xml

    <string-array name="hdmi_rotation_entries">
        <item>0</item>
        <!-- navy-->
        <item>30</item>
        <item>90</item>
        <item>180</item>
        <item>270</item>
    </string-array>
    <string-array name="hdmi_rotation_values">
        <item>0</item>
        <!-- navy-->
        <item>30</item>
        <item>90</item>
        <item>180</item>
        <item>270</item>
    </string-array>

2)路径:packages\apps\Settings\src\com\android\settings\HdmiSettings.java

 @Override
    public boolean onPreferenceChange(Preference preference, Object obj) {
        Log.i(TAG, "onPreferenceChange:" + obj);
        String key = preference.getKey();
        Log.d(TAG, key);
        if(preference == mHdmiResolution) {
            if (KEY_HDMI_RESOLUTION.equals(key)) {
                if (obj.equals(mOldResolution))
                    return true;
                int index = mHdmiResolution.findIndexOfValue((String) obj);
                Log.i(TAG, "onPreferenceChange: index= " + index);
                mDisplayInfo = getDisplayInfo();
                if (mDisplayInfo != null) {
                    DrmDisplaySetting.setDisplayModeTemp(mDisplayInfo, index);
                    showConfirmSetModeDialog();
                }
            }
         } else if (preference == mHdmiRotation) {
            if (KEY_HDMI_ROTATION.equals(key)) {
                try {
                    int value = Integer.parseInt((String) obj);
                    android.os.SystemProperties.set("persist.sys.orientation", (String) obj);
                    Log.d(TAG,"freezeRotation~~~value:"+(String) obj);
                    if(value == 0)
                        wm.freezeRotation(Surface.ROTATION_0);
                    else if(value == 90)
                        wm.freezeRotation(Surface.ROTATION_90);
                    else if(value == 180)
                        wm.freezeRotation(Surface.ROTATION_180);
                    else if(value == 270)
                        wm.freezeRotation(Surface.ROTATION_270);
                    /* navy */
                    else if(value == 30){ 
                        Log.d(TAG,"freezeRotation~~~Surface.ROTATION_30:"+ Surface.ROTATION_30);
                        wm.freezeRotation(Surface.ROTATION_30);
                    }
                       
                    else
                         return true;
                //android.os.SystemProperties.set("sys.boot_completed", "1");
                } catch (Exception e) {
                      Log.e(TAG, "freezeRotation error");
                }
            }
	    } else if (preference == mHdmiDualScreen) {
            android.provider.Settings.System.putInt(getActivity().getContentResolver(),DOUBLE_SCREEN_CONFIG,(Boolean)obj?1:0);
            SystemProperties.set("persist.orientation.vhinit", "0");
            SystemProperties.set("persist.orientation.vhshow", "false");
            mHdmiDualScreenVH.setEnabled((Boolean)obj);
            mHdmiDualScreenVH.setChecked(false);
            mHdmiDualScreenList.setEnabled(false);
            this.finish();
	    } else if (preference == mHdmiDualScreenVH) {
            if((Boolean)obj) {
                SystemProperties.set("persist.orientation.vhshow", "true");   
                mHdmiDualScreenList.setEnabled(true);
            } else {
                SystemProperties.set("persist.orientation.vhshow", "false");   
                mHdmiDualScreenList.setEnabled(false);
                SystemProperties.set("persist.orientation.vhinit", "0");
            }
            SystemProperties.set("persist.orientation.vhinit", "0");
	    } else if (preference == mHdmiDualScreenList) {
            if("0".equals(obj.toString())) {
                SystemProperties.set("persist.orientation.vhinit", "0");
            } else if ("1".equals(obj.toString())) {
                SystemProperties.set("persist.orientation.vhinit", "1");
            }
        }
        return true;
    }

3)设定30度

路径:packages\apps\Settings\src\com\android\settings\HdmiSettings.java

    private void init() {
        mIsUseDisplayd = SystemProperties.getBoolean("ro.rk.displayd.enable", false);

        //init hdmi rotation
        try {
             wm = IWindowManager.Stub.asInterface(
                  ServiceManager.getService(Context.WINDOW_SERVICE));
             int rotation = wm.getRotation();
             switch (rotation) {
                  case Surface.ROTATION_0:
                       mHdmiRotation.setValue("0");
                       break;
                  case Surface.ROTATION_90:
                       mHdmiRotation.setValue("90");
                       break;
                  case Surface.ROTATION_180:
                       mHdmiRotation.setValue("180");
                       break;
                  case Surface.ROTATION_270:
                       mHdmiRotation.setValue("270");
                       break;
                  /* navy */  
                  case Surface.ROTATION_30:
                       mHdmiRotation.setValue("30");
                       break;
                  default:
                       mHdmiRotation.setValue("0");
                }
            } catch (Exception e) {
                Log.e(TAG, e.toString());
            }
    }

3.修改WindowManagerService.java 中相关code

路径:frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java

 @Override
    public void freezeRotation(int rotation) {
        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                "freezeRotation()")) {
            throw new SecurityException("Requires SET_ORIENTATION permission");
        }
        /* navy */
        if (rotation < -1 || rotation > Surface.ROTATION_30) {
            throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
                    + "rotation constant.");
        }

        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: mRotation=" + mRotation);
        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: rotation=" + rotation);
        long origId = Binder.clearCallingIdentity();
        try {
            mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
                    rotation == -1 ? mRotation : rotation);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: mRotation1111111=" + mRotation);
        updateRotationUnchecked(false, false);
    }


  @Override
    public int getPreferredOptionsPanelGravity() {
        synchronized (mWindowMap) {
            final int rotation = getRotation();

            // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
            final DisplayContent displayContent = getDefaultDisplayContentLocked();
            if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
                // On devices with a natural orientation of portrait
                switch (rotation) {
                    default:
                    case Surface.ROTATION_0:
                    /* navy */
                    case Surface.ROTATION_30:
                        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
                    case Surface.ROTATION_90:
                        return Gravity.RIGHT | Gravity.BOTTOM;
                    case Surface.ROTATION_180:
                        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
                    case Surface.ROTATION_270:
                        return Gravity.START | Gravity.BOTTOM;
                }
            }

            // On devices with a natural orientation of landscape
            switch (rotation) {
                default:
                case Surface.ROTATION_0:
                /* navy */
                case Surface.ROTATION_30:
                    return Gravity.RIGHT | Gravity.BOTTOM;
                case Surface.ROTATION_90:
                    return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
                case Surface.ROTATION_180:
                    return Gravity.START | Gravity.BOTTOM;
                case Surface.ROTATION_270:
                    return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
            }
        }
    }



private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
                  int uiMode, int dw, int dh, float density, Configuration outConfig) {
        // TODO: Multidisplay: for now only use with default display.

        // We need to determine the smallest width that will occur under normal
        // operation.  To this, start with the base screen size and compute the
        // width under the different possible rotations.  We need to un-rotate
        // the current screen dimensions before doing this.
        int unrotDw, unrotDh;
        if (rotated) {
            unrotDw = dh;
            unrotDh = dw;
        } else {
            unrotDw = dw;
            unrotDh = dh;
        }
        displayInfo.smallestNominalAppWidth = 1<<30;
        displayInfo.smallestNominalAppHeight = 1<<30;
        displayInfo.largestNominalAppWidth = 0;
        displayInfo.largestNominalAppHeight = 0;
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, uiMode, unrotDw, unrotDh);
        /* navy */
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_30, uiMode, unrotDw, unrotDh);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, uiMode, unrotDh, unrotDw);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, uiMode, unrotDw, unrotDh);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, uiMode, unrotDh, unrotDw);
        int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode);
        /* navy */
        sl = reduceConfigLayout(sl, Surface.ROTATION_30, density, unrotDw, unrotDh, uiMode);
        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
        outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
        outConfig.screenLayout = sl;
    }

    private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
            DisplayMetrics dm, int dw, int dh) {
        // TODO: Multidisplay: for now only use with default display.
        dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode);
        dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode);
        float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
        int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
        if (curSize == 0 || size < curSize) {
            curSize = size;
        }
        return curSize;
    }

    private int computeCompatSmallestWidth(boolean rotated, int uiMode, DisplayMetrics dm, int dw, int dh) {
        // TODO: Multidisplay: for now only use with default display.
        mTmpDisplayMetrics.setTo(dm);
        final DisplayMetrics tmpDm = mTmpDisplayMetrics;
        final int unrotDw, unrotDh;
        if (rotated) {
            unrotDw = dh;
            unrotDh = dw;
        } else {
            unrotDw = dw;
            unrotDh = dh;
        }
        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh);
        /* navy */
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_30, uiMode, tmpDm, unrotDh, unrotDw);
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw);
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh);
        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw);
        return sw;
    }

4.修改PhoneWindowManager.java 中相关code

路径:frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

    /* navy :扩展数组长度*/
    int[] mNavigationBarHeightForRotationDefault = new int[10];
    int[] mNavigationBarWidthForRotationDefault = new int[10];
    int[] mNavigationBarHeightForRotationInCarMode = new int[10];
    int[] mNavigationBarWidthForRotationInCarMode = new int[10];

    int mLandscapeRotation = 0;  // default landscape rotation
    int mSeascapeRotation = 0;   // "other" landscape rotation, 180 degrees from mLandscapeRotation
    int mPortraitRotation = 0;   // default portrait rotation
    int mUpsideDownRotation = 0; // "other" portrait rotation
    /* navy */
    int mAnyRotation = 0; // "other" portrait rotation

  @Override
    public void onConfigurationChanged() {
        final Resources res = mContext.getResources();

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

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

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

        if (ALTERNATE_CAR_MODE_NAV_SIZE) {
            // Height of the navigation bar when presented horizontally at bottom
            mNavigationBarHeightForRotationInCarMode[mPortraitRotation] =
            mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] =
                    res.getDimensionPixelSize(
                            com.android.internal.R.dimen.navigation_bar_height_car_mode);
            mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] =
            mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = 
            mNavigationBarHeightForRotationInCarMode[mAnyRotation] = 
                    res.getDimensionPixelSize(
                        com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode);

            // Width of the navigation bar when presented vertically along one side
            mNavigationBarWidthForRotationInCarMode[mPortraitRotation] =
            mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] =
            mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] =
            mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] =
            mNavigationBarWidthForRotationInCarMode[mAnyRotation] =
                    res.getDimensionPixelSize(
                            com.android.internal.R.dimen.navigation_bar_width_car_mode);
        }
    }
        // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we
        // need to provide information to the clients that want to pretend that you can draw there.
        // We only want to apply outsets to certain types of windows. For example, we never want to
        // apply the outsets to floating dialogs, because they wouldn't make sense there.
        final boolean useOutsets = shouldUseOutsets(attrs, fl);
        if (isDefaultDisplay && useOutsets) {
            osf = mTmpOutsetFrame;
            osf.set(cf.left, cf.top, cf.right, cf.bottom);
            int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
            if (outset > 0) {
                int rotation = mDisplayRotation;
                //if (rotation == Surface.ROTATION_0) {
                /* navy */
                if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_30) {
                    osf.bottom += outset;
                } else if (rotation == Surface.ROTATION_90) {
                    osf.right += outset;
                } else if (rotation == Surface.ROTATION_180) {
                    osf.top -= outset;
         
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值