1 /* 2 * Copyright (C) 2016 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 android.server.am; 18 19 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; 21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; 22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 23 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 24 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 25 import static android.server.am.ComponentNameUtils.getActivityName; 26 import static android.server.am.ProtoExtractors.extract; 27 import static android.server.am.StateLogger.log; 28 import static android.server.am.StateLogger.logE; 29 30 import android.content.ComponentName; 31 import android.graphics.Rect; 32 import android.os.ParcelFileDescriptor; 33 import android.os.SystemClock; 34 import android.support.test.InstrumentationRegistry; 35 36 import com.android.server.am.nano.ActivityDisplayProto; 37 import com.android.server.am.nano.ActivityManagerServiceDumpActivitiesProto; 38 import com.android.server.am.nano.ActivityRecordProto; 39 import com.android.server.am.nano.ActivityStackProto; 40 import com.android.server.am.nano.ActivityStackSupervisorProto; 41 import com.android.server.am.nano.KeyguardControllerProto; 42 import com.android.server.am.nano.TaskRecordProto; 43 import com.android.server.wm.nano.ConfigurationContainerProto; 44 45 import com.google.protobuf.nano.InvalidProtocolBufferNanoException; 46 47 import java.io.ByteArrayOutputStream; 48 import java.io.FileInputStream; 49 import java.io.IOException; 50 import java.nio.charset.StandardCharsets; 51 import java.util.ArrayList; 52 import java.util.List; 53 54 public class ActivityManagerState { 55 56 public static final int DUMP_MODE_ACTIVITIES = 0; 57 58 public static final String STATE_RESUMED = "RESUMED"; 59 public static final String STATE_PAUSED = "PAUSED"; 60 public static final String STATE_STOPPED = "STOPPED"; 61 public static final String STATE_DESTROYED = "DESTROYED"; 62 63 private static final String DUMPSYS_ACTIVITY_ACTIVITIES = "dumpsys activity --proto activities"; 64 65 // Displays in z-order with the top most at the front of the list, starting with primary. 66 private final List<ActivityDisplay> mDisplays = new ArrayList<>(); 67 // Stacks in z-order with the top most at the front of the list, starting with primary display. 68 private final List<ActivityStack> mStacks = new ArrayList<>(); 69 private KeyguardControllerState mKeyguardControllerState; 70 private int mFocusedStackId = -1; 71 private Boolean mIsHomeRecentsComponent; 72 private String mResumedActivityRecord = null; 73 private final List<String> mResumedActivities = new ArrayList<>(); 74 computeState()75 void computeState() { 76 computeState(DUMP_MODE_ACTIVITIES); 77 } 78 computeState(int dumpMode)79 void computeState(int dumpMode) { 80 // It is possible the system is in the middle of transition to the right state when we get 81 // the dump. We try a few times to get the information we need before giving up. 82 int retriesLeft = 3; 83 boolean retry = false; 84 byte[] dump = null; 85 86 log("=============================="); 87 log(" ActivityManagerState "); 88 log("=============================="); 89 90 do { 91 if (retry) { 92 log("***Incomplete AM state. Retrying..."); 93 // Wait half a second between retries for activity manager to finish transitioning. 94 SystemClock.sleep(500); 95 } 96 97 String dumpsysCmd = ""; 98 switch (dumpMode) { 99 case DUMP_MODE_ACTIVITIES: 100 dumpsysCmd = DUMPSYS_ACTIVITY_ACTIVITIES; 101 break; 102 } 103 104 dump = executeShellCommand(dumpsysCmd); 105 try { 106 parseSysDumpProto(dump); 107 } catch (InvalidProtocolBufferNanoException ex) { 108 throw new RuntimeException("Failed to parse dumpsys:\n" 109 + new String(dump, StandardCharsets.UTF_8), ex); 110 } 111 112 retry = mStacks.isEmpty() || mFocusedStackId == -1 || (mResumedActivityRecord == null 113 || mResumedActivities.isEmpty()) && !mKeyguardControllerState.keyguardShowing; 114 } while (retry && retriesLeft-- > 0); 115 116 if (mStacks.isEmpty()) { 117 logE("No stacks found..."); 118 } 119 if (mFocusedStackId == -1) { 120 logE("No focused stack found..."); 121 } 122 if (mResumedActivityRecord == null) { 123 logE("No focused activity found..."); 124 } 125 if (mResumedActivities.isEmpty()) { 126 logE("No resumed activities found..."); 127 } 128 } 129 executeShellCommand(String cmd)130 private byte[] executeShellCommand(String cmd) { 131 try { 132 ParcelFileDescriptor pfd = 133 InstrumentationRegistry.getInstrumentation().getUiAutomation() 134 .executeShellCommand(cmd); 135 byte[] buf = new byte[512]; 136 int bytesRead; 137 FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); 138 ByteArrayOutputStream stdout = new ByteArrayOutputStream(); 139 while ((bytesRead = fis.read(buf)) != -1) { 140 stdout.write(buf, 0, bytesRead); 141 } 142 fis.close(); 143 return stdout.toByteArray(); 144 } catch (IOException e) { 145 throw new RuntimeException(e); 146 } 147 } 148 parseSysDumpProto(byte[] sysDump)149 private void parseSysDumpProto(byte[] sysDump) throws InvalidProtocolBufferNanoException { 150 reset(); 151 152 ActivityStackSupervisorProto state = ActivityManagerServiceDumpActivitiesProto.parseFrom(sysDump) 153 .activityStackSupervisor; 154 for (int i = 0; i < state.displays.length; i++) { 155 ActivityDisplayProto activityDisplay = state.displays[i]; 156 mDisplays.add(new ActivityDisplay(activityDisplay, this)); 157 } 158 mKeyguardControllerState = new KeyguardControllerState(state.keyguardController); 159 mFocusedStackId = state.focusedStackId; 160 if (state.resumedActivity != null) { 161 mResumedActivityRecord = state.resumedActivity.title; 162 } 163 mIsHomeRecentsComponent = new Boolean(state.isHomeRecentsComponent); 164 } 165 reset()166 private void reset() { 167 mDisplays.clear(); 168 mStacks.clear(); 169 mFocusedStackId = -1; 170 mResumedActivityRecord = null; 171 mResumedActivities.clear(); 172 mKeyguardControllerState = null; 173 mIsHomeRecentsComponent = null; 174 } 175 176 /** 177 * @return Whether the home activity is the recents component. 178 */ isHomeRecentsComponent()179 boolean isHomeRecentsComponent() { 180 if (mIsHomeRecentsComponent == null) { 181 computeState(); 182 } 183 return mIsHomeRecentsComponent; 184 } 185 getDisplay(int displayId)186 ActivityDisplay getDisplay(int displayId) { 187 for (ActivityDisplay display : mDisplays) { 188 if (display.mId == displayId) { 189 return display; 190 } 191 } 192 return null; 193 } 194 getFrontStackId(int displayId)195 int getFrontStackId(int displayId) { 196 return getDisplay(displayId).mStacks.get(0).mStackId; 197 } 198 getFrontStackActivityType(int displayId)199 int getFrontStackActivityType(int displayId) { 200 return getDisplay(displayId).mStacks.get(0).getActivityType(); 201 } 202 getFrontStackWindowingMode(int displayId)203 int getFrontStackWindowingMode(int displayId) { 204 return getDisplay(displayId).mStacks.get(0).getWindowingMode(); 205 } 206 getFocusedStackId()207 int getFocusedStackId() { 208 return mFocusedStackId; 209 } 210 getFocusedStackActivityType()211 int getFocusedStackActivityType() { 212 final ActivityStack stack = getStackById(mFocusedStackId); 213 return stack != null ? stack.getActivityType() : ACTIVITY_TYPE_UNDEFINED; 214 } 215 getFocusedStackWindowingMode()216 int getFocusedStackWindowingMode() { 217 final ActivityStack stack = getStackById(mFocusedStackId); 218 return stack != null ? stack.getWindowingMode() : WINDOWING_MODE_UNDEFINED; 219 } 220 getFocusedActivity()221 String getFocusedActivity() { 222 return mResumedActivityRecord; 223 } 224 getResumedActivity()225 String getResumedActivity() { 226 return mResumedActivities.get(0); 227 } 228 getResumedActivitiesCount()229 int getResumedActivitiesCount() { 230 return mResumedActivities.size(); 231 } 232 getKeyguardControllerState()233 public KeyguardControllerState getKeyguardControllerState() { 234 return mKeyguardControllerState; 235 } 236 containsStack(int stackId)237 boolean containsStack(int stackId) { 238 return getStackById(stackId) != null; 239 } 240 containsStack(int windowingMode, int activityType)241 boolean containsStack(int windowingMode, int activityType) { 242 for (ActivityStack stack : mStacks) { 243 if (activityType != ACTIVITY_TYPE_UNDEFINED 244 && activityType != stack.getActivityType()) { 245 continue; 246 } 247 if (windowingMode != WINDOWING_MODE_UNDEFINED 248 && windowingMode != stack.getWindowingMode()) { 249 continue; 250 } 251 return true; 252 } 253 return false; 254 } 255 getStackById(int stackId)256 ActivityStack getStackById(int stackId) { 257 for (ActivityStack stack : mStacks) { 258 if (stackId == stack.mStackId) { 259 return stack; 260 } 261 } 262 return null; 263 } 264 getStackByActivityType(int activityType)265 ActivityStack getStackByActivityType(int activityType) { 266 for (ActivityStack stack : mStacks) { 267 if (activityType == stack.getActivityType()) { 268 return stack; 269 } 270 } 271 return null; 272 } 273 getStandardStackByWindowingMode(int windowingMode)274 ActivityStack getStandardStackByWindowingMode(int windowingMode) { 275 for (ActivityStack stack : mStacks) { 276 if (stack.getActivityType() != ACTIVITY_TYPE_STANDARD) { 277 continue; 278 } 279 if (stack.getWindowingMode() == windowingMode) { 280 return stack; 281 } 282 } 283 return null; 284 } 285 getStandardTaskCountByWindowingMode(int windowingMode)286 int getStandardTaskCountByWindowingMode(int windowingMode) { 287 int count = 0; 288 for (ActivityStack stack : mStacks) { 289 if (stack.getActivityType() != ACTIVITY_TYPE_STANDARD) { 290 continue; 291 } 292 if (stack.getWindowingMode() == windowingMode) { 293 count += stack.mTasks.size(); 294 } 295 } 296 return count; 297 } 298 299 /** Get the stack position on its display. */ getStackIndexByActivityType(int activityType)300 int getStackIndexByActivityType(int activityType) { 301 for (ActivityDisplay display : mDisplays) { 302 for (int i = 0; i < display.mStacks.size(); i++) { 303 if (activityType == display.mStacks.get(i).getActivityType()) { 304 return i; 305 } 306 } 307 } 308 return -1; 309 } 310 311 /** Get the stack position on its display. */ getStackIndexByActivity(ComponentName activityName)312 int getStackIndexByActivity(ComponentName activityName) { 313 final String fullName = getActivityName(activityName); 314 315 for (ActivityDisplay display : mDisplays) { 316 for (int i = display.mStacks.size() - 1; i >= 0; --i) { 317 final ActivityStack stack = display.mStacks.get(i); 318 for (ActivityTask task : stack.mTasks) { 319 for (Activity activity : task.mActivities) { 320 if (activity.name.equals(fullName)) { 321 return i; 322 } 323 } 324 } 325 } 326 } 327 return -1; 328 } 329 330 /** Get display id by activity on it. */ getDisplayByActivity(ComponentName activityComponent)331 int getDisplayByActivity(ComponentName activityComponent) { 332 final ActivityManagerState.ActivityTask task = getTaskByActivity(activityComponent); 333 if (task == null) { 334 return -1; 335 } 336 return getStackById(task.mStackId).mDisplayId; 337 } 338 getDisplays()339 List<ActivityDisplay> getDisplays() { 340 return new ArrayList<>(mDisplays); 341 } 342 getStacks()343 List<ActivityStack> getStacks() { 344 return new ArrayList<>(mStacks); 345 } 346 getStackCount()347 int getStackCount() { 348 return mStacks.size(); 349 } 350 containsActivity(ComponentName activityName)351 boolean containsActivity(ComponentName activityName) { 352 final String fullName = getActivityName(activityName); 353 for (ActivityStack stack : mStacks) { 354 for (ActivityTask task : stack.mTasks) { 355 for (Activity activity : task.mActivities) { 356 if (activity.name.equals(fullName)) { 357 return true; 358 } 359 } 360 } 361 } 362 return false; 363 } 364 containsActivityInWindowingMode(ComponentName activityName, int windowingMode)365 boolean containsActivityInWindowingMode(ComponentName activityName, int windowingMode) { 366 final String fullName = getActivityName(activityName); 367 for (ActivityStack stack : mStacks) { 368 for (ActivityTask task : stack.mTasks) { 369 for (Activity activity : task.mActivities) { 370 if (activity.name.equals(fullName) 371 && activity.getWindowingMode() == windowingMode) { 372 return true; 373 } 374 } 375 } 376 } 377 return false; 378 } 379 isActivityVisible(ComponentName activityName)380 boolean isActivityVisible(ComponentName activityName) { 381 final String fullName = getActivityName(activityName); 382 for (ActivityStack stack : mStacks) { 383 for (ActivityTask task : stack.mTasks) { 384 for (Activity activity : task.mActivities) { 385 if (activity.name.equals(fullName)) { 386 return activity.visible; 387 } 388 } 389 } 390 } 391 return false; 392 } 393 isActivityTranslucent(ComponentName activityName)394 boolean isActivityTranslucent(ComponentName activityName) { 395 final String fullName = getActivityName(activityName); 396 for (ActivityStack stack : mStacks) { 397 for (ActivityTask task : stack.mTasks) { 398 for (Activity activity : task.mActivities) { 399 if (activity.name.equals(fullName)) { 400 return activity.translucent; 401 } 402 } 403 } 404 } 405 return false; 406 } 407 isBehindOpaqueActivities(ComponentName activityName)408 boolean isBehindOpaqueActivities(ComponentName activityName) { 409 final String fullName = getActivityName(activityName); 410 for (ActivityStack stack : mStacks) { 411 for (ActivityTask task : stack.mTasks) { 412 for (Activity activity : task.mActivities) { 413 if (activity.name.equals(fullName)) { 414 return false; 415 } 416 if (!activity.translucent) { 417 return true; 418 } 419 } 420 } 421 } 422 423 return false; 424 } 425 containsStartedActivities()426 boolean containsStartedActivities() { 427 for (ActivityStack stack : mStacks) { 428 for (ActivityTask task : stack.mTasks) { 429 for (Activity activity : task.mActivities) { 430 if (!activity.state.equals(STATE_STOPPED) 431 && !activity.state.equals(STATE_DESTROYED)) { 432 return true; 433 } 434 } 435 } 436 } 437 return false; 438 } 439 hasActivityState(ComponentName activityName, String activityState)440 boolean hasActivityState(ComponentName activityName, String activityState) { 441 final String fullName = getActivityName(activityName); 442 for (ActivityStack stack : mStacks) { 443 for (ActivityTask task : stack.mTasks) { 444 for (Activity activity : task.mActivities) { 445 if (activity.name.equals(fullName)) { 446 return activity.state.equals(activityState); 447 } 448 } 449 } 450 } 451 return false; 452 } 453 getActivityProcId(ComponentName activityName)454 int getActivityProcId(ComponentName activityName) { 455 final String fullName = getActivityName(activityName); 456 for (ActivityStack stack : mStacks) { 457 for (ActivityTask task : stack.mTasks) { 458 for (Activity activity : task.mActivities) { 459 if (activity.name.equals(fullName)) { 460 return activity.procId; 461 } 462 } 463 } 464 } 465 return -1; 466 } 467 isHomeActivityVisible()468 boolean isHomeActivityVisible() { 469 final Activity homeActivity = getHomeActivity(); 470 return homeActivity != null && homeActivity.visible; 471 } 472 isRecentsActivityVisible()473 boolean isRecentsActivityVisible() { 474 final Activity recentsActivity = getRecentsActivity(); 475 return recentsActivity != null && recentsActivity.visible; 476 } 477 getHomeActivityName()478 ComponentName getHomeActivityName() { 479 Activity activity = getHomeActivity(); 480 if (activity == null) { 481 return null; 482 } 483 return ComponentName.unflattenFromString(activity.name); 484 } 485 getHomeTask()486 ActivityTask getHomeTask() { 487 final ActivityStack homeStack = getStackByActivityType(ACTIVITY_TYPE_HOME); 488 if (homeStack != null && !homeStack.mTasks.isEmpty()) { 489 return homeStack.mTasks.get(0); 490 } 491 return null; 492 } 493 getRecentsTask()494 private ActivityTask getRecentsTask() { 495 final ActivityStack recentsStack = getStackByActivityType(ACTIVITY_TYPE_RECENTS); 496 if (recentsStack != null && !recentsStack.mTasks.isEmpty()) { 497 return recentsStack.mTasks.get(0); 498 } 499 return null; 500 } 501 getHomeActivity()502 private Activity getHomeActivity() { 503 final ActivityTask homeTask = getHomeTask(); 504 return homeTask != null ? homeTask.mActivities.get(homeTask.mActivities.size() - 1) : null; 505 } 506 getRecentsActivity()507 private Activity getRecentsActivity() { 508 final ActivityTask recentsTask = getRecentsTask(); 509 return recentsTask != null ? recentsTask.mActivities.get(recentsTask.mActivities.size() - 1) 510 : null; 511 } 512 getStackIdByActivity(ComponentName activityName)513 int getStackIdByActivity(ComponentName activityName) { 514 final ActivityTask task = getTaskByActivity(activityName); 515 return (task == null) ? INVALID_STACK_ID : task.mStackId; 516 } 517 getTaskByActivity(ComponentName activityName)518 ActivityTask getTaskByActivity(ComponentName activityName) { 519 return getTaskByActivityInternal(getActivityName(activityName), WINDOWING_MODE_UNDEFINED); 520 } 521 getTaskByActivity(ComponentName activityName, int windowingMode)522 ActivityTask getTaskByActivity(ComponentName activityName, int windowingMode) { 523 return getTaskByActivityInternal(getActivityName(activityName), windowingMode); 524 } 525 getTaskByActivityInternal(String fullName, int windowingMode)526 private ActivityTask getTaskByActivityInternal(String fullName, int windowingMode) { 527 for (ActivityStack stack : mStacks) { 528 if (windowingMode == WINDOWING_MODE_UNDEFINED 529 || windowingMode == stack.getWindowingMode()) { 530 for (ActivityTask task : stack.mTasks) { 531 for (Activity activity : task.mActivities) { 532 if (activity.name.equals(fullName)) { 533 return task; 534 } 535 } 536 } 537 } 538 } 539 return null; 540 } 541 542 static class ActivityDisplay extends ActivityContainer { 543 544 int mId; 545 ArrayList<ActivityStack> mStacks = new ArrayList<>(); 546 ActivityDisplay(ActivityDisplayProto proto, ActivityManagerState amState)547 ActivityDisplay(ActivityDisplayProto proto, ActivityManagerState amState) { 548 super(proto.configurationContainer); 549 mId = proto.id; 550 for (int i = 0; i < proto.stacks.length; i++) { 551 ActivityStack activityStack = new ActivityStack(proto.stacks[i]); 552 mStacks.add(activityStack); 553 // Also update activity manager state 554 amState.mStacks.add(activityStack); 555 if (activityStack.mResumedActivity != null) { 556 amState.mResumedActivities.add(activityStack.mResumedActivity); 557 } 558 } 559 } 560 } 561 562 static class ActivityStack extends ActivityContainer { 563 564 int mDisplayId; 565 int mStackId; 566 String mResumedActivity; 567 ArrayList<ActivityTask> mTasks = new ArrayList<>(); 568 ActivityStack(ActivityStackProto proto)569 ActivityStack(ActivityStackProto proto) { 570 super(proto.configurationContainer); 571 mStackId = proto.id; 572 mDisplayId = proto.displayId; 573 mBounds = extract(proto.bounds); 574 mFullscreen = proto.fullscreen; 575 for (int i = 0; i < proto.tasks.length; i++) { 576 mTasks.add(new ActivityTask(proto.tasks[i])); 577 } 578 if (proto.resumedActivity != null) { 579 mResumedActivity = proto.resumedActivity.title; 580 } 581 } 582 583 /** 584 * @return the bottom task in the stack. 585 */ getBottomTask()586 ActivityTask getBottomTask() { 587 if (!mTasks.isEmpty()) { 588 // NOTE: Unlike the ActivityManager internals, we dump the state from top to bottom, 589 // so the indices are inverted 590 return mTasks.get(mTasks.size() - 1); 591 } 592 return null; 593 } 594 595 /** 596 * @return the top task in the stack. 597 */ getTopTask()598 ActivityTask getTopTask() { 599 if (!mTasks.isEmpty()) { 600 // NOTE: Unlike the ActivityManager internals, we dump the state from top to bottom, 601 // so the indices are inverted 602 return mTasks.get(0); 603 } 604 return null; 605 } 606 getTasks()607 List<ActivityTask> getTasks() { 608 return new ArrayList<>(mTasks); 609 } 610 getTask(int taskId)611 ActivityTask getTask(int taskId) { 612 for (ActivityTask task : mTasks) { 613 if (taskId == task.mTaskId) { 614 return task; 615 } 616 } 617 return null; 618 } 619 } 620 621 static class ActivityTask extends ActivityContainer { 622 623 int mTaskId; 624 int mStackId; 625 Rect mLastNonFullscreenBounds; 626 String mRealActivity; 627 String mOrigActivity; 628 ArrayList<Activity> mActivities = new ArrayList<>(); 629 int mTaskType = -1; 630 private int mResizeMode; 631 ActivityTask(TaskRecordProto proto)632 ActivityTask(TaskRecordProto proto) { 633 super(proto.configurationContainer); 634 mTaskId = proto.id; 635 mStackId = proto.stackId; 636 mLastNonFullscreenBounds = extract(proto.lastNonFullscreenBounds); 637 mRealActivity = proto.realActivity; 638 mOrigActivity = proto.origActivity; 639 mTaskType = proto.activityType; 640 mResizeMode = proto.resizeMode; 641 mFullscreen = proto.fullscreen; 642 mBounds = extract(proto.bounds); 643 mMinWidth = proto.minWidth; 644 mMinHeight = proto.minHeight; 645 for (int i = 0; i < proto.activities.length; i++) { 646 mActivities.add(new Activity(proto.activities[i])); 647 } 648 } 649 getResizeMode()650 public int getResizeMode() { 651 return mResizeMode; 652 } 653 654 /** 655 * @return whether this task contains the given activity. 656 */ containsActivity(String activityName)657 public boolean containsActivity(String activityName) { 658 for (Activity activity : mActivities) { 659 if (activity.name.equals(activityName)) { 660 return true; 661 } 662 } 663 return false; 664 } 665 } 666 667 public static class Activity extends ActivityContainer { 668 669 String name; 670 String state; 671 boolean visible; 672 boolean frontOfTask; 673 int procId = -1; 674 public boolean translucent; 675 Activity(ActivityRecordProto proto)676 Activity(ActivityRecordProto proto) { 677 super(proto.configurationContainer); 678 name = proto.identifier.title; 679 state = proto.state; 680 visible = proto.visible; 681 frontOfTask = proto.frontOfTask; 682 if (proto.procId != 0) { 683 procId = proto.procId; 684 } 685 translucent = proto.translucent; 686 } 687 } 688 689 static abstract class ActivityContainer extends WindowManagerState.ConfigurationContainer { 690 protected boolean mFullscreen; 691 protected Rect mBounds; 692 protected int mMinWidth = -1; 693 protected int mMinHeight = -1; 694 ActivityContainer(ConfigurationContainerProto proto)695 ActivityContainer(ConfigurationContainerProto proto) { 696 super(proto); 697 } 698 getBounds()699 Rect getBounds() { 700 return mBounds; 701 } 702 isFullscreen()703 boolean isFullscreen() { 704 return mFullscreen; 705 } 706 getMinWidth()707 int getMinWidth() { 708 return mMinWidth; 709 } 710 getMinHeight()711 int getMinHeight() { 712 return mMinHeight; 713 } 714 } 715 716 static class KeyguardControllerState { 717 718 boolean keyguardShowing = false; 719 boolean keyguardOccluded = false; 720 KeyguardControllerState(KeyguardControllerProto proto)721 KeyguardControllerState(KeyguardControllerProto proto) { 722 if (proto != null) { 723 keyguardShowing = proto.keyguardShowing; 724 keyguardOccluded = proto.keyguardOccluded; 725 } 726 } 727 } 728 } 729