1 /* 2 * Copyright (C) 2012 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.am; 18 19 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 21 22 import android.app.IStopUserCallback; 23 import android.os.Trace; 24 import android.os.UserHandle; 25 import android.util.ArrayMap; 26 import android.util.Slog; 27 import android.util.proto.ProtoOutputStream; 28 29 import com.android.internal.util.ProgressReporter; 30 31 import java.io.PrintWriter; 32 import java.util.ArrayList; 33 34 public final class UserState { 35 private static final String TAG = TAG_WITH_CLASS_NAME ? "UserState" : TAG_AM; 36 37 // User is first coming up. 38 public final static int STATE_BOOTING = 0; 39 // User is in the locked state. 40 public final static int STATE_RUNNING_LOCKED = 1; 41 // User is in the unlocking state. 42 public final static int STATE_RUNNING_UNLOCKING = 2; 43 // User is in the running state. 44 public final static int STATE_RUNNING_UNLOCKED = 3; 45 // User is in the initial process of being stopped. 46 public final static int STATE_STOPPING = 4; 47 // User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN. 48 public final static int STATE_SHUTDOWN = 5; 49 50 public final UserHandle mHandle; 51 public final ArrayList<IStopUserCallback> mStopCallbacks 52 = new ArrayList<IStopUserCallback>(); 53 public final ProgressReporter mUnlockProgress; 54 55 public int state = STATE_BOOTING; 56 public int lastState = STATE_BOOTING; 57 public boolean switching; 58 public boolean tokenProvided; 59 60 /** 61 * The last time that a provider was reported to usage stats as being brought to important 62 * foreground procstate. 63 * <p><strong>Important: </strong>Only access this field when holding ActivityManagerService 64 * lock. 65 */ 66 final ArrayMap<String,Long> mProviderLastReportedFg = new ArrayMap<>(); 67 UserState(UserHandle handle)68 public UserState(UserHandle handle) { 69 mHandle = handle; 70 mUnlockProgress = new ProgressReporter(handle.getIdentifier()); 71 } 72 setState(int oldState, int newState)73 public boolean setState(int oldState, int newState) { 74 if (state == oldState) { 75 setState(newState); 76 return true; 77 } else { 78 Slog.w(TAG, "Expected user " + mHandle.getIdentifier() + " in state " 79 + stateToString(oldState) + " but was in state " + stateToString(state)); 80 return false; 81 } 82 } 83 setState(int newState)84 public void setState(int newState) { 85 if (newState == state) { 86 return; 87 } 88 final int userId = mHandle.getIdentifier(); 89 if (state != STATE_BOOTING) { 90 Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, 91 stateToString(state) + " " + userId, userId); 92 } 93 if (newState != STATE_SHUTDOWN) { 94 Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 95 stateToString(newState) + " " + userId, userId); 96 } 97 Slog.i(TAG, "User " + userId + " state changed from " 98 + stateToString(state) + " to " + stateToString(newState)); 99 EventLogTags.writeAmUserStateChanged(userId, newState); 100 lastState = state; 101 state = newState; 102 } 103 stateToString(int state)104 public static String stateToString(int state) { 105 switch (state) { 106 case STATE_BOOTING: return "BOOTING"; 107 case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED"; 108 case STATE_RUNNING_UNLOCKING: return "RUNNING_UNLOCKING"; 109 case STATE_RUNNING_UNLOCKED: return "RUNNING_UNLOCKED"; 110 case STATE_STOPPING: return "STOPPING"; 111 case STATE_SHUTDOWN: return "SHUTDOWN"; 112 default: return Integer.toString(state); 113 } 114 } 115 stateToProtoEnum(int state)116 public static int stateToProtoEnum(int state) { 117 switch (state) { 118 case STATE_BOOTING: return UserStateProto.STATE_BOOTING; 119 case STATE_RUNNING_LOCKED: return UserStateProto.STATE_RUNNING_LOCKED; 120 case STATE_RUNNING_UNLOCKING: return UserStateProto.STATE_RUNNING_UNLOCKING; 121 case STATE_RUNNING_UNLOCKED: return UserStateProto.STATE_RUNNING_UNLOCKED; 122 case STATE_STOPPING: return UserStateProto.STATE_STOPPING; 123 case STATE_SHUTDOWN: return UserStateProto.STATE_SHUTDOWN; 124 default: return state; 125 } 126 } 127 dump(String prefix, PrintWriter pw)128 void dump(String prefix, PrintWriter pw) { 129 pw.print(prefix); 130 pw.print("state="); pw.print(stateToString(state)); 131 if (switching) pw.print(" SWITCHING"); 132 pw.println(); 133 } 134 writeToProto(ProtoOutputStream proto, long fieldId)135 void writeToProto(ProtoOutputStream proto, long fieldId) { 136 final long token = proto.start(fieldId); 137 proto.write(UserStateProto.STATE, stateToProtoEnum(state)); 138 proto.write(UserStateProto.SWITCHING, switching); 139 proto.end(token); 140 } 141 } 142