android系统屏幕旋转实时生效

友宝和支付宝合作推出刷脸支付,友宝又是咱公司的长期客户,这次真的是傍上大腿了,喝汤也赚。
动态旋转系统屏幕,这个网上根本查不到,都是关于app如何旋转,系统级别的资料太少。查了2天快绝望了,然后灵光一闪,一试,成了,美滋滋~
盒子产品需要实时切换横竖屏,之前做过设置属性persist.panel.orientation然后重启设备生效。
修改点:
1.framework层

frameworks/native/services/surfaceflinger/DisplayDevice.cpp
DisplayDevice::DisplayDevice(
        const sp& flinger,
        DisplayType type,
        int32_t hwcId,
#ifndef USE_HWC2
        int format,
#endif
        bool isSecure,
        const wp& displayToken,
        const sp& displaySurface,
        const sp& producer,
        EGLConfig config)
    : lastCompositionHadVisibleLayers(false),
      mFlinger(flinger),
      mType(type),
      mHwcDisplayId(hwcId),
      mDisplayToken(displayToken),
      mDisplaySurface(displaySurface),
      mDisplay(EGL_NO_DISPLAY),
      mSurface(EGL_NO_SURFACE),
      mDisplayWidth(),
      mDisplayHeight(),
#ifndef USE_HWC2
      mFormat(),
#endif
      mFlags(),
      mPageFlipCount(),
      mIsSecure(isSecure),
      mLayerStack(NO_LAYER_STACK),
      mOrientation(),
      mPowerMode(HWC_POWER_MODE_OFF),
      mActiveConfig(0)
{
    Surface* surface;
    mNativeWindow = surface = new Surface(producer, false);
    ANativeWindow* const window = mNativeWindow.get();
    int defaultOrientation = 0;//andrew.hu add
    char property[PROPERTY_VALUE_MAX];

    /*
     * Create our display's surface
     */

    EGLSurface eglSurface;
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (config == EGL_NO_CONFIG) {
#ifdef USE_HWC2
        config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888);
#else
        config = RenderEngine::chooseEglConfig(display, format);
#endif
    }
    eglSurface = eglCreateWindowSurface(display, config, window, NULL);
    eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);
    eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);

    // Make sure that composition can never be stalled by a virtual display
    // consumer that isn't processing buffers fast enough. We have to do this
    // in two places:
    // * Here, in case the display is composed entirely by HWC.
    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
    //   window's swap interval in eglMakeCurrent, so they'll override the
    //   interval we set here.
    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
        window->setSwapInterval(window, 0);

    mConfig = config;
    mDisplay = display;
    mSurface = eglSurface;
#ifndef USE_HWC2
    mFormat = format;
#endif
    mPageFlipCount = 0;
    mViewport.makeInvalid();
    mFrame.makeInvalid();

    // virtual displays are always considered enabled
    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;

    // Name the display.  The name will be replaced shortly if the display
    // was created with createDisplay().
    switch (mType) {
        case DISPLAY_PRIMARY:
            mDisplayName = "Built-in Screen";
            break;
        case DISPLAY_EXTERNAL:
            mDisplayName = "HDMI Screen";
            break;
        default:
            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
            break;
    }

    mPanelMountFlip = 0;
    // 1: H-Flip, 2: V-Flip, 3: 180 (HV Flip)
    property_get("ro.panel.mountflip", property, "0");
    mPanelMountFlip = atoi(property);
    // add start 
    property_get("persist.panel.orientation", property, "0");
    defaultOrientation = atoi(property);
    switch(defaultOrientation) {
        case 0:
            defaultOrientation = DisplayState::eOrientationDefault;
            break;
        case 90:
            defaultOrientation = DisplayState::eOrientation90;
            break;
        case 180:
            defaultOrientation = DisplayState::eOrientation180;
            break;
        case 270:
            defaultOrientation = DisplayState::eOrientation270;
            break;
        default:
            defaultOrientation = DisplayState::eOrientationDefault;
            break;
    }
    // add end
    // initialize the display orientation transform. andrew.hu modify
    setProjection(defaultOrientation, mViewport, mFrame);

#ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS
    surface->allocateBuffers();
#endif
}

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private WindowManagerService(Context context, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
            ...
            filter.addAction("android.intent.action.DISPLAY_ORIENTATION"); // add
            ...
            // add start
        String defaultOrientation = SystemProperties.get("persist.panel.orientation", "0");
        if("0".equals(defaultOrientation)) {
            mRotation = Surface.ROTATION_0;
        } else if("90".equals(defaultOrientation)) {
            mRotation = Surface.ROTATION_90;
        } else if("180".equals(defaultOrientation)) {
            mRotation = Surface.ROTATION_180;
        } else if("270".equals(defaultOrientation)) {
            mRotation = Surface.ROTATION_270;
        } else {
            mRotation = Surface.ROTATION_0;
        }
        // add end
}

