Home | History | Annotate | Download | only in am
      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 
     75     void computeState() {
     76         computeState(DUMP_MODE_ACTIVITIES);
     77     }
     78 
     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 
    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 
    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 
    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      */
    179     boolean isHomeRecentsComponent() {
    180         if (mIsHomeRecentsComponent == null) {
    181             computeState();
    182         }
    183         return mIsHomeRecentsComponent;
    184     }
    185 
    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 
    195     int getFrontStackId(int displayId) {
    196         return getDisplay(displayId).mStacks.get(0).mStackId;
    197     }
    198 
    199     int getFrontStackActivityType(int displayId) {
    200         return getDisplay(displayId).mStacks.get(0).getActivityType();
    201     }
    202 
    203     int getFrontStackWindowingMode(int displayId) {
    204         return getDisplay(displayId).mStacks.get(0).getWindowingMode();
    205     }
    206 
    207     int getFocusedStackId() {
    208         return mFocusedStackId;
    209     }
    210 
    211     int getFocusedStackActivityType() {
    212         final ActivityStack stack = getStackById(mFocusedStackId);
    213         return stack != null ? stack.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
    214     }
    215 
    216     int getFocusedStackWindowingMode() {
    217         final ActivityStack stack = getStackById(mFocusedStackId);
    218         return stack != null ? stack.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
    219     }
    220 
    221     String getFocusedActivity() {
    222         return mResumedActivityRecord;
    223     }
    224 
    225     String getResumedActivity() {
    226         return mResumedActivities.get(0);
    227     }
    228 
    229     int getResumedActivitiesCount() {
    230         return mResumedActivities.size();
    231     }
    232 
    233     public KeyguardControllerState getKeyguardControllerState() {
    234         return mKeyguardControllerState;
    235     }
    236 
    237     boolean containsStack(int stackId) {
    238         return getStackById(stackId) != null;
    239     }
    240 
    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 
    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 
    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 
    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 
    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. */
    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. */
    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. */
    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 
    339     List<ActivityDisplay> getDisplays() {
    340         return new ArrayList<>(mDisplays);
    341     }
    342 
    343     List<ActivityStack> getStacks() {
    344         return new ArrayList<>(mStacks);
    345     }
    346 
    347     int getStackCount() {
    348         return mStacks.size();
    349     }
    350 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    468     boolean isHomeActivityVisible() {
    469         final Activity homeActivity = getHomeActivity();
    470         return homeActivity != null && homeActivity.visible;
    471     }
    472 
    473     boolean isRecentsActivityVisible() {
    474         final Activity recentsActivity = getRecentsActivity();
    475         return recentsActivity != null && recentsActivity.visible;
    476     }
    477 
    478     ComponentName getHomeActivityName() {
    479         Activity activity = getHomeActivity();
    480         if (activity == null) {
    481             return null;
    482         }
    483         return ComponentName.unflattenFromString(activity.name);
    484     }
    485 
    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 
    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 
    502     private Activity getHomeActivity() {
    503         final ActivityTask homeTask = getHomeTask();
    504         return homeTask != null ? homeTask.mActivities.get(homeTask.mActivities.size() - 1) : null;
    505     }
    506 
    507     private Activity getRecentsActivity() {
    508         final ActivityTask recentsTask = getRecentsTask();
    509         return recentsTask != null ? recentsTask.mActivities.get(recentsTask.mActivities.size() - 1)
    510                 : null;
    511     }
    512 
    513     int getStackIdByActivity(ComponentName activityName) {
    514         final ActivityTask task = getTaskByActivity(activityName);
    515         return  (task == null) ? INVALID_STACK_ID : task.mStackId;
    516     }
    517 
    518     ActivityTask getTaskByActivity(ComponentName activityName) {
    519         return getTaskByActivityInternal(getActivityName(activityName), WINDOWING_MODE_UNDEFINED);
    520     }
    521 
    522     ActivityTask getTaskByActivity(ComponentName activityName, int windowingMode) {
    523         return getTaskByActivityInternal(getActivityName(activityName), windowingMode);
    524     }
    525 
    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 
    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 
    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          */
    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          */
    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 
    607         List<ActivityTask> getTasks() {
    608             return new ArrayList<>(mTasks);
    609         }
    610 
    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 
    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 
    650         public int getResizeMode() {
    651             return mResizeMode;
    652         }
    653 
    654         /**
    655          * @return whether this task contains the given activity.
    656          */
    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 
    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 
    695         ActivityContainer(ConfigurationContainerProto proto) {
    696             super(proto);
    697         }
    698 
    699         Rect getBounds() {
    700             return mBounds;
    701         }
    702 
    703         boolean isFullscreen() {
    704             return mFullscreen;
    705         }
    706 
    707         int getMinWidth() {
    708             return mMinWidth;
    709         }
    710 
    711         int getMinHeight() {
    712             return mMinHeight;
    713         }
    714     }
    715 
    716     static class KeyguardControllerState {
    717 
    718         boolean keyguardShowing = false;
    719         boolean keyguardOccluded = false;
    720 
    721         KeyguardControllerState(KeyguardControllerProto proto) {
    722             if (proto != null) {
    723                 keyguardShowing = proto.keyguardShowing;
    724                 keyguardOccluded = proto.keyguardOccluded;
    725             }
    726         }
    727     }
    728 }
    729