1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm; 18 19 import static android.os.Build.IS_USER; 20 import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED; 21 22 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND; 23 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; 24 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR; 25 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER; 26 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; 27 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; 28 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; 29 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; 30 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; 31 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; 32 33 import android.content.res.Resources.NotFoundException; 34 import android.graphics.Color; 35 import android.graphics.Point; 36 import android.graphics.Rect; 37 import android.os.ParcelFileDescriptor; 38 import android.os.RemoteException; 39 import android.os.ShellCommand; 40 import android.os.UserHandle; 41 import android.provider.Settings; 42 import android.util.DisplayMetrics; 43 import android.util.Pair; 44 import android.util.TypedValue; 45 import android.view.Display; 46 import android.view.IWindow; 47 import android.view.IWindowManager; 48 import android.view.ViewDebug; 49 50 import com.android.internal.os.ByteTransferPipe; 51 import com.android.internal.protolog.ProtoLogImpl; 52 import com.android.server.IoThread; 53 import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType; 54 import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition; 55 import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilityPosition; 56 57 import java.io.IOException; 58 import java.io.PrintWriter; 59 import java.util.ArrayList; 60 import java.util.function.Consumer; 61 import java.util.regex.Matcher; 62 import java.util.regex.Pattern; 63 import java.util.zip.ZipEntry; 64 import java.util.zip.ZipOutputStream; 65 66 /** 67 * ShellCommands for WindowManagerService. 68 * 69 * Use with {@code adb shell cmd window ...}. 70 */ 71 public class WindowManagerShellCommand extends ShellCommand { 72 73 // IPC interface to activity manager -- don't need to do additional security checks. 74 private final IWindowManager mInterface; 75 76 // Internal service impl -- must perform security checks before touching. 77 private final WindowManagerService mInternal; 78 private final LetterboxConfiguration mLetterboxConfiguration; 79 WindowManagerShellCommand(WindowManagerService service)80 public WindowManagerShellCommand(WindowManagerService service) { 81 mInterface = service; 82 mInternal = service; 83 mLetterboxConfiguration = service.mLetterboxConfiguration; 84 } 85 86 @Override onCommand(String cmd)87 public int onCommand(String cmd) { 88 if (cmd == null) { 89 return handleDefaultCommands(cmd); 90 } 91 final PrintWriter pw = getOutPrintWriter(); 92 try { 93 switch (cmd) { 94 case "size": 95 return runDisplaySize(pw); 96 case "density": 97 return runDisplayDensity(pw); 98 case "folded-area": 99 return runDisplayFoldedArea(pw); 100 case "scaling": 101 return runDisplayScaling(pw); 102 case "dismiss-keyguard": 103 return runDismissKeyguard(pw); 104 case "tracing": 105 // XXX this should probably be changed to use openFileForSystem() to create 106 // the output trace file, so the shell gets the correct semantics for where 107 // trace files can be written. 108 return mInternal.mWindowTracing.onShellCommand(this); 109 case "logging": 110 int result = ProtoLogImpl.getSingleInstance().onShellCommand(this); 111 if (result != 0) { 112 pw.println("Not handled, please use " 113 + "`adb shell dumpsys activity service SystemUIService WMShell` " 114 + "if you are looking for ProtoLog in WMShell"); 115 } 116 return result; 117 case "user-rotation": 118 return runDisplayUserRotation(pw); 119 case "fixed-to-user-rotation": 120 return runFixedToUserRotation(pw); 121 case "set-ignore-orientation-request": 122 return runSetIgnoreOrientationRequest(pw); 123 case "get-ignore-orientation-request": 124 return runGetIgnoreOrientationRequest(pw); 125 case "dump-visible-window-views": 126 return runDumpVisibleWindowViews(pw); 127 case "set-letterbox-style": 128 return runSetLetterboxStyle(pw); 129 case "get-letterbox-style": 130 return runGetLetterboxStyle(pw); 131 case "reset-letterbox-style": 132 return runResetLetterboxStyle(pw); 133 case "set-sandbox-display-apis": 134 return runSandboxDisplayApis(pw); 135 case "set-multi-window-config": 136 return runSetMultiWindowConfig(); 137 case "get-multi-window-config": 138 return runGetMultiWindowConfig(pw); 139 case "reset-multi-window-config": 140 return runResetMultiWindowConfig(); 141 case "reset": 142 return runReset(pw); 143 case "disable-blur": 144 return runSetBlurDisabled(pw); 145 case "shell": 146 return runWmShellCommand(pw); 147 default: 148 return handleDefaultCommands(cmd); 149 } 150 } catch (RemoteException e) { 151 pw.println("Remote exception: " + e); 152 } 153 return -1; 154 } 155 getDisplayId(String opt)156 private int getDisplayId(String opt) { 157 int displayId = Display.DEFAULT_DISPLAY; 158 String option = "-d".equals(opt) ? opt : getNextOption(); 159 if (option != null && "-d".equals(option)) { 160 try { 161 displayId = Integer.parseInt(getNextArgRequired()); 162 } catch (NumberFormatException e) { 163 getErrPrintWriter().println("Error: bad number " + e); 164 } catch (IllegalArgumentException e) { 165 getErrPrintWriter().println("Error: " + e); 166 } 167 } 168 return displayId; 169 } 170 printInitialDisplaySize(PrintWriter pw , int displayId)171 private void printInitialDisplaySize(PrintWriter pw , int displayId) { 172 final Point initialSize = new Point(); 173 final Point baseSize = new Point(); 174 175 try { 176 mInterface.getInitialDisplaySize(displayId, initialSize); 177 mInterface.getBaseDisplaySize(displayId, baseSize); 178 pw.println("Physical size: " + initialSize.x + "x" + initialSize.y); 179 if (!initialSize.equals(baseSize)) { 180 pw.println("Override size: " + baseSize.x + "x" + baseSize.y); 181 } 182 } catch (RemoteException e) { 183 // Can't call getInitialDisplaySize() on IWindowManager or 184 // Can't call getBaseDisplaySize() on IWindowManager 185 pw.println("Remote exception: " + e); 186 } 187 } 188 runDisplaySize(PrintWriter pw)189 private int runDisplaySize(PrintWriter pw) throws RemoteException { 190 String size = getNextArg(); 191 int w, h; 192 final int displayId = getDisplayId(size); 193 if (size == null) { 194 printInitialDisplaySize(pw, displayId); 195 return 0; 196 } else if ("-d".equals(size)) { 197 printInitialDisplaySize(pw, displayId); 198 return 0; 199 } else if ("reset".equals(size)) { 200 w = h = -1; 201 } else { 202 int div = size.indexOf('x'); 203 if (div <= 0 || div >= (size.length()-1)) { 204 getErrPrintWriter().println("Error: bad size " + size); 205 return -1; 206 } 207 String wstr = size.substring(0, div); 208 String hstr = size.substring(div+1); 209 try { 210 w = parseDimension(wstr, displayId); 211 h = parseDimension(hstr, displayId); 212 } catch (NumberFormatException e) { 213 getErrPrintWriter().println("Error: bad number " + e); 214 return -1; 215 } 216 } 217 218 if (w >= 0 && h >= 0) { 219 mInterface.setForcedDisplaySize(displayId, w, h); 220 } else { 221 mInterface.clearForcedDisplaySize(displayId); 222 } 223 return 0; 224 } 225 runSetBlurDisabled(PrintWriter pw)226 private int runSetBlurDisabled(PrintWriter pw) throws RemoteException { 227 String arg = getNextArg(); 228 if (arg == null) { 229 pw.println("Blur supported on device: " + CROSS_WINDOW_BLUR_SUPPORTED); 230 pw.println("Blur enabled: " + mInternal.mBlurController.getBlurEnabled()); 231 return 0; 232 } 233 234 final boolean disableBlur; 235 switch (arg) { 236 case "true": 237 case "1": 238 disableBlur = true; 239 break; 240 case "false": 241 case "0": 242 disableBlur = false; 243 break; 244 default: 245 getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg); 246 return -1; 247 } 248 249 Settings.Global.putInt(mInternal.mContext.getContentResolver(), 250 Settings.Global.DISABLE_WINDOW_BLURS, disableBlur ? 1 : 0); 251 252 return 0; 253 } 254 printInitialDisplayDensity(PrintWriter pw , int displayId)255 private void printInitialDisplayDensity(PrintWriter pw , int displayId) { 256 try { 257 final int initialDensity = mInterface.getInitialDisplayDensity(displayId); 258 final int baseDensity = mInterface.getBaseDisplayDensity(displayId); 259 pw.println("Physical density: " + initialDensity); 260 if (initialDensity != baseDensity) { 261 pw.println("Override density: " + baseDensity); 262 } 263 } catch (RemoteException e) { 264 // Can't call getInitialDisplayDensity() on IWindowManager or 265 // Can't call getBaseDisplayDensity() on IWindowManager 266 pw.println("Remote exception: " + e); 267 } 268 } 269 runDisplayDensity(PrintWriter pw)270 private int runDisplayDensity(PrintWriter pw) throws RemoteException { 271 String densityStr = getNextArg(); 272 String option = getNextOption(); 273 String arg = getNextArg(); 274 int density; 275 int displayId = Display.DEFAULT_DISPLAY; 276 if ("-d".equals(option) && arg != null) { 277 try { 278 displayId = Integer.parseInt(arg); 279 } catch (NumberFormatException e) { 280 getErrPrintWriter().println("Error: bad number " + e); 281 } 282 } else if ("-u".equals(option) && arg != null) { 283 displayId = mInterface.getDisplayIdByUniqueId(arg); 284 if (displayId == Display.INVALID_DISPLAY) { 285 getErrPrintWriter().println("Error: the uniqueId is invalid "); 286 return -1; 287 } 288 } 289 290 if (densityStr == null) { 291 printInitialDisplayDensity(pw, displayId); 292 return 0; 293 } else if ("-d".equals(densityStr)) { 294 printInitialDisplayDensity(pw, displayId); 295 return 0; 296 } else if ("reset".equals(densityStr)) { 297 density = -1; 298 } else { 299 try { 300 density = Integer.parseInt(densityStr); 301 } catch (NumberFormatException e) { 302 getErrPrintWriter().println("Error: bad number " + e); 303 return -1; 304 } 305 if (density < 72) { 306 getErrPrintWriter().println("Error: density must be >= 72"); 307 return -1; 308 } 309 } 310 311 if (density > 0) { 312 mInterface.setForcedDisplayDensityForUser(displayId, density, 313 UserHandle.USER_CURRENT); 314 } else { 315 mInterface.clearForcedDisplayDensityForUser(displayId, 316 UserHandle.USER_CURRENT); 317 } 318 return 0; 319 } 320 printFoldedArea(PrintWriter pw)321 private void printFoldedArea(PrintWriter pw) { 322 final Rect foldedArea = mInternal.getFoldedArea(); 323 if (foldedArea.isEmpty()) { 324 pw.println("Folded area: none"); 325 } else { 326 pw.println("Folded area: " + foldedArea.left + "," + foldedArea.top + "," 327 + foldedArea.right + "," + foldedArea.bottom); 328 } 329 } 330 runDisplayFoldedArea(PrintWriter pw)331 private int runDisplayFoldedArea(PrintWriter pw) { 332 final String areaStr = getNextArg(); 333 final Rect rect = new Rect(); 334 if (areaStr == null) { 335 printFoldedArea(pw); 336 return 0; 337 } else if ("reset".equals(areaStr)) { 338 rect.setEmpty(); 339 } else { 340 final Pattern flattenedPattern = Pattern.compile( 341 "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)"); 342 final Matcher matcher = flattenedPattern.matcher(areaStr); 343 if (!matcher.matches()) { 344 getErrPrintWriter().println("Error: area should be LEFT,TOP,RIGHT,BOTTOM"); 345 return -1; 346 } 347 rect.set(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), 348 Integer.parseInt(matcher.group(3)), Integer.parseInt(matcher.group(4))); 349 } 350 351 mInternal.setOverrideFoldedArea(rect); 352 return 0; 353 } 354 runDisplayScaling(PrintWriter pw)355 private int runDisplayScaling(PrintWriter pw) throws RemoteException { 356 String scalingStr = getNextArgRequired(); 357 if ("auto".equals(scalingStr)) { 358 mInterface.setForcedDisplayScalingMode(getDisplayId(scalingStr), 359 DisplayContent.FORCE_SCALING_MODE_AUTO); 360 } else if ("off".equals(scalingStr)) { 361 mInterface.setForcedDisplayScalingMode(getDisplayId(scalingStr), 362 DisplayContent.FORCE_SCALING_MODE_DISABLED); 363 } else { 364 getErrPrintWriter().println("Error: scaling must be 'auto' or 'off'"); 365 return -1; 366 } 367 return 0; 368 } 369 370 /** 371 * Override display size and metrics to reflect the DisplayArea of the calling activity. 372 */ runSandboxDisplayApis(PrintWriter pw)373 private int runSandboxDisplayApis(PrintWriter pw) throws RemoteException { 374 int displayId = Display.DEFAULT_DISPLAY; 375 String arg = getNextArgRequired(); 376 if ("-d".equals(arg)) { 377 displayId = Integer.parseInt(getNextArgRequired()); 378 arg = getNextArgRequired(); 379 } 380 381 final boolean sandboxDisplayApis; 382 switch (arg) { 383 case "true": 384 case "1": 385 sandboxDisplayApis = true; 386 break; 387 case "false": 388 case "0": 389 sandboxDisplayApis = false; 390 break; 391 default: 392 getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we " 393 + "get " + arg); 394 return -1; 395 } 396 397 mInternal.setSandboxDisplayApis(displayId, sandboxDisplayApis); 398 return 0; 399 } 400 runDismissKeyguard(PrintWriter pw)401 private int runDismissKeyguard(PrintWriter pw) throws RemoteException { 402 mInterface.dismissKeyguard(null /* callback */, null /* message */); 403 return 0; 404 } 405 parseDimension(String s, int displayId)406 private int parseDimension(String s, int displayId) throws NumberFormatException { 407 if (s.endsWith("px")) { 408 return Integer.parseInt(s.substring(0, s.length() - 2)); 409 } 410 if (s.endsWith("dp")) { 411 int density; 412 try { 413 density = mInterface.getBaseDisplayDensity(displayId); 414 } catch (RemoteException e) { 415 density = DisplayMetrics.DENSITY_DEFAULT; 416 } 417 return Integer.parseInt(s.substring(0, s.length() - 2)) * density / 418 DisplayMetrics.DENSITY_DEFAULT; 419 } 420 return Integer.parseInt(s); 421 } 422 runDisplayUserRotation(PrintWriter pw)423 private int runDisplayUserRotation(PrintWriter pw) { 424 int displayId = Display.DEFAULT_DISPLAY; 425 String arg = getNextArg(); 426 if (arg == null) { 427 return printDisplayUserRotation(pw, displayId); 428 } 429 430 if ("-d".equals(arg)) { 431 displayId = Integer.parseInt(getNextArgRequired()); 432 arg = getNextArg(); 433 } 434 435 final String lockMode = arg; 436 if (lockMode == null) { 437 return printDisplayUserRotation(pw, displayId); 438 } 439 440 if ("free".equals(lockMode)) { 441 mInternal.thawDisplayRotation(displayId); 442 return 0; 443 } 444 445 if (!"lock".equals(lockMode)) { 446 getErrPrintWriter().println("Error: argument needs to be either -d, free or lock."); 447 return -1; 448 } 449 450 arg = getNextArg(); 451 try { 452 final int rotation = 453 arg != null ? Integer.parseInt(arg) : -1 /* lock to current rotation */; 454 mInternal.freezeDisplayRotation(displayId, rotation); 455 return 0; 456 } catch (IllegalArgumentException e) { 457 getErrPrintWriter().println("Error: " + e.getMessage()); 458 return -1; 459 } 460 } 461 printDisplayUserRotation(PrintWriter pw, int displayId)462 private int printDisplayUserRotation(PrintWriter pw, int displayId) { 463 final int displayUserRotation = mInternal.getDisplayUserRotation(displayId); 464 if (displayUserRotation < 0) { 465 getErrPrintWriter().println("Error: check logcat for more details."); 466 return -1; 467 } 468 if (!mInternal.isDisplayRotationFrozen(displayId)) { 469 pw.println("free"); 470 return 0; 471 } 472 pw.print("lock "); 473 pw.println(displayUserRotation); 474 return 0; 475 } 476 runFixedToUserRotation(PrintWriter pw)477 private int runFixedToUserRotation(PrintWriter pw) throws RemoteException { 478 int displayId = Display.DEFAULT_DISPLAY; 479 String arg = getNextArg(); 480 if (arg == null) { 481 printFixedToUserRotation(pw, displayId); 482 return 0; 483 } 484 485 if ("-d".equals(arg)) { 486 displayId = Integer.parseInt(getNextArgRequired()); 487 arg = getNextArg(); 488 } 489 490 if (arg == null) { 491 return printFixedToUserRotation(pw, displayId); 492 } 493 494 final int fixedToUserRotation; 495 switch (arg) { 496 case "enabled": 497 fixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_ENABLED; 498 break; 499 case "disabled": 500 fixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DISABLED; 501 break; 502 case "default": 503 fixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT; 504 break; 505 default: 506 getErrPrintWriter().println("Error: expecting enabled, disabled or default, but we " 507 + "get " + arg); 508 return -1; 509 } 510 511 mInterface.setFixedToUserRotation(displayId, fixedToUserRotation); 512 return 0; 513 } 514 printFixedToUserRotation(PrintWriter pw, int displayId)515 private int printFixedToUserRotation(PrintWriter pw, int displayId) { 516 int fixedToUserRotationMode = mInternal.getFixedToUserRotation(displayId); 517 switch (fixedToUserRotationMode) { 518 case IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT: 519 pw.println("default"); 520 return 0; 521 case IWindowManager.FIXED_TO_USER_ROTATION_DISABLED: 522 pw.println("disabled"); 523 return 0; 524 case IWindowManager.FIXED_TO_USER_ROTATION_ENABLED: 525 pw.println("enabled"); 526 return 0; 527 default: 528 getErrPrintWriter().println("Error: check logcat for more details."); 529 return -1; 530 } 531 } 532 runSetIgnoreOrientationRequest(PrintWriter pw)533 private int runSetIgnoreOrientationRequest(PrintWriter pw) throws RemoteException { 534 int displayId = Display.DEFAULT_DISPLAY; 535 String arg = getNextArgRequired(); 536 if ("-d".equals(arg)) { 537 displayId = Integer.parseInt(getNextArgRequired()); 538 arg = getNextArgRequired(); 539 } 540 541 final boolean ignoreOrientationRequest; 542 switch (arg) { 543 case "true": 544 case "1": 545 ignoreOrientationRequest = true; 546 break; 547 case "false": 548 case "0": 549 ignoreOrientationRequest = false; 550 break; 551 default: 552 getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we " 553 + "get " + arg); 554 return -1; 555 } 556 557 mInterface.setIgnoreOrientationRequest(displayId, ignoreOrientationRequest); 558 return 0; 559 } 560 runGetIgnoreOrientationRequest(PrintWriter pw)561 private int runGetIgnoreOrientationRequest(PrintWriter pw) throws RemoteException { 562 int displayId = Display.DEFAULT_DISPLAY; 563 String arg = getNextArg(); 564 if ("-d".equals(arg)) { 565 displayId = Integer.parseInt(getNextArgRequired()); 566 } 567 568 final boolean ignoreOrientationRequest = mInternal.getIgnoreOrientationRequest(displayId); 569 pw.println("ignoreOrientationRequest " + ignoreOrientationRequest 570 + " for displayId=" + displayId); 571 return 0; 572 } 573 dumpLocalWindowAsync(IWindow client, ParcelFileDescriptor pfd)574 private void dumpLocalWindowAsync(IWindow client, ParcelFileDescriptor pfd) { 575 // Make it asynchronous to avoid writer from being blocked 576 // by waiting for the buffer to be consumed in the same process. 577 IoThread.getExecutor().execute(() -> { 578 synchronized (mInternal.mGlobalLock) { 579 try { 580 client.executeCommand(ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd); 581 } catch (Exception e) { 582 // Ignore RemoteException for local call. Just print trace for other 583 // exceptions caused by RC with tolerable low possibility. 584 e.printStackTrace(); 585 } 586 } 587 }); 588 } 589 runDumpVisibleWindowViews(PrintWriter pw)590 private int runDumpVisibleWindowViews(PrintWriter pw) { 591 if (!mInternal.checkCallingPermission(android.Manifest.permission.DUMP, 592 "runDumpVisibleWindowViews()")) { 593 throw new SecurityException("Requires DUMP permission"); 594 } 595 596 try (ZipOutputStream out = new ZipOutputStream(getRawOutputStream())) { 597 ArrayList<Pair<String, ByteTransferPipe>> requestList = new ArrayList<>(); 598 synchronized (mInternal.mGlobalLock) { 599 final RecentTasks recentTasks = mInternal.mAtmService.getRecentTasks(); 600 final int recentsComponentUid = recentTasks != null 601 ? recentTasks.getRecentsComponentUid() 602 : -1; 603 // Request dump from all windows parallelly before writing to disk. 604 mInternal.mRoot.forAllWindows(w -> { 605 final boolean isRecents = (w.getUid() == recentsComponentUid); 606 if (w.isVisible() || isRecents) { 607 ByteTransferPipe pipe = null; 608 try { 609 pipe = new ByteTransferPipe(); 610 final ParcelFileDescriptor pfd = pipe.getWriteFd(); 611 if (w.isClientLocal()) { 612 dumpLocalWindowAsync(w.mClient, pfd); 613 } else { 614 w.mClient.executeCommand( 615 ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd); 616 } 617 requestList.add(Pair.create(w.getName(), pipe)); 618 } catch (IOException | RemoteException e) { 619 // Skip this window 620 if (pipe != null) { 621 pipe.kill(); 622 } 623 } 624 } 625 }, false /* traverseTopToBottom */); 626 } 627 for (Pair<String, ByteTransferPipe> entry : requestList) { 628 byte[] data; 629 try { 630 data = entry.second.get(); 631 } catch (IOException e) { 632 // Ignore this window 633 continue; 634 } 635 out.putNextEntry(new ZipEntry(entry.first)); 636 out.write(data); 637 } 638 } catch (IOException e) { 639 pw.println("Error fetching dump " + e.getMessage()); 640 } 641 return 0; 642 } 643 runSetFixedOrientationLetterboxAspectRatio(PrintWriter pw)644 private int runSetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException { 645 final float aspectRatio; 646 try { 647 String arg = getNextArgRequired(); 648 aspectRatio = Float.parseFloat(arg); 649 } catch (NumberFormatException e) { 650 getErrPrintWriter().println("Error: bad aspect ratio format " + e); 651 return -1; 652 } catch (IllegalArgumentException e) { 653 getErrPrintWriter().println( 654 "Error: aspect ratio should be provided as an argument " + e); 655 return -1; 656 } 657 synchronized (mInternal.mGlobalLock) { 658 mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(aspectRatio); 659 } 660 return 0; 661 } 662 runSetDefaultMinAspectRatioForUnresizableApps(PrintWriter pw)663 private int runSetDefaultMinAspectRatioForUnresizableApps(PrintWriter pw) 664 throws RemoteException { 665 final float aspectRatio; 666 try { 667 String arg = getNextArgRequired(); 668 aspectRatio = Float.parseFloat(arg); 669 } catch (NumberFormatException e) { 670 getErrPrintWriter().println("Error: bad aspect ratio format " + e); 671 return -1; 672 } catch (IllegalArgumentException e) { 673 getErrPrintWriter().println( 674 "Error: aspect ratio should be provided as an argument " + e); 675 return -1; 676 } 677 synchronized (mInternal.mGlobalLock) { 678 mLetterboxConfiguration.setDefaultMinAspectRatioForUnresizableApps(aspectRatio); 679 } 680 return 0; 681 } 682 runSetLetterboxActivityCornersRadius(PrintWriter pw)683 private int runSetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException { 684 final int cornersRadius; 685 try { 686 String arg = getNextArgRequired(); 687 cornersRadius = Integer.parseInt(arg); 688 } catch (NumberFormatException e) { 689 getErrPrintWriter().println("Error: bad corners radius format " + e); 690 return -1; 691 } catch (IllegalArgumentException e) { 692 getErrPrintWriter().println( 693 "Error: corners radius should be provided as an argument " + e); 694 return -1; 695 } 696 synchronized (mInternal.mGlobalLock) { 697 mLetterboxConfiguration.setLetterboxActivityCornersRadius(cornersRadius); 698 } 699 return 0; 700 } 701 runSetLetterboxBackgroundType(PrintWriter pw)702 private int runSetLetterboxBackgroundType(PrintWriter pw) throws RemoteException { 703 @LetterboxBackgroundType final int backgroundType; 704 try { 705 String arg = getNextArgRequired(); 706 switch (arg) { 707 case "solid_color": 708 backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR; 709 break; 710 case "app_color_background": 711 backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND; 712 break; 713 case "app_color_background_floating": 714 backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; 715 break; 716 case "wallpaper": 717 backgroundType = LETTERBOX_BACKGROUND_WALLPAPER; 718 break; 719 default: 720 getErrPrintWriter().println( 721 "Error: 'solid_color', 'app_color_background' or " 722 + "'wallpaper' should be provided as an argument"); 723 return -1; 724 } 725 } catch (IllegalArgumentException e) { 726 getErrPrintWriter().println( 727 "Error: 'solid_color', 'app_color_background' or " 728 + "'wallpaper' should be provided as an argument" + e); 729 return -1; 730 } 731 synchronized (mInternal.mGlobalLock) { 732 mLetterboxConfiguration.setLetterboxBackgroundTypeOverride(backgroundType); 733 } 734 return 0; 735 } 736 runSetLetterboxBackgroundColorResource(PrintWriter pw)737 private int runSetLetterboxBackgroundColorResource(PrintWriter pw) throws RemoteException { 738 final int colorId; 739 try { 740 String arg = getNextArgRequired(); 741 colorId = mInternal.mContext.getResources() 742 .getIdentifier(arg, "color", "com.android.internal"); 743 } catch (NotFoundException e) { 744 getErrPrintWriter().println( 745 "Error: color in '@android:color/resource_name' format should be provided as " 746 + "an argument " + e); 747 return -1; 748 } 749 synchronized (mInternal.mGlobalLock) { 750 mLetterboxConfiguration.setLetterboxBackgroundColorResourceId(colorId); 751 } 752 return 0; 753 } 754 runSetLetterboxBackgroundColor(PrintWriter pw)755 private int runSetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException { 756 final Color color; 757 try { 758 String arg = getNextArgRequired(); 759 color = Color.valueOf(Color.parseColor(arg)); 760 } catch (IllegalArgumentException e) { 761 getErrPrintWriter().println( 762 "Error: color in #RRGGBB format should be provided as " 763 + "an argument " + e); 764 return -1; 765 } 766 synchronized (mInternal.mGlobalLock) { 767 mLetterboxConfiguration.setLetterboxBackgroundColor(color); 768 } 769 return 0; 770 } 771 runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)772 private int runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw) 773 throws RemoteException { 774 final int radiusDp; 775 try { 776 String arg = getNextArgRequired(); 777 radiusDp = Integer.parseInt(arg); 778 } catch (NumberFormatException e) { 779 getErrPrintWriter().println("Error: blur radius format " + e); 780 return -1; 781 } catch (IllegalArgumentException e) { 782 getErrPrintWriter().println( 783 "Error: blur radius should be provided as an argument " + e); 784 return -1; 785 } 786 synchronized (mInternal.mGlobalLock) { 787 final int radiusPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 788 radiusDp, mInternal.mContext.getResources().getDisplayMetrics()); 789 mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadiusPx(radiusPx); 790 } 791 return 0; 792 } 793 runSetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)794 private int runSetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw) 795 throws RemoteException { 796 final float alpha; 797 try { 798 String arg = getNextArgRequired(); 799 alpha = Float.parseFloat(arg); 800 } catch (NumberFormatException e) { 801 getErrPrintWriter().println("Error: bad alpha format " + e); 802 return -1; 803 } catch (IllegalArgumentException e) { 804 getErrPrintWriter().println( 805 "Error: alpha should be provided as an argument " + e); 806 return -1; 807 } 808 synchronized (mInternal.mGlobalLock) { 809 mLetterboxConfiguration.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha); 810 } 811 return 0; 812 } 813 runSetLetterboxHorizontalPositionMultiplier(PrintWriter pw)814 private int runSetLetterboxHorizontalPositionMultiplier(PrintWriter pw) throws RemoteException { 815 final float multiplier; 816 try { 817 String arg = getNextArgRequired(); 818 multiplier = Float.parseFloat(arg); 819 } catch (NumberFormatException e) { 820 getErrPrintWriter().println("Error: bad multiplier format " + e); 821 return -1; 822 } catch (IllegalArgumentException e) { 823 getErrPrintWriter().println( 824 "Error: multiplier should be provided as an argument " + e); 825 return -1; 826 } 827 synchronized (mInternal.mGlobalLock) { 828 mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(multiplier); 829 } 830 return 0; 831 } 832 runSetLetterboxVerticalPositionMultiplier(PrintWriter pw)833 private int runSetLetterboxVerticalPositionMultiplier(PrintWriter pw) throws RemoteException { 834 final float multiplier; 835 try { 836 String arg = getNextArgRequired(); 837 multiplier = Float.parseFloat(arg); 838 } catch (NumberFormatException e) { 839 getErrPrintWriter().println("Error: bad multiplier format " + e); 840 return -1; 841 } catch (IllegalArgumentException e) { 842 getErrPrintWriter().println( 843 "Error: multiplier should be provided as an argument " + e); 844 return -1; 845 } 846 synchronized (mInternal.mGlobalLock) { 847 mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(multiplier); 848 } 849 return 0; 850 } 851 runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw)852 private int runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw) 853 throws RemoteException { 854 @LetterboxHorizontalReachabilityPosition final int position; 855 try { 856 String arg = getNextArgRequired(); 857 switch (arg) { 858 case "left": 859 position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; 860 break; 861 case "center": 862 position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; 863 break; 864 case "right": 865 position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; 866 break; 867 default: 868 getErrPrintWriter().println( 869 "Error: 'left', 'center' or 'right' are expected as an argument"); 870 return -1; 871 } 872 } catch (IllegalArgumentException e) { 873 getErrPrintWriter().println( 874 "Error: 'left', 'center' or 'right' are expected as an argument" + e); 875 return -1; 876 } 877 synchronized (mInternal.mGlobalLock) { 878 mLetterboxConfiguration.setDefaultPositionForHorizontalReachability(position); 879 } 880 return 0; 881 } 882 runSetLetterboxDefaultPositionForVerticalReachability(PrintWriter pw)883 private int runSetLetterboxDefaultPositionForVerticalReachability(PrintWriter pw) 884 throws RemoteException { 885 @LetterboxVerticalReachabilityPosition final int position; 886 try { 887 String arg = getNextArgRequired(); 888 switch (arg) { 889 case "top": 890 position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; 891 break; 892 case "center": 893 position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; 894 break; 895 case "bottom": 896 position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; 897 break; 898 default: 899 getErrPrintWriter().println( 900 "Error: 'top', 'center' or 'bottom' are expected as an argument"); 901 return -1; 902 } 903 } catch (IllegalArgumentException e) { 904 getErrPrintWriter().println( 905 "Error: 'top', 'center' or 'bottom' are expected as an argument" + e); 906 return -1; 907 } 908 synchronized (mInternal.mGlobalLock) { 909 mLetterboxConfiguration.setDefaultPositionForVerticalReachability(position); 910 } 911 return 0; 912 } 913 runSetPersistentLetterboxPositionForHorizontalReachability(PrintWriter pw)914 private int runSetPersistentLetterboxPositionForHorizontalReachability(PrintWriter pw) 915 throws RemoteException { 916 @LetterboxHorizontalReachabilityPosition final int position; 917 try { 918 String arg = getNextArgRequired(); 919 switch (arg) { 920 case "left": 921 position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; 922 break; 923 case "center": 924 position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; 925 break; 926 case "right": 927 position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; 928 break; 929 default: 930 getErrPrintWriter().println( 931 "Error: 'left', 'center' or 'right' are expected as an argument"); 932 return -1; 933 } 934 } catch (IllegalArgumentException e) { 935 getErrPrintWriter().println( 936 "Error: 'left', 'center' or 'right' are expected as an argument" + e); 937 return -1; 938 } 939 synchronized (mInternal.mGlobalLock) { 940 mLetterboxConfiguration.setPersistentLetterboxPositionForHorizontalReachability( 941 false /* IsInBookMode */, position); 942 } 943 return 0; 944 } 945 runSetPersistentLetterboxPositionForVerticalReachability(PrintWriter pw)946 private int runSetPersistentLetterboxPositionForVerticalReachability(PrintWriter pw) 947 throws RemoteException { 948 @LetterboxVerticalReachabilityPosition final int position; 949 try { 950 String arg = getNextArgRequired(); 951 switch (arg) { 952 case "top": 953 position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; 954 break; 955 case "center": 956 position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; 957 break; 958 case "bottom": 959 position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; 960 break; 961 default: 962 getErrPrintWriter().println( 963 "Error: 'top', 'center' or 'bottom' are expected as an argument"); 964 return -1; 965 } 966 } catch (IllegalArgumentException e) { 967 getErrPrintWriter().println( 968 "Error: 'top', 'center' or 'bottom' are expected as an argument" + e); 969 return -1; 970 } 971 synchronized (mInternal.mGlobalLock) { 972 mLetterboxConfiguration.setPersistentLetterboxPositionForVerticalReachability( 973 false /* forTabletopMode */, position); 974 } 975 return 0; 976 } 977 runSetBooleanFlag(PrintWriter pw, Consumer<Boolean> setter)978 private int runSetBooleanFlag(PrintWriter pw, Consumer<Boolean> setter) 979 throws RemoteException { 980 String arg = getNextArg(); 981 if (arg == null) { 982 getErrPrintWriter().println("Error: expected true, 1, false, 0, but got empty input."); 983 return -1; 984 } 985 final boolean enabled; 986 switch (arg) { 987 case "true": 988 case "1": 989 enabled = true; 990 break; 991 case "false": 992 case "0": 993 enabled = false; 994 break; 995 default: 996 getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg); 997 return -1; 998 } 999 1000 synchronized (mInternal.mGlobalLock) { 1001 setter.accept(enabled); 1002 } 1003 return 0; 1004 } 1005 runSetLetterboxStyle(PrintWriter pw)1006 private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException { 1007 if (peekNextArg() == null) { 1008 getErrPrintWriter().println("Error: No arguments provided."); 1009 } 1010 while (peekNextArg() != null) { 1011 String arg = getNextArg(); 1012 switch (arg) { 1013 case "--aspectRatio": 1014 runSetFixedOrientationLetterboxAspectRatio(pw); 1015 break; 1016 case "--minAspectRatioForUnresizable": 1017 runSetDefaultMinAspectRatioForUnresizableApps(pw); 1018 break; 1019 case "--cornerRadius": 1020 runSetLetterboxActivityCornersRadius(pw); 1021 break; 1022 case "--backgroundType": 1023 runSetLetterboxBackgroundType(pw); 1024 break; 1025 case "--backgroundColor": 1026 runSetLetterboxBackgroundColor(pw); 1027 break; 1028 case "--backgroundColorResource": 1029 runSetLetterboxBackgroundColorResource(pw); 1030 break; 1031 case "--wallpaperBlurRadius": 1032 runSetLetterboxBackgroundWallpaperBlurRadius(pw); 1033 break; 1034 case "--wallpaperDarkScrimAlpha": 1035 runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw); 1036 break; 1037 case "--horizontalPositionMultiplier": 1038 runSetLetterboxHorizontalPositionMultiplier(pw); 1039 break; 1040 case "--verticalPositionMultiplier": 1041 runSetLetterboxVerticalPositionMultiplier(pw); 1042 break; 1043 case "--isHorizontalReachabilityEnabled": 1044 runSetBooleanFlag(pw, mLetterboxConfiguration 1045 ::setIsHorizontalReachabilityEnabled); 1046 break; 1047 case "--isVerticalReachabilityEnabled": 1048 runSetBooleanFlag(pw, mLetterboxConfiguration 1049 ::setIsVerticalReachabilityEnabled); 1050 break; 1051 case "--isAutomaticReachabilityInBookModeEnabled": 1052 runSetBooleanFlag(pw, mLetterboxConfiguration 1053 ::setIsAutomaticReachabilityInBookModeEnabled); 1054 break; 1055 case "--defaultPositionForHorizontalReachability": 1056 runSetLetterboxDefaultPositionForHorizontalReachability(pw); 1057 break; 1058 case "--defaultPositionForVerticalReachability": 1059 runSetLetterboxDefaultPositionForVerticalReachability(pw); 1060 break; 1061 case "--persistentPositionForHorizontalReachability": 1062 runSetPersistentLetterboxPositionForHorizontalReachability(pw); 1063 break; 1064 case "--persistentPositionForVerticalReachability": 1065 runSetPersistentLetterboxPositionForVerticalReachability(pw); 1066 break; 1067 case "--isEducationEnabled": 1068 runSetBooleanFlag(pw, mLetterboxConfiguration::setIsEducationEnabled); 1069 break; 1070 case "--isSplitScreenAspectRatioForUnresizableAppsEnabled": 1071 runSetBooleanFlag(pw, mLetterboxConfiguration 1072 ::setIsSplitScreenAspectRatioForUnresizableAppsEnabled); 1073 break; 1074 case "--isDisplayAspectRatioEnabledForFixedOrientationLetterbox": 1075 runSetBooleanFlag(pw, mLetterboxConfiguration 1076 ::setIsDisplayAspectRatioEnabledForFixedOrientationLetterbox); 1077 break; 1078 case "--isTranslucentLetterboxingEnabled": 1079 runSetBooleanFlag(pw, mLetterboxConfiguration 1080 ::setTranslucentLetterboxingOverrideEnabled); 1081 break; 1082 case "--isUserAppAspectRatioSettingsEnabled": 1083 runSetBooleanFlag(pw, mLetterboxConfiguration 1084 ::setUserAppAspectRatioSettingsOverrideEnabled); 1085 break; 1086 case "--isUserAppAspectRatioFullscreenEnabled": 1087 runSetBooleanFlag(pw, mLetterboxConfiguration 1088 ::setUserAppAspectRatioFullscreenOverrideEnabled); 1089 break; 1090 case "--isCameraCompatRefreshEnabled": 1091 runSetBooleanFlag(pw, mLetterboxConfiguration::setCameraCompatRefreshEnabled); 1092 break; 1093 case "--isCameraCompatRefreshCycleThroughStopEnabled": 1094 runSetBooleanFlag(pw, 1095 mLetterboxConfiguration::setCameraCompatRefreshCycleThroughStopEnabled); 1096 break; 1097 default: 1098 getErrPrintWriter().println( 1099 "Error: Unrecognized letterbox style option: " + arg); 1100 return -1; 1101 } 1102 } 1103 return 0; 1104 } 1105 runResetLetterboxStyle(PrintWriter pw)1106 private int runResetLetterboxStyle(PrintWriter pw) throws RemoteException { 1107 if (peekNextArg() == null) { 1108 resetLetterboxStyle(); 1109 } 1110 synchronized (mInternal.mGlobalLock) { 1111 while (peekNextArg() != null) { 1112 String arg = getNextArg(); 1113 switch (arg) { 1114 case "aspectRatio": 1115 mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio(); 1116 break; 1117 case "minAspectRatioForUnresizable": 1118 mLetterboxConfiguration.resetDefaultMinAspectRatioForUnresizableApps(); 1119 break; 1120 case "cornerRadius": 1121 mLetterboxConfiguration.resetLetterboxActivityCornersRadius(); 1122 break; 1123 case "backgroundType": 1124 mLetterboxConfiguration.resetLetterboxBackgroundType(); 1125 break; 1126 case "backgroundColor": 1127 mLetterboxConfiguration.resetLetterboxBackgroundColor(); 1128 break; 1129 case "wallpaperBlurRadius": 1130 mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadiusPx(); 1131 break; 1132 case "wallpaperDarkScrimAlpha": 1133 mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha(); 1134 break; 1135 case "horizontalPositionMultiplier": 1136 mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); 1137 break; 1138 case "verticalPositionMultiplier": 1139 mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier(); 1140 break; 1141 case "isHorizontalReachabilityEnabled": 1142 mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled(); 1143 break; 1144 case "isVerticalReachabilityEnabled": 1145 mLetterboxConfiguration.resetIsVerticalReachabilityEnabled(); 1146 break; 1147 case "defaultPositionForHorizontalReachability": 1148 mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability(); 1149 break; 1150 case "defaultPositionForVerticalReachability": 1151 mLetterboxConfiguration.resetDefaultPositionForVerticalReachability(); 1152 break; 1153 case "persistentPositionForHorizontalReachability": 1154 mLetterboxConfiguration 1155 .resetPersistentLetterboxPositionForHorizontalReachability(); 1156 break; 1157 case "persistentPositionForVerticalReachability": 1158 mLetterboxConfiguration 1159 .resetPersistentLetterboxPositionForVerticalReachability(); 1160 break; 1161 case "isEducationEnabled": 1162 mLetterboxConfiguration.resetIsEducationEnabled(); 1163 break; 1164 case "isSplitScreenAspectRatioForUnresizableAppsEnabled": 1165 mLetterboxConfiguration 1166 .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled(); 1167 break; 1168 case "IsDisplayAspectRatioEnabledForFixedOrientationLetterbox": 1169 mLetterboxConfiguration 1170 .resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(); 1171 break; 1172 case "isTranslucentLetterboxingEnabled": 1173 mLetterboxConfiguration.resetTranslucentLetterboxingEnabled(); 1174 break; 1175 case "isUserAppAspectRatioSettingsEnabled": 1176 mLetterboxConfiguration.resetUserAppAspectRatioSettingsEnabled(); 1177 break; 1178 case "isUserAppAspectRatioFullscreenEnabled": 1179 mLetterboxConfiguration.resetUserAppAspectRatioFullscreenEnabled(); 1180 break; 1181 case "isCameraCompatRefreshEnabled": 1182 mLetterboxConfiguration.resetCameraCompatRefreshEnabled(); 1183 break; 1184 case "isCameraCompatRefreshCycleThroughStopEnabled": 1185 mLetterboxConfiguration 1186 .resetCameraCompatRefreshCycleThroughStopEnabled(); 1187 break; 1188 default: 1189 getErrPrintWriter().println( 1190 "Error: Unrecognized letterbox style option: " + arg); 1191 return -1; 1192 } 1193 } 1194 } 1195 return 0; 1196 } 1197 runSetMultiWindowConfig()1198 private int runSetMultiWindowConfig() { 1199 if (peekNextArg() == null) { 1200 getErrPrintWriter().println("Error: No arguments provided."); 1201 } 1202 int result = 0; 1203 while (peekNextArg() != null) { 1204 String arg = getNextArg(); 1205 switch (arg) { 1206 case "--supportsNonResizable": 1207 result += runSetSupportsNonResizableMultiWindow(); 1208 break; 1209 case "--respectsActivityMinWidthHeight": 1210 result += runSetRespectsActivityMinWidthHeightMultiWindow(); 1211 break; 1212 default: 1213 getErrPrintWriter().println( 1214 "Error: Unrecognized multi window option: " + arg); 1215 return -1; 1216 } 1217 } 1218 return result == 0 ? 0 : -1; 1219 } 1220 runSetSupportsNonResizableMultiWindow()1221 private int runSetSupportsNonResizableMultiWindow() { 1222 final String arg = getNextArg(); 1223 if (!arg.equals("-1") && !arg.equals("0") && !arg.equals("1")) { 1224 getErrPrintWriter().println("Error: a config value of [-1, 0, 1] must be provided as" 1225 + " an argument for supportsNonResizableMultiWindow"); 1226 return -1; 1227 } 1228 final int configValue = Integer.parseInt(arg); 1229 synchronized (mInternal.mAtmService.mGlobalLock) { 1230 mInternal.mAtmService.mSupportsNonResizableMultiWindow = configValue; 1231 } 1232 return 0; 1233 } 1234 runSetRespectsActivityMinWidthHeightMultiWindow()1235 private int runSetRespectsActivityMinWidthHeightMultiWindow() { 1236 final String arg = getNextArg(); 1237 if (!arg.equals("-1") && !arg.equals("0") && !arg.equals("1")) { 1238 getErrPrintWriter().println("Error: a config value of [-1, 0, 1] must be provided as" 1239 + " an argument for respectsActivityMinWidthHeightMultiWindow"); 1240 return -1; 1241 } 1242 final int configValue = Integer.parseInt(arg); 1243 synchronized (mInternal.mAtmService.mGlobalLock) { 1244 mInternal.mAtmService.mRespectsActivityMinWidthHeightMultiWindow = configValue; 1245 } 1246 return 0; 1247 } 1248 runGetMultiWindowConfig(PrintWriter pw)1249 private int runGetMultiWindowConfig(PrintWriter pw) { 1250 synchronized (mInternal.mAtmService.mGlobalLock) { 1251 pw.println("Supports non-resizable in multi window: " 1252 + mInternal.mAtmService.mSupportsNonResizableMultiWindow); 1253 pw.println("Respects activity min width/height in multi window: " 1254 + mInternal.mAtmService.mRespectsActivityMinWidthHeightMultiWindow); 1255 } 1256 return 0; 1257 } 1258 runResetMultiWindowConfig()1259 private int runResetMultiWindowConfig() { 1260 final int supportsNonResizable = mInternal.mContext.getResources().getInteger( 1261 com.android.internal.R.integer.config_supportsNonResizableMultiWindow); 1262 final int respectsActivityMinWidthHeight = mInternal.mContext.getResources().getInteger( 1263 com.android.internal.R.integer.config_respectsActivityMinWidthHeightMultiWindow); 1264 synchronized (mInternal.mAtmService.mGlobalLock) { 1265 mInternal.mAtmService.mSupportsNonResizableMultiWindow = supportsNonResizable; 1266 mInternal.mAtmService.mRespectsActivityMinWidthHeightMultiWindow = 1267 respectsActivityMinWidthHeight; 1268 } 1269 return 0; 1270 } 1271 resetLetterboxStyle()1272 private void resetLetterboxStyle() { 1273 synchronized (mInternal.mGlobalLock) { 1274 mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio(); 1275 mLetterboxConfiguration.resetDefaultMinAspectRatioForUnresizableApps(); 1276 mLetterboxConfiguration.resetLetterboxActivityCornersRadius(); 1277 mLetterboxConfiguration.resetLetterboxBackgroundType(); 1278 mLetterboxConfiguration.resetLetterboxBackgroundColor(); 1279 mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadiusPx(); 1280 mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha(); 1281 mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); 1282 mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier(); 1283 mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled(); 1284 mLetterboxConfiguration.resetIsVerticalReachabilityEnabled(); 1285 mLetterboxConfiguration.resetEnabledAutomaticReachabilityInBookMode(); 1286 mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability(); 1287 mLetterboxConfiguration.resetDefaultPositionForVerticalReachability(); 1288 mLetterboxConfiguration.resetPersistentLetterboxPositionForHorizontalReachability(); 1289 mLetterboxConfiguration.resetPersistentLetterboxPositionForVerticalReachability(); 1290 mLetterboxConfiguration.resetIsEducationEnabled(); 1291 mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled(); 1292 mLetterboxConfiguration.resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(); 1293 mLetterboxConfiguration.resetTranslucentLetterboxingEnabled(); 1294 mLetterboxConfiguration.resetUserAppAspectRatioSettingsEnabled(); 1295 mLetterboxConfiguration.resetUserAppAspectRatioFullscreenEnabled(); 1296 mLetterboxConfiguration.resetCameraCompatRefreshEnabled(); 1297 mLetterboxConfiguration.resetCameraCompatRefreshCycleThroughStopEnabled(); 1298 } 1299 } 1300 runGetLetterboxStyle(PrintWriter pw)1301 private int runGetLetterboxStyle(PrintWriter pw) throws RemoteException { 1302 synchronized (mInternal.mGlobalLock) { 1303 pw.println("Corner radius: " 1304 + mLetterboxConfiguration.getLetterboxActivityCornersRadius()); 1305 pw.println("Horizontal position multiplier: " 1306 + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier( 1307 false /* isInBookMode */)); 1308 pw.println("Vertical position multiplier: " 1309 + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier( 1310 false /* isInTabletopMode */)); 1311 pw.println("Horizontal position multiplier (book mode): " 1312 + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier( 1313 true /* isInBookMode */)); 1314 pw.println("Vertical position multiplier (tabletop mode): " 1315 + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier( 1316 true /* isInTabletopMode */)); 1317 pw.println("Horizontal position multiplier for reachability: " 1318 + mLetterboxConfiguration.getHorizontalMultiplierForReachability( 1319 false /* isInBookMode */)); 1320 pw.println("Vertical position multiplier for reachability: " 1321 + mLetterboxConfiguration.getVerticalMultiplierForReachability( 1322 false /* isInTabletopMode */)); 1323 pw.println("Aspect ratio: " 1324 + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio()); 1325 pw.println("Default min aspect ratio for unresizable apps: " 1326 + mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()); 1327 pw.println("Is horizontal reachability enabled: " 1328 + mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()); 1329 pw.println("Is vertical reachability enabled: " 1330 + mLetterboxConfiguration.getIsVerticalReachabilityEnabled()); 1331 pw.println("Is automatic reachability in book mode enabled: " 1332 + mLetterboxConfiguration.getIsAutomaticReachabilityInBookModeEnabled()); 1333 pw.println("Default position for horizontal reachability: " 1334 + LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString( 1335 mLetterboxConfiguration.getDefaultPositionForHorizontalReachability())); 1336 pw.println("Default position for vertical reachability: " 1337 + LetterboxConfiguration.letterboxVerticalReachabilityPositionToString( 1338 mLetterboxConfiguration.getDefaultPositionForVerticalReachability())); 1339 pw.println("Current position for horizontal reachability:" 1340 + LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString( 1341 mLetterboxConfiguration.getLetterboxPositionForHorizontalReachability(false))); 1342 pw.println("Current position for vertical reachability:" 1343 + LetterboxConfiguration.letterboxVerticalReachabilityPositionToString( 1344 mLetterboxConfiguration.getLetterboxPositionForVerticalReachability(false))); 1345 pw.println("Is education enabled: " 1346 + mLetterboxConfiguration.getIsEducationEnabled()); 1347 pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: " 1348 + mLetterboxConfiguration 1349 .getIsSplitScreenAspectRatioForUnresizableAppsEnabled()); 1350 pw.println("Is using display aspect ratio as aspect ratio for all letterboxed apps: " 1351 + mLetterboxConfiguration 1352 .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()); 1353 pw.println(" Is activity \"refresh\" in camera compatibility treatment enabled: " 1354 + mLetterboxConfiguration.isCameraCompatRefreshEnabled()); 1355 pw.println(" Refresh using \"stopped -> resumed\" cycle: " 1356 + mLetterboxConfiguration.isCameraCompatRefreshCycleThroughStopEnabled()); 1357 pw.println("Background type: " 1358 + LetterboxConfiguration.letterboxBackgroundTypeToString( 1359 mLetterboxConfiguration.getLetterboxBackgroundType())); 1360 pw.println(" Background color: " + Integer.toHexString( 1361 mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb())); 1362 pw.println(" Wallpaper blur radius: " 1363 + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadiusPx()); 1364 pw.println(" Wallpaper dark scrim alpha: " 1365 + mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha()); 1366 pw.println("Is letterboxing for translucent activities enabled: " 1367 + mLetterboxConfiguration.isTranslucentLetterboxingEnabled()); 1368 pw.println("Is the user aspect ratio settings enabled: " 1369 + mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()); 1370 pw.println("Is the fullscreen option in user aspect ratio settings enabled: " 1371 + mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()); 1372 } 1373 return 0; 1374 } 1375 runWmShellCommand(PrintWriter pw)1376 private int runWmShellCommand(PrintWriter pw) { 1377 String arg = getNextArg(); 1378 1379 switch (arg) { 1380 case "tracing": 1381 return runWmShellTracing(pw); 1382 case "help": 1383 default: 1384 return runHelp(pw); 1385 } 1386 } 1387 runHelp(PrintWriter pw)1388 private int runHelp(PrintWriter pw) { 1389 pw.println("Window Manager Shell commands:"); 1390 pw.println(" help"); 1391 pw.println(" Print this help text."); 1392 pw.println(" tracing <start/stop>"); 1393 pw.println(" Start/stop shell transition tracing."); 1394 1395 return 0; 1396 } 1397 runWmShellTracing(PrintWriter pw)1398 private int runWmShellTracing(PrintWriter pw) { 1399 String arg = getNextArg(); 1400 1401 switch (arg) { 1402 case "start": 1403 mInternal.mTransitionTracer.startTrace(pw); 1404 break; 1405 case "stop": 1406 mInternal.mTransitionTracer.stopTrace(pw); 1407 break; 1408 case "save-for-bugreport": 1409 mInternal.mTransitionTracer.saveForBugreport(pw); 1410 break; 1411 default: 1412 getErrPrintWriter() 1413 .println("Error: expected 'start' or 'stop', but got '" + arg + "'"); 1414 return -1; 1415 } 1416 1417 return 0; 1418 } 1419 runReset(PrintWriter pw)1420 private int runReset(PrintWriter pw) throws RemoteException { 1421 int displayId = getDisplayId(getNextArg()); 1422 1423 // size 1424 mInterface.clearForcedDisplaySize(displayId); 1425 1426 // density 1427 mInterface.clearForcedDisplayDensityForUser(displayId, UserHandle.USER_CURRENT); 1428 1429 // folded-area 1430 mInternal.setOverrideFoldedArea(new Rect()); 1431 1432 // scaling 1433 mInterface.setForcedDisplayScalingMode(displayId, DisplayContent.FORCE_SCALING_MODE_AUTO); 1434 1435 // user-rotation 1436 mInternal.thawDisplayRotation(displayId); 1437 1438 // fixed-to-user-rotation 1439 mInterface.setFixedToUserRotation(displayId, IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT); 1440 1441 // set-ignore-orientation-request 1442 mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */); 1443 1444 // set-letterbox-style 1445 resetLetterboxStyle(); 1446 1447 // set-sandbox-display-apis 1448 mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true); 1449 1450 // set-multi-window-config 1451 runResetMultiWindowConfig(); 1452 1453 pw.println("Reset all settings for displayId=" + displayId); 1454 return 0; 1455 } 1456 1457 @Override onHelp()1458 public void onHelp() { 1459 PrintWriter pw = getOutPrintWriter(); 1460 pw.println("Window manager (window) commands:"); 1461 pw.println(" help"); 1462 pw.println(" Print this help text."); 1463 pw.println(" size [reset|WxH|WdpxHdp] [-d DISPLAY_ID]"); 1464 pw.println(" Return or override display size."); 1465 pw.println(" width and height in pixels unless suffixed with 'dp'."); 1466 pw.println(" density [reset|DENSITY] [-d DISPLAY_ID] [-u UNIQUE_ID]"); 1467 pw.println(" Return or override display density."); 1468 pw.println(" folded-area [reset|LEFT,TOP,RIGHT,BOTTOM]"); 1469 pw.println(" Return or override folded area."); 1470 pw.println(" scaling [off|auto] [-d DISPLAY_ID]"); 1471 pw.println(" Set display scaling mode."); 1472 pw.println(" dismiss-keyguard"); 1473 pw.println(" Dismiss the keyguard, prompting user for auth if necessary."); 1474 pw.println(" disable-blur [true|1|false|0]"); 1475 pw.println(" user-rotation [-d DISPLAY_ID] [free|lock] [rotation]"); 1476 pw.println(" Print or set user rotation mode and user rotation."); 1477 pw.println(" dump-visible-window-views"); 1478 pw.println(" Dumps the encoded view hierarchies of visible windows"); 1479 pw.println(" fixed-to-user-rotation [-d DISPLAY_ID] [enabled|disabled|default]"); 1480 pw.println(" Print or set rotating display for app requested orientation."); 1481 pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]"); 1482 pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] "); 1483 pw.println(" If app requested orientation should be ignored."); 1484 pw.println(" set-sandbox-display-apis [true|1|false|0]"); 1485 pw.println(" Sets override of Display APIs getRealSize / getRealMetrics to reflect "); 1486 pw.println(" DisplayArea of the activity, or the window bounds if in letterbox or"); 1487 pw.println(" Size Compat Mode."); 1488 1489 printLetterboxHelp(pw); 1490 printMultiWindowConfigHelp(pw); 1491 1492 pw.println(" reset [-d DISPLAY_ID]"); 1493 pw.println(" Reset all override settings."); 1494 if (!IS_USER) { 1495 pw.println(" tracing (start | stop)"); 1496 pw.println(" Start or stop window tracing."); 1497 pw.println(" logging (start | stop | enable | disable | enable-text | disable-text)"); 1498 pw.println(" Logging settings."); 1499 } 1500 } 1501 printLetterboxHelp(PrintWriter pw)1502 private void printLetterboxHelp(PrintWriter pw) { 1503 pw.println(" set-letterbox-style"); 1504 pw.println(" Sets letterbox style using the following options:"); 1505 pw.println(" --aspectRatio aspectRatio"); 1506 pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= " 1507 + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO); 1508 pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will"); 1509 pw.println(" be ignored and framework implementation will determine aspect ratio."); 1510 pw.println(" --minAspectRatioForUnresizable aspectRatio"); 1511 pw.println(" Default min aspect ratio for unresizable apps which is used when an"); 1512 pw.println(" app is eligible for the size compat mode. If aspectRatio <= " 1513 + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO); 1514 pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will"); 1515 pw.println(" be ignored and framework implementation will determine aspect ratio."); 1516 pw.println(" --cornerRadius radius"); 1517 pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,"); 1518 pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be"); 1519 pw.println(" ignored and corners of the activity won't be rounded."); 1520 pw.println(" --backgroundType [reset|solid_color|app_color_background"); 1521 pw.println(" |app_color_background_floating|wallpaper]"); 1522 pw.println(" Type of background used in the letterbox mode."); 1523 pw.println(" --backgroundColor color"); 1524 pw.println(" Color of letterbox which is be used when letterbox background type"); 1525 pw.println(" is 'solid-color'. Use (set)get-letterbox-style to check and control"); 1526 pw.println(" letterbox background type. See Color#parseColor for allowed color"); 1527 pw.println(" formats (#RRGGBB and some colors by name, e.g. magenta or olive)."); 1528 pw.println(" --backgroundColorResource resource_name"); 1529 pw.println(" Color resource name of letterbox background which is used when"); 1530 pw.println(" background type is 'solid-color'. Use (set)get-letterbox-style to"); 1531 pw.println(" check and control background type. Parameter is a color resource"); 1532 pw.println(" name, for example, @android:color/system_accent2_50."); 1533 pw.println(" --wallpaperBlurRadius radius"); 1534 pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0"); 1535 pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius"); 1536 pw.println(" are ignored and 0 is used."); 1537 pw.println(" --wallpaperDarkScrimAlpha alpha"); 1538 pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'"); 1539 pw.println(" letterbox background. If alpha < 0 or >= 1 both it and"); 1540 pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored"); 1541 pw.println(" and 0.0 (transparent) is used instead."); 1542 pw.println(" --horizontalPositionMultiplier multiplier"); 1543 pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,"); 1544 pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier"); 1545 pw.println(" are ignored and central position (0.5) is used."); 1546 pw.println(" --verticalPositionMultiplier multiplier"); 1547 pw.println(" Vertical position of app window center. If multiplier < 0 or > 1,"); 1548 pw.println(" both it and R.dimen.config_letterboxVerticalPositionMultiplier"); 1549 pw.println(" are ignored and central position (0.5) is used."); 1550 pw.println(" --isHorizontalReachabilityEnabled [true|1|false|0]"); 1551 pw.println(" Whether horizontal reachability repositioning is allowed for "); 1552 pw.println(" letterboxed fullscreen apps in landscape device orientation."); 1553 pw.println(" --isVerticalReachabilityEnabled [true|1|false|0]"); 1554 pw.println(" Whether vertical reachability repositioning is allowed for "); 1555 pw.println(" letterboxed fullscreen apps in portrait device orientation."); 1556 pw.println(" --defaultPositionForHorizontalReachability [left|center|right]"); 1557 pw.println(" Default position of app window when horizontal reachability is."); 1558 pw.println(" enabled."); 1559 pw.println(" --defaultPositionForVerticalReachability [top|center|bottom]"); 1560 pw.println(" Default position of app window when vertical reachability is."); 1561 pw.println(" enabled."); 1562 pw.println(" --persistentPositionForHorizontalReachability [left|center|right]"); 1563 pw.println(" Persistent position of app window when horizontal reachability is."); 1564 pw.println(" enabled."); 1565 pw.println(" --persistentPositionForVerticalReachability [top|center|bottom]"); 1566 pw.println(" Persistent position of app window when vertical reachability is."); 1567 pw.println(" enabled."); 1568 pw.println(" --isEducationEnabled [true|1|false|0]"); 1569 pw.println(" Whether education is allowed for letterboxed fullscreen apps."); 1570 pw.println(" --isSplitScreenAspectRatioForUnresizableAppsEnabled [true|1|false|0]"); 1571 pw.println(" Whether using split screen aspect ratio as a default aspect ratio for"); 1572 pw.println(" unresizable apps."); 1573 pw.println(" --isTranslucentLetterboxingEnabled [true|1|false|0]"); 1574 pw.println(" Whether letterboxing for translucent activities is enabled."); 1575 pw.println(" --isUserAppAspectRatioSettingsEnabled [true|1|false|0]"); 1576 pw.println(" Whether user aspect ratio settings are enabled."); 1577 pw.println(" --isUserAppAspectRatioFullscreenEnabled [true|1|false|0]"); 1578 pw.println(" Whether user aspect ratio fullscreen option is enabled."); 1579 pw.println(" --isCameraCompatRefreshEnabled [true|1|false|0]"); 1580 pw.println(" Whether camera compatibility refresh is enabled."); 1581 pw.println(" --isCameraCompatRefreshCycleThroughStopEnabled [true|1|false|0]"); 1582 pw.println(" Whether activity \"refresh\" in camera compatibility treatment should"); 1583 pw.println(" happen using the \"stopped -> resumed\" cycle rather than"); 1584 pw.println(" \"paused -> resumed\" cycle."); 1585 pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType"); 1586 pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha"); 1587 pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier"); 1588 pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled"); 1589 pw.println(" |isEducationEnabled|defaultPositionMultiplierForHorizontalReachability"); 1590 pw.println(" |isTranslucentLetterboxingEnabled|isUserAppAspectRatioSettingsEnabled"); 1591 pw.println(" |persistentPositionMultiplierForHorizontalReachability"); 1592 pw.println(" |persistentPositionMultiplierForVerticalReachability"); 1593 pw.println(" |defaultPositionMultiplierForVerticalReachability]"); 1594 pw.println(" Resets overrides to default values for specified properties separated"); 1595 pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'."); 1596 pw.println(" If no arguments provided, all values will be reset."); 1597 pw.println(" get-letterbox-style"); 1598 pw.println(" Prints letterbox style configuration."); 1599 } 1600 printMultiWindowConfigHelp(PrintWriter pw)1601 private void printMultiWindowConfigHelp(PrintWriter pw) { 1602 pw.println(" set-multi-window-config"); 1603 pw.println(" Sets options to determine if activity should be shown in multi window:"); 1604 pw.println(" --supportsNonResizable [configValue]"); 1605 pw.println(" Whether the device supports non-resizable activity in multi window."); 1606 pw.println(" -1: The device doesn't support non-resizable in multi window."); 1607 pw.println(" 0: The device supports non-resizable in multi window only if"); 1608 pw.println(" this is a large screen device."); 1609 pw.println(" 1: The device always supports non-resizable in multi window."); 1610 pw.println(" --respectsActivityMinWidthHeight [configValue]"); 1611 pw.println(" Whether the device checks the activity min width/height to determine "); 1612 pw.println(" if it can be shown in multi window."); 1613 pw.println(" -1: The device ignores the activity min width/height when determining"); 1614 pw.println(" if it can be shown in multi window."); 1615 pw.println(" 0: If this is a small screen, the device compares the activity min"); 1616 pw.println(" width/height with the min multi window modes dimensions"); 1617 pw.println(" the device supports to determine if the activity can be shown in"); 1618 pw.println(" multi window."); 1619 pw.println(" 1: The device always compare the activity min width/height with the"); 1620 pw.println(" min multi window dimensions the device supports to determine if"); 1621 pw.println(" the activity can be shown in multi window."); 1622 pw.println(" get-multi-window-config"); 1623 pw.println(" Prints values of the multi window config options."); 1624 pw.println(" reset-multi-window-config"); 1625 pw.println(" Resets overrides to default values of the multi window config options."); 1626 } 1627 } 1628