Wm.java revision c652de8141f5b8e3c6bcf8916842b6e106413b1a
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 19package com.android.commands.wm; 20 21import android.content.Context; 22import android.graphics.Rect; 23import android.os.RemoteException; 24import android.os.ServiceManager; 25import android.util.AndroidException; 26import android.view.Display; 27import android.view.IWindowManager; 28 29import java.util.regex.Matcher; 30import java.util.regex.Pattern; 31 32public class Wm { 33 34 private IWindowManager mWm; 35 private String[] mArgs; 36 private int mNextArg; 37 private String mCurArgData; 38 39 // These are magic strings understood by the Eclipse plugin. 40 private static final String FATAL_ERROR_CODE = "Error type 1"; 41 private static final String NO_SYSTEM_ERROR_CODE = "Error type 2"; 42 private static final String NO_CLASS_ERROR_CODE = "Error type 3"; 43 44 /** 45 * Command-line entry point. 46 * 47 * @param args The command-line arguments 48 */ 49 public static void main(String[] args) { 50 try { 51 (new Wm()).run(args); 52 } catch (IllegalArgumentException e) { 53 showUsage(); 54 System.err.println("Error: " + e.getMessage()); 55 } catch (Exception e) { 56 e.printStackTrace(System.err); 57 System.exit(1); 58 } 59 } 60 61 private void run(String[] args) throws Exception { 62 if (args.length < 1) { 63 showUsage(); 64 return; 65 } 66 67 mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService( 68 Context.WINDOW_SERVICE)); 69 if (mWm == null) { 70 System.err.println(NO_SYSTEM_ERROR_CODE); 71 throw new AndroidException("Can't connect to window manager; is the system running?"); 72 } 73 74 mArgs = args; 75 String op = args[0]; 76 mNextArg = 1; 77 78 if (op.equals("size")) { 79 runDisplaySize(); 80 } else if (op.equals("density")) { 81 runDisplayDensity(); 82 } else if (op.equals("overscan")) { 83 runDisplayOverscan(); 84 } else { 85 throw new IllegalArgumentException("Unknown command: " + op); 86 } 87 } 88 89 private void runDisplaySize() throws Exception { 90 String size = nextArgRequired(); 91 int w, h; 92 if ("reset".equals(size)) { 93 w = h = -1; 94 } else { 95 int div = size.indexOf('x'); 96 if (div <= 0 || div >= (size.length()-1)) { 97 System.err.println("Error: bad size " + size); 98 return; 99 } 100 String wstr = size.substring(0, div); 101 String hstr = size.substring(div+1); 102 try { 103 w = Integer.parseInt(wstr); 104 h = Integer.parseInt(hstr); 105 } catch (NumberFormatException e) { 106 System.err.println("Error: bad number " + e); 107 return; 108 } 109 } 110 111 try { 112 if (w >= 0 && h >= 0) { 113 // TODO(multidisplay): For now Configuration only applies to main screen. 114 mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h); 115 } else { 116 mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY); 117 } 118 } catch (RemoteException e) { 119 } 120 } 121 122 private void runDisplayDensity() throws Exception { 123 String densityStr = nextArgRequired(); 124 int density; 125 if ("reset".equals(densityStr)) { 126 density = -1; 127 } else { 128 try { 129 density = Integer.parseInt(densityStr); 130 } catch (NumberFormatException e) { 131 System.err.println("Error: bad number " + e); 132 return; 133 } 134 if (density < 72) { 135 System.err.println("Error: density must be >= 72"); 136 return; 137 } 138 } 139 140 try { 141 if (density > 0) { 142 // TODO(multidisplay): For now Configuration only applies to main screen. 143 mWm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density); 144 } else { 145 mWm.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY); 146 } 147 } catch (RemoteException e) { 148 } 149 } 150 151 private void runDisplayOverscan() throws Exception { 152 String overscanStr = nextArgRequired(); 153 Rect rect = new Rect(); 154 int density; 155 if ("reset".equals(overscanStr)) { 156 rect.set(0, 0, 0, 0); 157 } else { 158 final Pattern FLATTENED_PATTERN = Pattern.compile( 159 "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)"); 160 Matcher matcher = FLATTENED_PATTERN.matcher(overscanStr); 161 if (!matcher.matches()) { 162 System.err.println("Error: bad rectangle arg: " + overscanStr); 163 return; 164 } 165 rect.left = Integer.parseInt(matcher.group(1)); 166 rect.top = Integer.parseInt(matcher.group(2)); 167 rect.right = Integer.parseInt(matcher.group(3)); 168 rect.bottom = Integer.parseInt(matcher.group(4)); 169 } 170 171 try { 172 mWm.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right, rect.bottom); 173 } catch (RemoteException e) { 174 } 175 } 176 177 private String nextOption() { 178 if (mCurArgData != null) { 179 String prev = mArgs[mNextArg - 1]; 180 throw new IllegalArgumentException("No argument expected after \"" + prev + "\""); 181 } 182 if (mNextArg >= mArgs.length) { 183 return null; 184 } 185 String arg = mArgs[mNextArg]; 186 if (!arg.startsWith("-")) { 187 return null; 188 } 189 mNextArg++; 190 if (arg.equals("--")) { 191 return null; 192 } 193 if (arg.length() > 1 && arg.charAt(1) != '-') { 194 if (arg.length() > 2) { 195 mCurArgData = arg.substring(2); 196 return arg.substring(0, 2); 197 } else { 198 mCurArgData = null; 199 return arg; 200 } 201 } 202 mCurArgData = null; 203 return arg; 204 } 205 206 private String nextArg() { 207 if (mCurArgData != null) { 208 String arg = mCurArgData; 209 mCurArgData = null; 210 return arg; 211 } else if (mNextArg < mArgs.length) { 212 return mArgs[mNextArg++]; 213 } else { 214 return null; 215 } 216 } 217 218 private String nextArgRequired() { 219 String arg = nextArg(); 220 if (arg == null) { 221 String prev = mArgs[mNextArg - 1]; 222 throw new IllegalArgumentException("Argument expected after \"" + prev + "\""); 223 } 224 return arg; 225 } 226 227 private static void showUsage() { 228 System.err.println( 229 "usage: wm [subcommand] [options]\n" + 230 " wm size [reset|WxH]\n" + 231 " wm density [reset|DENSITY]\n" + 232 " wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" + 233 "\n" + 234 "wm size: override display size.\n" + 235 "\n" + 236 "wm density: override display density.\n" + 237 "\n" + 238 "wm overscan: set overscan area for display.\n" 239 ); 240 } 241} 242