1. 程式人生 > >Android 原始碼 修改系統預設橫屏

Android 原始碼 修改系統預設橫屏

1:WindowManagerService:

platform\frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.class 

具體改動的地方看程式碼吧,

   public int getOrientationFromWindowsLocked() {
        ....
        -- return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        ++ return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
  /*
     * Determine the new desired orientation of the display, returning
     * a non-null new Configuration if it has changed from the current
     * orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL
     * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
     * SCREEN.  This will typically be done for you if you call
     * sendNewConfiguration().
     *
     * The orientation is computed from non-application windows first. If none of
     * the non-application windows specify orientation, the orientation is computed from
     * application tokens.
     * @see android.view.IWindowManager#updateOrientationFromAppTokens(
     * android.os.IBinder)
     */
    boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
        long ident = Binder.clearCallingIdentity();
        try {
            int req = getOrientationFromWindowsLocked();
            if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
-- mForcedAppOrientation = req;
-- req = getOrientationFromAppTokensLocked();
         ++req=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            }

            if (req != mForcedAppOrientation) {
                -- mForcedAppOrientation = req;
                ++ mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
....
    }
    boolean computeScreenConfigurationLocked(Configuration config) {

....
        if (config != null) {
            -- config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT:Configuration.ORIENTATION_LANDSCAPE;
            ++ config.orientation = Configuration.ORIENTATION_LANDSCAPE;
        }

....
        return true;
    }

修改這幾處程式碼便能把系統預設的豎屏變成橫屏,但是會有其他的應用出現問題,比如撥號盤原本豎屏顯示的,但是在這種橫屏模式下開啟撥號盤會報空指標錯誤,進原始碼一看原來撥號盤也準備了兩套的佈局,一套橫屏一套豎屏的,單獨修改windowmanagerservice後不知道為什麼這些系統應用沒有變成豎屏模式,或許是時間倉促,並沒有對windowmanagerservice的流程作很詳細的分析,以後有時間再找機會研究下這個流程吧。

2:PhoneWindowManager

  1. public int rotationForOrientationLw(int orientation, int lastRotation,  
  2.            boolean displayEnabled) {  
  3.        if (mPortraitRotation < 0) {  
  4.            // Initialize the rotation angles for each orientation once.  
  5.            Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))  
  6.                    .getDefaultDisplay();  
  7.            if (d.getWidth() > d.getHeight()) {  
  8.                mPortraitRotation = Surface.ROTATION_90;  
  9.                mLandscapeRotation = Surface.ROTATION_0;  
  10.                mUpsideDownRotation = Surface.ROTATION_270;  
  11.                mSeascapeRotation = Surface.ROTATION_180;  
  12.            } else {  
  13.                mPortraitRotation = Surface.ROTATION_0;  
  14.                mLandscapeRotation = Surface.ROTATION_90;  
  15.                mUpsideDownRotation = Surface.ROTATION_180;  
  16.                mSeascapeRotation = Surface.ROTATION_270;  
  17.            }  
  18.        }  
  19.     {  
  20.         Log.i(TAG, "MediaPlayer.is not PlayingVideo");  
  21.         synchronized (mLock) {  
  22.             switch (orientation) {  
  23.                 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:  
  24.                     //always return portrait if orientation set to portrait  
  25.                     //return mPortraitRotation;  
  26.                     return mUpsideDownRotation;  
  27.                 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:  
  28.                     //always return landscape if orientation set to landscape  
  29.                     return mLandscapeRotation;  
  30.                 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:  
  31.                     //always return portrait if orientation set to portrait  
  32.                     //return mUpsideDownRotation;  
  33.                     return mPortraitRotation;  
  34.                 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:  
  35.                     //always return seascape if orientation set to reverse landscape  
  36.                     return mSeascapeRotation;  
  37.                 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:  
  38.                     //return either landscape rotation based on the sensor  
  39.                     mOrientationListener.setAllow180Rotation(  
  40.                             isLandscapeOrSeascape(Surface.ROTATION_180));  
  41.                     return getCurrentLandscapeRotation(lastRotation);  
  42.                 case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:  
  43.                     mOrientationListener.setAllow180Rotation(  
  44.                             !isLandscapeOrSeascape(Surface.ROTATION_180));  
  45.                     return getCurrentPortraitRotation(lastRotation);  
  46.             }  
  47.             mOrientationListener.setAllow180Rotation(  
  48.                    orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR  
  49.                    || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);  
  50.             // case for nosensor meaning ignore sensor and consider only lid  
  51.             // or orientation sensor disabled  
  52.             //or case.unspecified  
  53.             if (mLidOpen) {  
  54.                 return mLidOpenRotation;  
  55.             } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {  
  56.                 return mCarDockRotation;  
  57.             } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {  
  58.                 return mDeskDockRotation;  
  59.             } else {  
  60.                 if (useSensorForOrientationLp(orientation)) {  
  61.                     return mOrientationListener.getCurrentRotation(lastRotation);  
  62.                 }  
  63.                 return Surface.ROTATION_0;  
  64.             }  
  65.         }  
  66. }  
  67.    }  


修改上面倒數一行程式碼把return Surface.ROTATION_0改為你要的方向,記得這個要和上面的匹配,寬高不同,Surface.ROTATION_0也不同。因為程式碼開頭就有

  1. if (mPortraitRotation < 0) {  
  2.     // Initialize the rotation angles for each orientation once.  
  3.     Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))  
  4.             .getDefaultDisplay();  
  5.     if (d.getWidth() > d.getHeight()) {  
  6.         mPortraitRotation = Surface.ROTATION_90;  
  7.         mLandscapeRotation = Surface.ROTATION_0;  
  8.         mUpsideDownRotation = Surface.ROTATION_270;  
  9.         mSeascapeRotation = Surface.ROTATION_180;  
  10.     } else {  
  11.         mPortraitRotation = Surface.ROTATION_0;  
  12.         mLandscapeRotation = Surface.ROTATION_90;  
  13.         mUpsideDownRotation = Surface.ROTATION_180;  
  14.         mSeascapeRotation = Surface.ROTATION_270;  
  15.     }  
  16. }  

讓所有應用都橫屏顯示:

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

    public int rotationForOrientationLw(int orientation, int lastRotation,

            boolean displayEnabled) {

            // Initialize the rotation angles for each orientation once.

            Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))

                    .getDefaultDisplay();

            if (d.getWidth() > d.getHeight()) {

                mPortraitRotation = Surface.ROTATION_0;  //jeff. ROTATION_90;

                mLandscapeRotation = Surface.ROTATION_0;

                mUpsideDownRotation = Surface.ROTATION_90;  //jeff. 270;

                mSeascapeRotation = Surface.ROTATION_180;

            }