/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.am;

import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;

import android.app.IStopUserCallback;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;

import com.android.internal.util.ProgressReporter;

import java.io.PrintWriter;
import java.util.ArrayList;

public final class UserState {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "UserState" : TAG_AM;

    // User is first coming up.
    public final static int STATE_BOOTING = 0;
    // User is in the locked state.
    public final static int STATE_RUNNING_LOCKED = 1;
    // User is in the unlocking state.
    public final static int STATE_RUNNING_UNLOCKING = 2;
    // User is in the running state.
    public final static int STATE_RUNNING_UNLOCKED = 3;
    // User is in the initial process of being stopped.
    public final static int STATE_STOPPING = 4;
    // User is in the final phase of stopping, sending Intent.ACTION_SHUTDOWN.
    public final static int STATE_SHUTDOWN = 5;

    public final UserHandle mHandle;
    public final ArrayList<IStopUserCallback> mStopCallbacks
            = new ArrayList<IStopUserCallback>();
    public final ProgressReporter mUnlockProgress;

    public int state = STATE_BOOTING;
    public int lastState = STATE_BOOTING;
    public boolean switching;
    public boolean tokenProvided;

    /**
     * The last time that a provider was reported to usage stats as being brought to important
     * foreground procstate.
     */
    public final ArrayMap<String,Long> mProviderLastReportedFg = new ArrayMap<>();

    public UserState(UserHandle handle) {
        mHandle = handle;
        mUnlockProgress = new ProgressReporter(handle.getIdentifier());
    }

    public boolean setState(int oldState, int newState) {
        if (state == oldState) {
            setState(newState);
            return true;
        } else {
            Slog.w(TAG, "Expected user " + mHandle.getIdentifier() + " in state "
                    + stateToString(oldState) + " but was in state " + stateToString(state));
            return false;
        }
    }

    public void setState(int newState) {
        if (newState == state) {
            return;
        }
        final int userId = mHandle.getIdentifier();
        if (state != STATE_BOOTING) {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    stateToString(state) + " " + userId, userId);
        }
        if (newState != STATE_SHUTDOWN) {
            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    stateToString(newState) + " " + userId, userId);
        }
        Slog.i(TAG, "User " + userId + " state changed from "
                + stateToString(state) + " to " + stateToString(newState));
        EventLogTags.writeAmUserStateChanged(userId, newState);
        lastState = state;
        state = newState;
    }

    public static String stateToString(int state) {
        switch (state) {
            case STATE_BOOTING: return "BOOTING";
            case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
            case STATE_RUNNING_UNLOCKING: return "RUNNING_UNLOCKING";
            case STATE_RUNNING_UNLOCKED: return "RUNNING_UNLOCKED";
            case STATE_STOPPING: return "STOPPING";
            case STATE_SHUTDOWN: return "SHUTDOWN";
            default: return Integer.toString(state);
        }
    }

    void dump(String prefix, PrintWriter pw) {
        pw.print(prefix);
        pw.print("state="); pw.print(stateToString(state));
        if (switching) pw.print(" SWITCHING");
        pw.println();
    }
}
