android 修改UI默认屏幕方向

1. modify WindowManagerService.java
    /**

     * Updates the current rotation.

     *

     * Returns true if the rotation has been changed.  In this case YOU

     * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.

     */

    public boolean updateRotationUncheckedLocked(boolean inTransaction) {

		alog("updateRotationUncheckedLocked");

        if (mDeferredRotationPauseCount > 0) {

            // Rotation updates have been paused temporarily.  Defer the update until

            // updates have been resumed.

            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");

            return false;

        }



        ScreenRotationAnimation screenRotationAnimation =

                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);

        if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {

            // Rotation updates cannot be performed while the previous rotation change

            // animation is still in progress.  Skip this update.  We will try updating

            // again after the animation is finished and the display is unfrozen.

            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");

            return false;

        }



        if (!mDisplayEnabled) {

            // No point choosing a rotation if the display is not enabled.

            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");

            return false;

        }



        // TODO: Implement forced rotation changes.

        //       Set mAltOrientation to indicate that the application is receiving

        //       an orientation that has different metrics than it expected.

        //       eg. Portrait instead of Landscape.



        int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);

        boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(

                mForcedAppOrientation, rotation);



        if (DEBUG_ORIENTATION) {

            Slog.v(TAG, "Application requested orientation "

                    + mForcedAppOrientation + ", got rotation " + rotation

                    + " which has " + (altOrientation ? "incompatible" : "compatible")

                    + " metrics");

        }



        if (mRotateOnBoot) {

             mRotation = Surface.ROTATION_0;

             rotation = Surface.ROTATION_90;//AnsonCode default is 0, but if tablet should be Surface.ROTATION_90

        }



        if (!mRotateOnBoot/****AnsonCode for exec onBoot.*****/ && mRotation == rotation && mAltOrientation == altOrientation) {

            // No change.

            return false;

        }



        if (Math.abs(mRotation - rotation) == 2) {

            mMirrorOrientation = true;

            final WindowList windows = getDefaultWindowListLocked();

            final int N = windows.size();

            for (int i = 0; i < N; i++) {

                WindowState ws = windows.get(i);

                ws.mWinAnimator.mMirrorOrientation = true;

            }

        }



        if (DEBUG_ORIENTATION) {

            Slog.v(TAG,

                "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")

                + " from " + mRotation + (mAltOrientation ? " (alt)" : "")

                + ", forceApp=" + mForcedAppOrientation);

        }



        mRotation = rotation;

        mAltOrientation = altOrientation;

        mPolicy.setRotationLw(mRotation);



        mWindowsFreezingScreen = true;

        mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);

        mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),

                WINDOW_FREEZE_TIMEOUT_DURATION);

        mWaitingForConfig = true;

        getDefaultDisplayContentLocked().layoutNeeded = true;

        startFreezingDisplayLocked(inTransaction, 0, 0);

        // startFreezingDisplayLocked can reset the ScreenRotationAnimation.

        screenRotationAnimation =

                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);



        if (mRotateOnBoot) {

            try {

                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");

                if (surfaceFlinger != null) {

                    //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");

                    Parcel data = Parcel.obtain();

                    data.writeInterfaceToken("android.ui.ISurfaceComposer");

                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,

                                            data, null, 0);

                    data.recycle();

                }

            } catch (RemoteException ex) {

                Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");

            }

            // Waiting for boot animation to finish;

            SystemClock.sleep(1000);

        }

        // We need to update our screen size information to match the new

        // rotation.  Note that this is redundant with the later call to

        // sendNewConfiguration() that must be called after this function

        // returns...  however we need to do the screen size part of that

        // before then so we have the correct size to use when initializing

        // the rotation animation for the new rotation.

        computeScreenConfigurationLocked(null);



        final DisplayContent displayContent = getDefaultDisplayContentLocked();

        final DisplayInfo displayInfo = displayContent.getDisplayInfo();

        if (!inTransaction) {

            if (SHOW_TRANSACTIONS) {

                Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");

            }

            Surface.openTransaction();

        }

        try {

            // NOTE: We disable the rotation in the emulator because

            //       it doesn't support hardware OpenGL emulation yet.

            if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null

                    && screenRotationAnimation.hasScreenshot()) {

                if (screenRotationAnimation.setRotationInTransaction(

                        rotation, mFxSession,

                        MAX_ANIMATION_DURATION, mTransitionAnimationScale,

                        displayInfo.logicalWidth, displayInfo.logicalHeight)) {

                    updateLayoutToAnimationLocked();

                }

            }



            mDisplayManagerService.performTraversalInTransactionFromWindowManager();

        } finally {

            if (!inTransaction) {

                Surface.closeTransaction();

                if (SHOW_LIGHT_TRANSACTIONS) {

                    Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");

                }

            }

        }



        final WindowList windows = displayContent.getWindowList();

        for (int i = windows.size() - 1; i >= 0; i--) {

            WindowState w = windows.get(i);

            if (w.mHasSurface) {

                if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);

                w.mOrientationChanging = true;

                mInnerFields.mOrientationChangeComplete = false;

            }

        }



        for (int i=mRotationWatchers.size()-1; i>=0; i--) {

            try {

                mRotationWatchers.get(i).onRotationChanged(rotation);

            } catch (RemoteException e) {

            }

        }



        scheduleNotifyRotationChangedIfNeededLocked(displayContent, rotation);



        return true;

    }



