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