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