Home | History | Annotate | Download | only in wm
      1 /*
      2 **
      3 ** Copyright 2013, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 
     19 package com.android.commands.wm;
     20 
     21 import android.content.Context;
     22 import android.graphics.Point;
     23 import android.graphics.Rect;
     24 import android.os.RemoteException;
     25 import android.os.ServiceManager;
     26 import android.util.AndroidException;
     27 import android.view.Display;
     28 import android.view.IWindowManager;
     29 import com.android.internal.os.BaseCommand;
     30 
     31 import java.io.PrintStream;
     32 import java.util.regex.Matcher;
     33 import java.util.regex.Pattern;
     34 
     35 public class Wm extends BaseCommand {
     36 
     37     private IWindowManager mWm;
     38 
     39     /**
     40      * Command-line entry point.
     41      *
     42      * @param args The command-line arguments
     43      */
     44     public static void main(String[] args) {
     45         (new Wm()).run(args);
     46     }
     47 
     48     public void onShowUsage(PrintStream out) {
     49         out.println(
     50                 "usage: wm [subcommand] [options]\n" +
     51                 "       wm size [reset|WxH]\n" +
     52                 "       wm density [reset|DENSITY]\n" +
     53                 "       wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
     54                 "\n" +
     55                 "wm size: return or override display size.\n" +
     56                 "\n" +
     57                 "wm density: override display density.\n" +
     58                 "\n" +
     59                 "wm overscan: set overscan area for display.\n"
     60                 );
     61     }
     62 
     63     public void onRun() throws Exception {
     64         mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
     65                         Context.WINDOW_SERVICE));
     66         if (mWm == null) {
     67             System.err.println(NO_SYSTEM_ERROR_CODE);
     68             throw new AndroidException("Can't connect to window manager; is the system running?");
     69         }
     70 
     71         String op = nextArgRequired();
     72 
     73         if (op.equals("size")) {
     74             runDisplaySize();
     75         } else if (op.equals("density")) {
     76             runDisplayDensity();
     77         } else if (op.equals("overscan")) {
     78             runDisplayOverscan();
     79         } else {
     80             showError("Error: unknown command '" + op + "'");
     81             return;
     82         }
     83     }
     84 
     85     private void runDisplaySize() throws Exception {
     86         String size = nextArg();
     87         int w, h;
     88         if (size == null) {
     89             Point initialSize = new Point();
     90             Point baseSize = new Point();
     91             try {
     92                 mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);
     93                 mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);
     94                 System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y);
     95                 if (!initialSize.equals(baseSize)) {
     96                     System.out.println("Override size: " + baseSize.x + "x" + baseSize.y);
     97                 }
     98             } catch (RemoteException e) {
     99             }
    100             return;
    101         } else if ("reset".equals(size)) {
    102             w = h = -1;
    103         } else {
    104             int div = size.indexOf('x');
    105             if (div <= 0 || div >= (size.length()-1)) {
    106                 System.err.println("Error: bad size " + size);
    107                 return;
    108             }
    109             String wstr = size.substring(0, div);
    110             String hstr = size.substring(div+1);
    111             try {
    112                 w = Integer.parseInt(wstr);
    113                 h = Integer.parseInt(hstr);
    114             } catch (NumberFormatException e) {
    115                 System.err.println("Error: bad number " + e);
    116                 return;
    117             }
    118         }
    119 
    120         try {
    121             if (w >= 0 && h >= 0) {
    122                 // TODO(multidisplay): For now Configuration only applies to main screen.
    123                 mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);
    124             } else {
    125                 mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
    126             }
    127         } catch (RemoteException e) {
    128         }
    129     }
    130 
    131     private void runDisplayDensity() throws Exception {
    132         String densityStr = nextArg();
    133         int density;
    134         if (densityStr == null) {
    135             try {
    136                 int initialDensity = mWm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);
    137                 int baseDensity = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
    138                 System.out.println("Physical density: " + initialDensity);
    139                 if (initialDensity != baseDensity) {
    140                     System.out.println("Override density: " + baseDensity);
    141                 }
    142             } catch (RemoteException e) {
    143             }
    144             return;
    145         } else if ("reset".equals(densityStr)) {
    146             density = -1;
    147         } else {
    148             try {
    149                 density = Integer.parseInt(densityStr);
    150             } catch (NumberFormatException e) {
    151                 System.err.println("Error: bad number " + e);
    152                 return;
    153             }
    154             if (density < 72) {
    155                 System.err.println("Error: density must be >= 72");
    156                 return;
    157             }
    158         }
    159 
    160         try {
    161             if (density > 0) {
    162                 // TODO(multidisplay): For now Configuration only applies to main screen.
    163                 mWm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density);
    164             } else {
    165                 mWm.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
    166             }
    167         } catch (RemoteException e) {
    168         }
    169     }
    170 
    171     private void runDisplayOverscan() throws Exception {
    172         String overscanStr = nextArgRequired();
    173         Rect rect = new Rect();
    174         int density;
    175         if ("reset".equals(overscanStr)) {
    176             rect.set(0, 0, 0, 0);
    177         } else {
    178             final Pattern FLATTENED_PATTERN = Pattern.compile(
    179                     "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)");
    180             Matcher matcher = FLATTENED_PATTERN.matcher(overscanStr);
    181             if (!matcher.matches()) {
    182                 System.err.println("Error: bad rectangle arg: " + overscanStr);
    183                 return;
    184             }
    185             rect.left = Integer.parseInt(matcher.group(1));
    186             rect.top = Integer.parseInt(matcher.group(2));
    187             rect.right = Integer.parseInt(matcher.group(3));
    188             rect.bottom = Integer.parseInt(matcher.group(4));
    189         }
    190 
    191         try {
    192             mWm.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right, rect.bottom);
    193         } catch (RemoteException e) {
    194         }
    195     }
    196 }
    197