So I bought a Nexus 10 for development and was super excited by the prospect of being able to simulate other devices using the “adb shell wm” command, with its size, density, and overscan subcommands.
However, I’ve had a few problems making this work. I’d like to see if anyone else has encountered/overcome these. For the sake of this discussion, let’s say I’m trying to simulate a typical phone, running the following:
adb shell wm size 800x480 adb shell wm density 240 adb shell wm overscan reset
First, setting the size messes up the menu bar. In portrait mode, only some of the buttons will be present and at the wrong scale, and in landscape mode, the menu bar is completely missing. In fact, even after you reset everything, it’s still missing until you restart the device. Any workaround for this?
Secondly, what does the overscan command do? I can’t find any documentation for it anywhere.
Thirdly, is there any way to make the device render the screen using 1 pixel of the new size to 1 pixel of the physical screen? That is to say, if I set the size to 800×480, I’d like to see the new screen take up exactly that much space. Instead, what seems to happen is the 800×480 screen is stretched so that the longest side just fits on the physical display. I suspect that overscan might be the answer, but when I tried to set it to 0,0,800,480, it permanently hung my system and I had to reset to the factory image to recover.
Finally, is there any way to cause the tablet to simulate a phone in terms of what happens to the menu bar during an orientation change? On a tablet, the menu bar goes to new bottom of the screen, but on a phone, it stays where it is.
I like this device so far, but if I could just get this device simulation stuff working, I’d love it! Thanks in advance for any pointers.
Okay, I think I figured out enough of this to be useful. I will attempt to answer each of the questions I raised in my original post. Then I’ll share a few other things I’ve learned about how to use this effectively.
- Is there any way to avoid messing up the menu bar when at the home screen?
Not that I’ve discovered, and changing the settings seems to have a cumulative effect that will usually royally screw up the home screen until you restart the device. However, you can usually at least unlock the device, which is enough to be useful. The key is to start your app first, then adjust the size and density while already running it. Simply press the power button to turn off the screen, adjust the size and density as you like, then power the screen back on, unlock, and you’re app will be running properly at the new size and density.
- What does the overscan command do?
I’ve found only oblique references to this, but the best I can determine, it’s for TVs or other displays where not all of the screen is guaranteed to be usable/visible. I don’t think it really applies to a regular phone or tablet.
- Is there any way to make the device render the screen using 1 pixel of the new size to 1 pixel of the physical screen?
Not that I’ve discovered. But it probably doesn’t matter. I think the main point of using the adb shell wm commands is to test layout, not to see pixel-perfect graphics. (And believe me, what you get is the farthest thing possible from pixel-perfect.)
- Is there any way to cause the tablet to simulate a phone in terms of what happens to the menu bar during an orientation change?
Maybe I’m doing it wrong, but for me, the menu bar behaves in bizarre and unpredictable ways. Sometimes it’s massive, sometimes it’s just missing. Don’t count on being able to use it. Yes, this sucks. Someone please chime in if there’s a solution to this.
- So how do I use “adb shell wm” effectively?
I’m not sure why, but it took me a little while to grasp this. That’s probably because when I first started this, my mind was not accustomed to the Android way of thinking about things. But it’s actually pretty simple.
First, set the size you want in pixels. For this discussion, let’s say we’re going to use 1024×600.
Next, set the DPI. But what should you set it to?
That’s the tricky part (well, the part I didn’t get at first). When you set the DPI, you’re setting the other half of the equation that will determine the dimensions in DP of the virtual application space, which the app will use to render itself. (Duh, I know, but I at first thought the specified DPI would be used mainly to select resources, which indeed it also does.)
Let’s take a look at the consequences of using various densities with a screen size of 1024×600.
First, keep in mind that
dp = px * (160 / dpi)
That means if we specify our dpi at 160, the app will believe that the available space is 1024dp x 600dp. If instead we use 240, that changes to a meager 683dp x 400 dp, and conversely, if we use 120, we get an impressive 1365 dp x 800 dp. Set it to 80, and now you’re rocking 2048dp x 1200dp.
The counter-intuitive part is realizing that specifying a low density results an image that appears like what you might see in an ultra-hi-res monitor — everything is tiny. But that’s because the app is now treating the same physical space as though it were a very large size in dp.
So going back to the example of a density of 80, we have a virtual area of 2048dp x 1200dp, but it is being scrunched onto whatever sized physical screen you’re actually using. Since 160dp is supposed to be about 1 inch, that would be an almost otherworldly tablet with a width of 12.8 inches. But that entire thing is scrunched down to the actual size of your tablet, making your generously sized 30dp text appear pretty puny.
Maybe I’m just the slowest kid in the room, but it took me a while to really grok this. I hope it helps someone else out there.
I guess overscan is setting the space of the screen (“the margin”) that is not used. Try with something like adb shell wm overscan 200,200,200,200 start an app and you will see the difference. In Home the difference is not so clear.
If this is really useful in combination with size and density I don’t know. I did some tests but no useful result. It is a little complicated (?) to see what values to use…
Just in case someone else runs into the “reset to the factory image” crash menu after trying to change the device’s resolution, here is how I solved it without factory reset (multiple hard reboots would always lead to the same “blue screen” menu):
- connect computer to phone through usb (wifi connection won’t work since phone rebooted)
- send back the adb command to set the original dimensions (
adb shell wm <width>x<height>), between the moment the phone is starting and the moment it crashes (you’ve got to be fast)