设置屏幕分辨率指令
adb shell wm size 1920x1080
代码监听处
WindowManagerShellCommand中的
@Override
@Override
68 public int onCommand(String cmd) {
69 if (cmd == null) {
70 return handleDefaultCommands(cmd);
71 }
72 final PrintWriter pw = getOutPrintWriter();
73 try {
74 switch (cmd) {
75 case "size":
76 return runDisplaySize(pw);
77 case "density":
78 return runDisplayDensity(pw);
79 case "folded-area":
80 return runDisplayFoldedArea(pw);
81 case "scaling":
82 return runDisplayScaling(pw);
83 case "dismiss-keyguard":
84 return runDismissKeyguard(pw);
85 case "tracing":
86 // XXX this should probably be changed to use openFileForSystem() to create
87 // the output trace file, so the shell gets the correct semantics for where
88 // trace files can be written.
89 return mInternal.mWindowTracing.onShellCommand(this);
90 case "logging":
91 String[] args = peekRemainingArgs();
92 int result = ProtoLogImpl.getSingleInstance().onShellCommand(this);
93 if (result != 0) {
94 // Let the shell try and handle this
95 try (ParcelFileDescriptor pfd
96 = ParcelFileDescriptor.dup(getOutFileDescriptor())){
97 pw.println("Not handled, calling status bar with args: "
98 + Arrays.toString(args));
99 LocalServices.getService(StatusBarManagerInternal.class)
100 .handleWindowManagerLoggingCommand(args, pfd);
101 } catch (IOException e) {
102 pw.println("Failed to handle logging command: " + e.getMessage());
103 }
104 }
105 return result;
106 case "user-rotation":
107 return runDisplayUserRotation(pw);
108 case "fixed-to-user-rotation":
109 return runFixedToUserRotation(pw);
110 case "set-ignore-orientation-request":
111 return runSetIgnoreOrientationRequest(pw);
112 case "get-ignore-orientation-request":
113 return runGetIgnoreOrientationRequest(pw);
114 case "dump-visible-window-views":
115 return runDumpVisibleWindowViews(pw);
116 case "set-multi-window-config":
117 return runSetMultiWindowConfig();
118 case "get-multi-window-config":
119 return runGetMultiWindowConfig(pw);
120 case "reset-multi-window-config":
121 return runResetMultiWindowConfig();
122 case "reset":
123 return runReset(pw);
124 case "disable-blur":
125 return runSetBlurDisabled(pw);
126 default:
127 return handleDefaultCommands(cmd);
128 }
129 } catch (RemoteException e) {
130 pw.println("Remote exception: " + e);
131 }
132 return -1;
133 }
其中的runDisplaySize代码
private int runDisplaySize(PrintWriter pw) throws RemoteException {
169 String size = getNextArg();
170 int w, h;
171 final int displayId = getDisplayId(size);
172 if (size == null) {
173 printInitialDisplaySize(pw, displayId);
174 return 0;
175 } else if ("-d".equals(size)) {
176 printInitialDisplaySize(pw, displayId);
177 return 0;
178 } else if ("reset".equals(size)) {
179 w = h = -1;
180 } else {
181 int div = size.indexOf('x');
182 if (div <= 0 || div >= (size.length()-1)) {
183 getErrPrintWriter().println("Error: bad size " + size);
184 return -1;
185 }
186 String wstr = size.substring(0, div);
187 String hstr = size.substring(div+1);
188 try {
189 w = parseDimension(wstr, displayId);
190 h = parseDimension(hstr, displayId);
191 } catch (NumberFormatException e) {
192 getErrPrintWriter().println("Error: bad number " + e);
193 return -1;
194 }
195 }
196
197 if (w >= 0 && h >= 0) {
198 mInterface.setForcedDisplaySize(displayId, w, h);
199 } else {
200 mInterface.clearForcedDisplaySize(displayId);
201 }
202 return 0;
203 }
看代码逻辑会走到mInterface.setForcedDisplaySize(displayId, w, h);
此时调用到
@Override
public void setForcedDisplaySize(int displayId, int width, int height) {
if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
}
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
displayContent.setForcedSize(width, height);
}
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}
继续到 displayContent.setForcedSize(width, height);代码DisplayContent中的
/** If the given width and height equal to initial size, the setting will be cleared. */
void setForcedSize(int width, int height) {
mIsSizeForced = mInitialDisplayWidth != width || mInitialDisplayHeight != height;
if (mIsSizeForced) {
// Set some sort of reasonable bounds on the size of the display that we will try
// to emulate.
final int minSize = 200;
final int maxScale = 2;
width = Math.min(Math.max(width, minSize), mInitialDisplayWidth * maxScale);
height = Math.min(Math.max(height, minSize), mInitialDisplayHeight * maxScale);
}
Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
updateBaseDisplayMetrics(width, height, mBaseDisplayDensity);
reconfigureDisplayLocked();
if (!mIsSizeForced) {
width = height = 0;
}
mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
}
最终生效处应该是下面三个代码中,但是我们其实去看 mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
这个里面的调用,他会去修改settings数据库。
updateBaseDisplayMetrics(width, height, mBaseDisplayDensity);
reconfigureDisplayLocked();
mWmService.mDisplayWindowSettings.setForcedSize(this, width, height);
void setForcedSize(DisplayContent displayContent, int width, int height) {
if (displayContent.isDefaultDisplay) {
final String sizeString = (width == 0 || height == 0) ? "" : (width + "," + height);
Settings.Global.putString(mService.mContext.getContentResolver(),
Settings.Global.DISPLAY_SIZE_FORCED, sizeString);
}
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
final SettingsProvider.SettingsEntry overrideSettings =
mSettingsProvider.getOverrideSettings(displayInfo);
overrideSettings.mForcedWidth = width;
overrideSettings.mForcedHeight = height;
mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
}
我们通过手动更改这个数据库值DISPLAY_SIZE_FORCED,通过指令修改重启后也可以达到相同的效果
adb shell settings put global display_size_forced 1920,1280
所以我们也可以在settingprovider中配置默认值进行修改。
另外,查看这个属性值的使用,我们在windowmanagerservice中可以看到,会先从这个数据库属性值中获取数据,如果没有也会从 private static final String SIZE_OVERRIDE = “ro.config.size_override”;这个配置值中获取,所以我们也可以在mk中配置PRODUCT_PROPERTY_OVERRIDES += ro.config.size_override=3840,2160这个是我根据代码猜测的,未进行测试。
/** The global settings only apply to default display. */
private boolean applyForcedPropertiesForDefaultDisplay() {
boolean changed = false;
final DisplayContent displayContent = getDefaultDisplayContentLocked();
// Display size.
String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.DISPLAY_SIZE_FORCED);
if (sizeStr == null || sizeStr.length() == 0) {
sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
}
if (sizeStr != null && sizeStr.length() > 0) {
final int pos = sizeStr.indexOf(',');
if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
int width, height;
try {
width = Integer.parseInt(sizeStr.substring(0, pos));
height = Integer.parseInt(sizeStr.substring(pos + 1));
if (displayContent.mBaseDisplayWidth != width
|| displayContent.mBaseDisplayHeight != height) {
ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height);
displayContent.updateBaseDisplayMetrics(width, height,
displayContent.mBaseDisplayDensity);
changed = true;
}
} catch (NumberFormatException ex) {
}
}
}
// Display density.
final int density = getForcedDisplayDensityForUserLocked(mCurrentUserId);
if (density != 0 && density != displayContent.mBaseDisplayDensity) {
displayContent.mBaseDisplayDensity = density;
changed = true;
}
// Display scaling mode.
int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DISPLAY_SCALING_FORCE, 0);
if (displayContent.mDisplayScalingDisabled != (mode != 0)) {
ProtoLog.i(WM_ERROR, "FORCED DISPLAY SCALING DISABLED");
displayContent.mDisplayScalingDisabled = true;
changed = true;
}
return changed;
}