/* ** ** Copyright 2013, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ package com.android.commands.wm; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.os.RemoteException; import android.os.ServiceManager; import android.util.AndroidException; import android.view.Display; import android.view.IWindowManager; import com.android.internal.os.BaseCommand; import java.io.PrintStream; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Wm extends BaseCommand { private IWindowManager mWm; /** * Command-line entry point. * * @param args The command-line arguments */ public static void main(String[] args) { (new Wm()).run(args); } public void onShowUsage(PrintStream out) { out.println( "usage: wm [subcommand] [options]\n" + " wm size [reset|WxH]\n" + " wm density [reset|DENSITY]\n" + " wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" + "\n" + "wm size: return or override display size.\n" + "\n" + "wm density: override display density.\n" + "\n" + "wm overscan: set overscan area for display.\n" ); } public void onRun() throws Exception { mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService( Context.WINDOW_SERVICE)); if (mWm == null) { System.err.println(NO_SYSTEM_ERROR_CODE); throw new AndroidException("Can't connect to window manager; is the system running?"); } String op = nextArgRequired(); if (op.equals("size")) { runDisplaySize(); } else if (op.equals("density")) { runDisplayDensity(); } else if (op.equals("overscan")) { runDisplayOverscan(); } else { showError("Error: unknown command '" + op + "'"); return; } } private void runDisplaySize() throws Exception { String size = nextArg(); int w, h; if (size == null) { Point initialSize = new Point(); Point baseSize = new Point(); try { mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize); mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize); System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y); if (!initialSize.equals(baseSize)) { System.out.println("Override size: " + baseSize.x + "x" + baseSize.y); } } catch (RemoteException e) { } return; } else if ("reset".equals(size)) { w = h = -1; } else { int div = size.indexOf('x'); if (div <= 0 || div >= (size.length()-1)) { System.err.println("Error: bad size " + size); return; } String wstr = size.substring(0, div); String hstr = size.substring(div+1); try { w = Integer.parseInt(wstr); h = Integer.parseInt(hstr); } catch (NumberFormatException e) { System.err.println("Error: bad number " + e); return; } } try { if (w >= 0 && h >= 0) { // TODO(multidisplay): For now Configuration only applies to main screen. mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h); } else { mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY); } } catch (RemoteException e) { } } private void runDisplayDensity() throws Exception { String densityStr = nextArg(); int density; if (densityStr == null) { try { int initialDensity = mWm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY); int baseDensity = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY); System.out.println("Physical density: " + initialDensity); if (initialDensity != baseDensity) { System.out.println("Override density: " + baseDensity); } } catch (RemoteException e) { } return; } else if ("reset".equals(densityStr)) { density = -1; } else { try { density = Integer.parseInt(densityStr); } catch (NumberFormatException e) { System.err.println("Error: bad number " + e); return; } if (density < 72) { System.err.println("Error: density must be >= 72"); return; } } try { if (density > 0) { // TODO(multidisplay): For now Configuration only applies to main screen. mWm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density); } else { mWm.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY); } } catch (RemoteException e) { } } private void runDisplayOverscan() throws Exception { String overscanStr = nextArgRequired(); Rect rect = new Rect(); int density; if ("reset".equals(overscanStr)) { rect.set(0, 0, 0, 0); } else { final Pattern FLATTENED_PATTERN = Pattern.compile( "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)"); Matcher matcher = FLATTENED_PATTERN.matcher(overscanStr); if (!matcher.matches()) { System.err.println("Error: bad rectangle arg: " + overscanStr); return; } rect.left = Integer.parseInt(matcher.group(1)); rect.top = Integer.parseInt(matcher.group(2)); rect.right = Integer.parseInt(matcher.group(3)); rect.bottom = Integer.parseInt(matcher.group(4)); } try { mWm.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right, rect.bottom); } catch (RemoteException e) { } } }