2. modify PhoneWindowManager.java
//this part will make some APK user android:screenOrientation="nosensor" in AndroidMainfest.xml
//show in correct orientation

    @Override
    public int rotationForOrientationLw(int orientation, int lastRotation) {
        if (false) {
            Slog.v(TAG, "rotationForOrientationLw(orient="
                        + orientation + ", last=" + lastRotation
                        + "); user=" + mUserRotation + " "
                        + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
                            ? "USER_ROTATION_LOCKED" : "")
                        );
        }

        synchronized (mLock) {
            int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
            if (sensorRotation < 0) {
                sensorRotation = lastRotation;
            }

            final int preferredRotation;
            if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
                // Ignore sensor when lid switch is open and rotation is forced.
                preferredRotation = mLidOpenRotation;
            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
                    && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
                // Ignore sensor when in car dock unless explicitly enabled.
                // This case can override the behavior of NOSENSOR, and can also
                // enable 180 degree rotation while docked.
                preferredRotation = mCarDockEnablesAccelerometer
                        ? sensorRotation : mCarDockRotation;
            } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
                    || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
                    || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
                    && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
                // Ignore sensor when in desk dock unless explicitly enabled.
                // This case can override the behavior of NOSENSOR, and can also
                // enable 180 degree rotation while docked.
                preferredRotation = mDeskDockEnablesAccelerometer
                        ? sensorRotation : mDeskDockRotation;
            } else if (mHdmiPlugged && mHdmiRotationLock) {
                // Ignore sensor when plugged into HDMI.
                // Note that the dock orientation overrides the HDMI orientation.
                preferredRotation = mHdmiRotation;
                return mHdmiRotation;
            } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
                            && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
                                    || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
                // Otherwise, use sensor only if requested by the application or enabled
                // by default for USER or UNSPECIFIED modes.  Does not apply to NOSENSOR.
                if (mAllowAllRotations < 0) {
                    // Can't read this during init() because the context doesn't
                    // have display metrics at that time so we cannot determine
                    // tablet vs. phone then.
                    mAllowAllRotations = mContext.getResources().getBoolean(
                            com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
                }
                if (sensorRotation != Surface.ROTATION_180
                        || mAllowAllRotations == 1
                        || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
                    preferredRotation = sensorRotation;
                } else {
                    preferredRotation = lastRotation;
                }
            } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
                    && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
                // Apply rotation lock.  Does not apply to NOSENSOR.
                // The idea is that the user rotation expresses a weak preference for the direction
                // of gravity and as NOSENSOR is never affected by gravity, then neither should
                // NOSENSOR be affected by rotation lock (although it will be affected by docks).
                preferredRotation = mUserRotation;
            } else {
                // No overriding preference.
                // We will do exactly what the application asked us to do.
                preferredRotation = -1;
            }

            switch (orientation) {
                case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
                    // Return portrait unless overridden.
                    if (isAnyPortrait(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mPortraitRotation;

                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
                    // Return landscape unless overridden.
                    if (isLandscapeOrSeascape(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mLandscapeRotation;

                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
                    // Return reverse portrait unless overridden.
                    if (isAnyPortrait(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mUpsideDownRotation;

                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
                    // Return seascape unless overridden.
                    if (isLandscapeOrSeascape(preferredRotation)) {
                        return preferredRotation;
                    }
                    return mSeascapeRotation;

                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
                    // Return either landscape rotation.
                    if (isLandscapeOrSeascape(preferredRotation)) {
                        return preferredRotation;
                    }
                    if (isLandscapeOrSeascape(lastRotation)) {
                        return lastRotation;
                    }
                    return mLandscapeRotation;

                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
                    // Return either portrait rotation.
                    if (isAnyPortrait(preferredRotation)) {
                        return preferredRotation;
                    }
                    if (isAnyPortrait(lastRotation)) {
                        return lastRotation;
                    }
                    return mPortraitRotation;

                default:
                    // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
                    // just return the preferred orientation we already calculated.
                    if (preferredRotation >= 0) {
                        return preferredRotation;
                    }
                    return Surface.ROTATION_90;/**********AnsonCode 2014.1.2 return default orientation.************/
            }
        }
    }

 

PS: 以上代码仅在RK上测试过, 其它平台无从考证

 

 

你可能感兴趣的:(ORIENTATION,rotation)