1c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn/*
2c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn**
3c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** Copyright 2013, The Android Open Source Project
4c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn**
5c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** Licensed under the Apache License, Version 2.0 (the "License");
6c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** you may not use this file except in compliance with the License.
7c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** You may obtain a copy of the License at
8c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn**
9c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn**     http://www.apache.org/licenses/LICENSE-2.0
10c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn**
11c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** Unless required by applicable law or agreed to in writing, software
12c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** distributed under the License is distributed on an "AS IS" BASIS,
13c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** See the License for the specific language governing permissions and
15c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn** limitations under the License.
16c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn*/
17c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
18c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
19c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornpackage com.android.commands.wm;
20c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
21c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.content.Context;
22672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackbornimport android.graphics.Point;
23c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.graphics.Rect;
243b716249cc2f94aa9842576b618998c28593be90Robert Carrimport android.os.ParcelFileDescriptor;
25c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.os.RemoteException;
26c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.os.ServiceManager;
27df3a7cab8f534584bcef83e222372e1be9be12c5Alan Viveretteimport android.os.UserHandle;
28c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.util.AndroidException;
29d46747a1c64b6ca3282e8841833980ab91829436Jeff Brownimport android.util.DisplayMetrics;
303b716249cc2f94aa9842576b618998c28593be90Robert Carrimport android.system.Os;
31c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.view.Display;
32c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport android.view.IWindowManager;
3379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornimport com.android.internal.os.BaseCommand;
34c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
353b716249cc2f94aa9842576b618998c28593be90Robert Carrimport java.io.FileDescriptor;
363b716249cc2f94aa9842576b618998c28593be90Robert Carrimport java.io.FileInputStream;
373b716249cc2f94aa9842576b618998c28593be90Robert Carrimport java.io.DataInputStream;
3879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornimport java.io.PrintStream;
393b716249cc2f94aa9842576b618998c28593be90Robert Carrimport java.lang.Runtime;
40c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.util.regex.Matcher;
41c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackbornimport java.util.regex.Pattern;
42c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
4379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackbornpublic class Wm extends BaseCommand {
44c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
45c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    private IWindowManager mWm;
46c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
47c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    /**
48c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn     * Command-line entry point.
49c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn     *
50c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn     * @param args The command-line arguments
51c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn     */
52c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    public static void main(String[] args) {
5379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn        (new Wm()).run(args);
54c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    }
55c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
56d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown    @Override
5779f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn    public void onShowUsage(PrintStream out) {
5879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn        out.println(
5979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "usage: wm [subcommand] [options]\n" +
60d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                "       wm size [reset|WxH|WdpxHdp]\n" +
6179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "       wm density [reset|DENSITY]\n" +
6279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "       wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +
63d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                "       wm scaling [off|auto]\n" +
64f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale                "       wm screen-capture [userId] [true|false]\n" +
6579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "\n" +
6679f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "wm size: return or override display size.\n" +
67d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                "         width and height in pixels unless suffixed with 'dp'.\n" +
6879f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "\n" +
6979f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "wm density: override display density.\n" +
7079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                "\n" +
71d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                "wm overscan: set overscan area for display.\n" +
72d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                "\n" +
73f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale                "wm scaling: set display scaling mode.\n" +
74f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale                "\n" +
75f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn                "wm screen-capture: enable/disable screen capture.\n" +
76f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn                "\n" +
77f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn                "wm dismiss-keyguard: dismiss the keyguard, prompting the user for auth if " +
783b716249cc2f94aa9842576b618998c28593be90Robert Carr                "necessary.\n" +
793b716249cc2f94aa9842576b618998c28593be90Robert Carr                "\n" +
8058c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr                "wm surface-trace: log surface commands to stdout in a binary format.\n"
8179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn                );
8279f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn    }
83c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
84d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown    @Override
8579f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn    public void onRun() throws Exception {
86c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
87c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                        Context.WINDOW_SERVICE));
88c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        if (mWm == null) {
89c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            System.err.println(NO_SYSTEM_ERROR_CODE);
90c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            throw new AndroidException("Can't connect to window manager; is the system running?");
91c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
92c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
9379f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn        String op = nextArgRequired();
94c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
95c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        if (op.equals("size")) {
96c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            runDisplaySize();
97c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } else if (op.equals("density")) {
98c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            runDisplayDensity();
99c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } else if (op.equals("overscan")) {
100c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            runDisplayOverscan();
101d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        } else if (op.equals("scaling")) {
102d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            runDisplayScaling();
103f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        } else if (op.equals("screen-capture")) {
104f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale            runSetScreenCapture();
105f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn        } else if (op.equals("dismiss-keyguard")) {
106f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn            runDismissKeyguard();
1073b716249cc2f94aa9842576b618998c28593be90Robert Carr        } else if (op.equals("surface-trace")) {
1083b716249cc2f94aa9842576b618998c28593be90Robert Carr            runSurfaceTrace();
109c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } else {
11079f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn            showError("Error: unknown command '" + op + "'");
11179f7ec70ebd5758ce54fd5b6fcd60fd27457cba6Dianne Hackborn            return;
112c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
113c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    }
1143b716249cc2f94aa9842576b618998c28593be90Robert Carr
1153b716249cc2f94aa9842576b618998c28593be90Robert Carr    private void runSurfaceTrace() throws Exception {
11658c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr        ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(FileDescriptor.out);
11758c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr        mWm.enableSurfaceTrace(pfd);
1183b716249cc2f94aa9842576b618998c28593be90Robert Carr
1193b716249cc2f94aa9842576b618998c28593be90Robert Carr        try {
12058c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr            // No one is going to wake us up, we are just waiting on SIGINT. Otherwise
12158c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr            // the WM can happily continue writing to our stdout.
12258c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr            synchronized (this) {
12358c3437228b8b7b2ab4e5a80e6406f9c39309053Robert Carr                this.wait();
1243b716249cc2f94aa9842576b618998c28593be90Robert Carr            }
1253b716249cc2f94aa9842576b618998c28593be90Robert Carr        } finally {
1263b716249cc2f94aa9842576b618998c28593be90Robert Carr            mWm.disableSurfaceTrace();
1273b716249cc2f94aa9842576b618998c28593be90Robert Carr        }
1283b716249cc2f94aa9842576b618998c28593be90Robert Carr    }
129c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
130f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale    private void runSetScreenCapture() throws Exception {
131f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        String userIdStr = nextArg();
132f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        String enableStr = nextArg();
133f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        int userId;
134f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        boolean disable;
135f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale
136f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        try {
137f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale            userId = Integer.parseInt(userIdStr);
138f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        } catch (NumberFormatException e) {
139f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale            System.err.println("Error: bad number " + e);
140f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale            return;
141f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        }
142f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale
143f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        disable = !Boolean.parseBoolean(enableStr);
144f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale
145f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        try {
146f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale            mWm.setScreenCaptureDisabled(userId, disable);
147f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        } catch (RemoteException e) {
148f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale            System.err.println("Error: Can't set screen capture " + e);
149f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale        }
150f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale    }
151f5ad42f4324bfb7aa28f0967e2fcc89f55d6e91fWale Ogunwale
152c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    private void runDisplaySize() throws Exception {
153672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn        String size = nextArg();
154c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        int w, h;
155672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn        if (size == null) {
156672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            Point initialSize = new Point();
157672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            Point baseSize = new Point();
158672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            try {
159672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);
160672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);
161672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y);
162672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                if (!initialSize.equals(baseSize)) {
163672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                    System.out.println("Override size: " + baseSize.x + "x" + baseSize.y);
164672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                }
165672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            } catch (RemoteException e) {
166672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            }
167672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            return;
168672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn        } else if ("reset".equals(size)) {
169c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            w = h = -1;
170c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } else {
171c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            int div = size.indexOf('x');
172c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            if (div <= 0 || div >= (size.length()-1)) {
173c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                System.err.println("Error: bad size " + size);
174c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                return;
175c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
176c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            String wstr = size.substring(0, div);
177c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            String hstr = size.substring(div+1);
178c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            try {
179d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                w = parseDimension(wstr);
180d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                h = parseDimension(hstr);
181c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            } catch (NumberFormatException e) {
182c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                System.err.println("Error: bad number " + e);
183c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                return;
184c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
185c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
186c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
187c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        try {
188c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            if (w >= 0 && h >= 0) {
189c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                // TODO(multidisplay): For now Configuration only applies to main screen.
190c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);
191c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            } else {
192c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);
193c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
194c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } catch (RemoteException e) {
195c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
196c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    }
197c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
198c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    private void runDisplayDensity() throws Exception {
199672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn        String densityStr = nextArg();
200c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        int density;
201672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn        if (densityStr == null) {
202672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            try {
203672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                int initialDensity = mWm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);
204672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                int baseDensity = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
205672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                System.out.println("Physical density: " + initialDensity);
206672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                if (initialDensity != baseDensity) {
207672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                    System.out.println("Override density: " + baseDensity);
208672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn                }
209672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            } catch (RemoteException e) {
210672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            }
211672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn            return;
212672cf45de7aa5ad6fd1f75512ee5a451a16c0b39Dianne Hackborn        } else if ("reset".equals(densityStr)) {
213c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            density = -1;
214c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } else {
215c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            try {
216c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                density = Integer.parseInt(densityStr);
217c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            } catch (NumberFormatException e) {
218c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                System.err.println("Error: bad number " + e);
219c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                return;
220c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
221c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            if (density < 72) {
222c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                System.err.println("Error: density must be >= 72");
223c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                return;
224c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
225c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
226c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
227c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        try {
228c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            if (density > 0) {
229c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                // TODO(multidisplay): For now Configuration only applies to main screen.
230df3a7cab8f534584bcef83e222372e1be9be12c5Alan Viverette                mWm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density,
231df3a7cab8f534584bcef83e222372e1be9be12c5Alan Viverette                        UserHandle.USER_CURRENT);
232c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            } else {
233df3a7cab8f534584bcef83e222372e1be9be12c5Alan Viverette                mWm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY,
234df3a7cab8f534584bcef83e222372e1be9be12c5Alan Viverette                        UserHandle.USER_CURRENT);
235c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
236c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } catch (RemoteException e) {
237c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
238c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    }
239c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
240c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    private void runDisplayOverscan() throws Exception {
241c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        String overscanStr = nextArgRequired();
242c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        Rect rect = new Rect();
243c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        if ("reset".equals(overscanStr)) {
244c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            rect.set(0, 0, 0, 0);
245c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } else {
246c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            final Pattern FLATTENED_PATTERN = Pattern.compile(
247c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                    "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)");
248c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            Matcher matcher = FLATTENED_PATTERN.matcher(overscanStr);
249c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            if (!matcher.matches()) {
250c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                System.err.println("Error: bad rectangle arg: " + overscanStr);
251c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn                return;
252c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            }
253c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            rect.left = Integer.parseInt(matcher.group(1));
254c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            rect.top = Integer.parseInt(matcher.group(2));
255c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            rect.right = Integer.parseInt(matcher.group(3));
256c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            rect.bottom = Integer.parseInt(matcher.group(4));
257c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
258c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn
259c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        try {
260c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn            mWm.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right, rect.bottom);
261c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        } catch (RemoteException e) {
262c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn        }
263c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn    }
264d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown
265d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown    private void runDisplayScaling() throws Exception {
266d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        String scalingStr = nextArgRequired();
267d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        if ("auto".equals(scalingStr)) {
268d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 0);
269d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        } else if ("off".equals(scalingStr)) {
270d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
271d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        } else {
272d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            System.err.println("Error: scaling must be 'auto' or 'off'");
273d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        }
274d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown    }
275d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown
276f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn    private void runDismissKeyguard() throws Exception {
277241ae10b2189f449e57d8d660235ac56d8fb1b80Jorim Jaggi        mWm.dismissKeyguard(null /* callback */);
278f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn    }
279f40c66d1a13b7cf88ba06cff10f6343471afd840Tim Kilbourn
280d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown    private int parseDimension(String s) throws NumberFormatException {
281d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        if (s.endsWith("px")) {
282d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            return Integer.parseInt(s.substring(0, s.length() - 2));
283d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        }
284d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        if (s.endsWith("dp")) {
285d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            int density;
286d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            try {
287d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                density = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
288d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            } catch (RemoteException e) {
289d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                density = DisplayMetrics.DENSITY_DEFAULT;
290d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            }
291d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown            return Integer.parseInt(s.substring(0, s.length() - 2)) * density /
292d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown                    DisplayMetrics.DENSITY_DEFAULT;
293d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        }
294d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown        return Integer.parseInt(s);
295d46747a1c64b6ca3282e8841833980ab91829436Jeff Brown    }
296c652de8141f5b8e3c6bcf8916842b6e106413b1aDianne Hackborn}
297