By default, the device is turned on with a vertical screen. If the device has a gravity sensor, the screen orientation is set according to the automatic rotation and gravity sensor. If we need the device to be turned on with a horizontal screen, or the user can customize the horizontal or vertical screen switch. The need to modify mainly includes four major blocks:
First add the custom attribute persist.sys.panel.orientation=1, the optional values are 0,1,2,3 where 0,2 is vertical screen, 1.3 is horizontal screen
- boot animation
//frameworks/base/cmds/bootanimation/BootAnimation.cpp status_t BootAnimation::readyToRun() { resolution = limitSurfaceSize(resolution.width, resolution.height); //phoebe add start char rAngleValue[PROPERTY_VALUE_MAX]; property_get("persist.sys.panel.orientation", rAngleValue, "1"); int rAngle = atoi(rAngleValue); SurfaceComposerClient::Transaction t; int temp = resolution.height; ui::Rotation rota; switch(rAngle){ case 0: rota=ui::ROTATION_0; break; case 1: resolution.height= resolution.width; resolution.width= temp; rota=ui::ROTATION_90; break; case 2: rota=ui::ROTATION_180; break; case 3: resolution.height= resolution.width; resolution.width= temp; rota=ui::ROTATION_270; break; default: rota=ui::ROTATION_90; break; } Rect destRect(resolution.width, resolution.height); ALOGD("BootAnimation default set rotation to be %d...",rAngle); t.setDisplayProjection(mDisplayToken, rota, destRect, destRect); //phoebe add end // create the native surface sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565); // SurfaceComposerClient::Transaction t; // this guest property specifies multi-display IDs to show the boot animation // multiple ids can be set with comma (,) as separator, for example: // setprop persist.boot.animation.displays 19260422155234049,19261083906282754 Vector<uint64_t> physicalDisplayIds; ... }
- UI modification
// frameworks/base/core/res/res/values/config.xml 关闭自动旋转 <bool name="config_supportAutoRotation">false</bool> //默认为横屏 <integer name="config_lidOpenRotation">90</integer> //frameworks/base/core/java/android/view/DisplayInfo.java //初始值为设置的属性 public int rotation= SystemProperties.getInt("persist.sys.panel.orientation",1); //frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java public void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device, boolean isBlanked) { //... //orientation = (orientation + displayDeviceInfo.rotation) % 4; //方向为我们设置的方向 orientation = SystemProperties.getInt("persist.sys.panel.orientation", 1); Slog.d("zmm","zmm add for configureDisplayLocked:"+orientation); //... } } //frameworks/base/services/core/java/com/android/server/wm/DisplayRotation.java 保存用户设置的方向 void setUserRotation(int userRotationMode, int userRotation) { if (isDefaultDisplay) { // We'll be notified via settings listener, so we don't need to update internal values. ... SystemProperties.set("persist.sys.panel.orientation",""+userRotation); return; } }
- The screen touch coordinates are changed to horizontal screen
//frameworks/native/services/surfaceflinger/DisplayDevice.cpp DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) : mFlinger(args.flinger), mDisplayToken(args.displayToken), mSequenceId(args.sequenceId), mConnectionType(args.connectionType), mCompositionDisplay{args.compositionDisplay}, mPhysicalOrientation(args.physicalOrientation), mIsPrimary(args.isPrimary), mIsPowerModeOverride(false){ //.. setPowerMode(args.initialPowerMode); //nick.tan add screen flipping char property_rotation[PROPERTY_VALUE_MAX]; // int defaultOrientation = 0; property_get("persist.sys.panel.orientation", property_rotation, "1"); int defaultOrientation = atoi(property_rotation); ui::Rotation rota; switch(defaultOrientation) { case 0: rota = ui::ROTATION_0; break; case 1: rota = ui::ROTATION_90; break; case 2: rota = ui::ROTATION_180; break; case 3: rota = ui::ROTATION_270; break; default: rota = ui::ROTATION_90; break; } ALOGE("zmm add for DisplayDevice:%d",defaultOrientation); // initialize the display orientation transform. setProjection(rota, Rect::INVALID_RECT, Rect::INVALID_RECT); } //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp void SurfaceFlinger::onInitializeDisplays() { const auto display = getDefaultDisplayDeviceLocked(); if (!display) return; //... //nick.tan add screen flipping char property_rotation[PROPERTY_VALUE_MAX]; //int defaultOrientation = 0; property_get("persist.sys.panel.orientation", property_rotation, "1"); int defaultOrientation = atoi(property_rotation); ui::Rotation rota; switch(defaultOrientation) { case 0: rota = ui::ROTATION_0; break; case 1: rota = ui::ROTATION_90; break; case 2: rota = ui::ROTATION_180; break; case 3: rota = ui::ROTATION_270; break; default: rota = ui::ROTATION_90; break; } ALOGE("zmm add for SurfaceFlinger:%d",defaultOrientation); d.orientation = rota; //... }
- Modification of SystemUi and Launcher
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { //... // Currently there is no accelerometer sensor on non-default display. if (mIsOnDefaultDisplay) { final RotationButtonController rotationButtonController = mNavigationBarView.getRotationButtonController(); rotationButtonController.addRotationCallback(mRotationWatcher); // Reset user rotation pref to match that of the WindowManager if starting in locked // mode. This will automatically happen when switching from auto-rotate to locked mode. if (display != null && rotationButtonController.isRotationLocked()) { 导航栏会重新设置方向,故去掉 // rotationButtonController.setRotationLockedAtAngle(display.getRotation()); } } else { mDisabledFlags2 |= StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS; } //... } //frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java 需调整navigationbar位置。系统设置为横屏显示后,横屏后 navigationBar默认在左边。需修改DisplayPolicy中的navigationBarPosition函数,屏蔽判断部分,使其直接返回NAV_BAR_BOTTOM。 private boolean shouldOverrideUserLockPrefs(final int rotation) { if (mSkipOverrideUserLockPrefsOnce) { mSkipOverrideUserLockPrefsOnce = false; return false; } // Only override user prefs when returning to the natural rotation (normally portrait). // Don't let apps that force landscape or 180 alter user lock. // return rotation == NATURAL_ROTATION; //默认不支持旋转 return false; } //frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java void updateConfigurationAndScreenSizeDependentBehaviors() { final Resources res = getCurrentUserResources(); // mNavigationBarCanMove = // mDisplayContent.mBaseDisplayWidth != mDisplayContent.mBaseDisplayHeight // && res.getBoolean(R.bool.config_navBarCanMove); mNavigationBarCanMove=false; Slog.d(TAG,"zmm add for updateConfigurationAndScreenSizeDependentBehaviors"+mNavigationBarCanMove); mDisplayContent.getDisplayRotation().updateUserDependentConfiguration(res); } //同样hostseat也在右侧,如果需要在底部,。修改hotseat_transpose_layout_with_orientation的值,由true改成false。 //packages/apps/Launcher3/res/values/config.xml <!-- Hotseat --> - <bool name="hotseat_transpose_layout_with_orientation">true</bool> + <bool name="hotseat_transpose_layout_with_orientation">false</bool> 配置hotseat 位置居于底部后,allapp界面部分改变了,本身是4x4的布局,现在图标变小填充并且不再是4x4。表现为右侧留白。需修改availableHeightPx 和availableWidthPx 部分。 //packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java public DeviceProfile(Context context, InvariantDeviceProfile inv, Point minSize, Point maxSize, int width, int height, boolean isLandscape, boolean isMultiWindowMode) { this.inv = inv; this.isLandscape = isLandscape; this.isMultiWindowMode = isMultiWindowMode; // Determine sizes. widthPx = width; heightPx = height; if (isLandscape) { /* availableWidthPx = maxSize.x; availableHeightPx = minSize.y;*/ availableWidthPx = minSize.x; availableHeightPx = maxSize.y; } else { availableWidthPx = minSize.x; availableHeightPx = maxSize.y; } workspace区域添加的图标显示不全。具体修改如下 //packages/apps/Launcher3/src/com/android/launcher3/CellLayout.java public class CellLayout extends ViewGroup implements Transposable { if (mFixedCellWidth < 0 || mFixedCellHeight < 0) { int cw = DeviceProfile.calculateCellWidth(childWidthSize, mCountX); - int ch = DeviceProfile.calculateCellHeight(childHeightSize, mCountY); + int ch = childHeightSize;//DeviceProfile.calculateCellHeight(childHeightSize, mCountY); if (cw != mCellWidth || ch != mCellHeight) { mCellWidth = cw; mCellHeight = ch; 移除workspace区域的google搜索:注释掉bindAndInitFirstWorkspaceScreen中qsb部分。 //packages/apps/Launcher3/src/com/android/launcher3/Workspace.java public void bindAndInitFirstWorkspaceScreen(View qsb) { if (!FeatureFlags.QSB_ON_FIRST_SCREEN) { return; } // Add the first page CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, 0); // Always add a QSB on the first screen. /* if (qsb == null) { // In transposed layout, we add the QSB in the Grid. As workspace does not touch the // edges, we do not need a full width QSB. qsb = LayoutInflater.from(getContext()) .inflate(R.layout.search_container_workspace,firstPage, false); } CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(), 1); lp.canReorder = false; if (!firstPage.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true)) { Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout"); }*/ }
The above can realize the horizontal screen at startup, and the user can set the property to switch
SystemProperties.put("persist.sys.panel.orientation","1");
Daily record: A busy year, but also a fulfilling year. The article was written before, but it was only recorded locally. Today’s lunch break, I sorted it out and uploaded it as a summary.
Single cycle "Fulfillment"