// 动态通过广播获取启动
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
                mKeyguardDisableHandler.sendEmptyMessage(
                    KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
            } else if ("android.intent.action.DISPLAY_ORIENTATION".equals(action)){ // add
                updateRotationUnchecked(true, false);
            }
        }
    };

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@Override
    public void setInitialDisplaySize(Display display, int width, int height, int density) {
    ...
    // add start
        String defaultOrientation = SystemProperties.get("persist.panel.orientation", "0");
        if("0".equals(defaultOrientation)) {
            mDefaultOrientation = Surface.ROTATION_0;
        } else if("90".equals(defaultOrientation)) {
            mDefaultOrientation = Surface.ROTATION_90;
        } else if("180".equals(defaultOrientation)) {
            mDefaultOrientation = Surface.ROTATION_180;
        } else if("270".equals(defaultOrientation)) {
            mDefaultOrientation = Surface.ROTATION_270;
        } else {
            mDefaultOrientation = Surface.ROTATION_0;
        }
        // add end
}

//动态的关键
@Override
    public int rotationForOrientationLw(int orientation, int lastRotation) {
    ...
    // add begin
                    String defaultOrientation = SystemProperties.get("persist.panel.orientation", "0");
                    if("0".equals(defaultOrientation)) {
                        mDefaultOrientation = Surface.ROTATION_0;
                    } else if("90".equals(defaultOrientation)) {
                        mDefaultOrientation = Surface.ROTATION_90;
                    } else if("180".equals(defaultOrientation)) {
                        mDefaultOrientation = Surface.ROTATION_180;
                    } else if("270".equals(defaultOrientation)) {
                        mDefaultOrientation = Surface.ROTATION_270;
                    } else {
                        mDefaultOrientation = Surface.ROTATION_0;
                    }
                    return mDefaultOrientation;
                    // add end
}

2.设置部分

packages/apps/Settings/src/com/android/settings/DisplaySettings.java
onCreate()
// 主屏
mDisplayorientationPreference = (ListPreference) findPreference(KEY_DISPLAY_ORIENTATION);
        if(mDisplayorientationPreference != null) {
            mDisplayorientationPreference.setOnPreferenceChangeListener(this);
            String Displayorientation = "landscape";
            switch (SystemProperties.getInt("persist.panel.orientation",0)) {
                case 0:
                    Displayorientation = "landscape";
                    break;
                case 90:
                    Displayorientation = "upsidedown";
                    break;
                case 180:
                    Displayorientation = "seascape";
                    break;
                case 270:
                    Displayorientation = "portrait";
                    break;
            }
            mDisplayorientationPreference.setValue(Displayorientation);
            int IndexValue = mDisplayorientationPreference.findIndexOfValue(Displayorientation);
            final CharSequence[] entries = mDisplayorientationPreference.getEntries();
            mDisplayorientationPreference.setSummary(getResources().getString(R.string.display_orientation_summary) + entries[IndexValue]);
        }
        
        // 副屏
        mViceDisplayorientationPreference = (ListPreference) findPreference(KEY_VICE_DISPLAY_ORIENTATION);
        if(mViceDisplayorientationPreference != null) {
            mViceDisplayorientationPreference.setOnPreferenceChangeListener(this);
            String Displayorientation = SystemProperties.get("persist.demo.hdmirotation","landscape");
            mViceDisplayorientationPreference.setValue(Displayorientation);
            int IndexValue = mViceDisplayorientationPreference.findIndexOfValue(Displayorientation);
            final CharSequence[] entries = mViceDisplayorientationPreference.getEntries();
            mViceDisplayorientationPreference.setSummary(getResources().getString(R.string.display_orientation_summary) + entries[IndexValue]);
        }

//默认显示
onPreferenceChange
if (KEY_DISPLAY_ORIENTATION.equals(key)) {
            final CharSequence[] entries = mDisplayorientationPreference.getEntries();
            int IndexValue = mDisplayorientationPreference.findIndexOfValue(objValue.toString());
            mDisplayorientationPreference.setSummary(getResources().getString(R.string.display_orientation_summary) + entries[IndexValue]);
            switch (objValue.toString()) {
                case "landscape":
                    SystemProperties.set("persist.panel.orientation", "0");
                    break;
                case "upsidedown":
                    SystemProperties.set("persist.panel.orientation", "90");
                    break;
                case "seascape":
                    SystemProperties.set("persist.panel.orientation", "180");
                    break;
                case "portrait":
                    SystemProperties.set("persist.panel.orientation", "270");
                    break;
            }
            // 动态发送广播启动旋转操作
            Intent intent = new Intent("android.intent.action.DISPLAY_ORIENTATION");
            preference.getContext().sendBroadcast(intent);
        }
        
        if (KEY_VICE_DISPLAY_ORIENTATION.equals(key)) {
            final CharSequence[] entries = mViceDisplayorientationPreference.getEntries();
            int IndexValue = mViceDisplayorientationPreference.findIndexOfValue(objValue.toString());
            mViceDisplayorientationPreference.setSummary(getResources().getString(R.string.display_orientation_summary) + entries[IndexValue]);
            SystemProperties.set("persist.demo.hdmirotation", objValue.toString());
        }

你可能感兴趣的:(android_system)