/*
 * Copyright (C) 2016 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.wm;

import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_UNKNOWN_APP_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.NonNull;
import android.util.ArrayMap;
import android.util.Slog;

import com.android.server.wm.WindowManagerService.H;

import java.io.PrintWriter;

/**
 * Manages the set of {@link AppWindowToken}s for which we don't know yet whether it's visible or
 * not. This happens when starting an activity while the lockscreen is showing. In that case, the
 * keyguard flags an app might set influence it's visibility, so we wait until this is resolved to
 * start the transition to avoid flickers.
 */
class UnknownAppVisibilityController {

    private static final String TAG = TAG_WITH_CLASS_NAME ? "UnknownAppVisibility" : TAG_WM;

    /**
     * We are currently waiting until the app is done resuming.
     */
    private static final int UNKNOWN_STATE_WAITING_RESUME = 1;

    /**
     * The activity has finished resuming, and we are waiting on the next relayout.
     */
    private static final int UNKNOWN_STATE_WAITING_RELAYOUT = 2;

    /**
     * The client called {@link Session#relayout} with the appropriate Keyguard flags and we are
     * waiting until activity manager has updated the visibilities of all the apps.
     */
    private static final int UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE = 3;

    // Set of apps for which we don't know yet whether it's visible or not, depending on what kind
    // of lockscreen flags the app might set during its first relayout.
    private final ArrayMap<AppWindowToken, Integer> mUnknownApps = new ArrayMap<>();

    private final WindowManagerService mService;

    private final DisplayContent mDisplayContent;

    UnknownAppVisibilityController(WindowManagerService service, DisplayContent displayContent) {
        mService = service;
        mDisplayContent = displayContent;
    }

    boolean allResolved() {
        return mUnknownApps.isEmpty();
    }

    void clear() {
        mUnknownApps.clear();
    }

    String getDebugMessage() {
        final StringBuilder builder = new StringBuilder();
        for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
            builder.append("app=").append(mUnknownApps.keyAt(i))
                    .append(" state=").append(mUnknownApps.valueAt(i));
            if (i != 0) {
                builder.append(' ');
            }
        }
        return builder.toString();
    }

    void appRemovedOrHidden(@NonNull AppWindowToken appWindow) {
        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
            Slog.d(TAG, "App removed or hidden appWindow=" + appWindow);
        }
        mUnknownApps.remove(appWindow);
    }

    /**
     * Notifies that {@param appWindow} has been launched behind Keyguard, and we need to wait until
     * it is resumed and relaid out to resolve the visibility.
     */
    void notifyLaunched(@NonNull AppWindowToken appWindow) {
        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
            Slog.d(TAG, "App launched appWindow=" + appWindow);
        }
        mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RESUME);
    }

    /**
     * Notifies that {@param appWindow} has finished resuming.
     */
    void notifyAppResumedFinished(@NonNull AppWindowToken appWindow) {
        if (mUnknownApps.containsKey(appWindow)
                && mUnknownApps.get(appWindow) == UNKNOWN_STATE_WAITING_RESUME) {
            if (DEBUG_UNKNOWN_APP_VISIBILITY) {
                Slog.d(TAG, "App resume finished appWindow=" + appWindow);
            }
            mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RELAYOUT);
        }
    }

    /**
     * Notifies that {@param appWindow} has relaid out.
     */
    void notifyRelayouted(@NonNull AppWindowToken appWindow) {
        if (!mUnknownApps.containsKey(appWindow)) {
            return;
        }
        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
            Slog.d(TAG, "App relayouted appWindow=" + appWindow);
        }
        int state = mUnknownApps.get(appWindow);
        if (state == UNKNOWN_STATE_WAITING_RELAYOUT) {
            mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
            mService.notifyKeyguardFlagsChanged(this::notifyVisibilitiesUpdated,
                    appWindow.getDisplayContent().getDisplayId());
        }
    }

    private void notifyVisibilitiesUpdated() {
        if (DEBUG_UNKNOWN_APP_VISIBILITY) {
            Slog.d(TAG, "Visibility updated DONE");
        }
        boolean changed = false;
        for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
            if (mUnknownApps.valueAt(i) == UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE) {
                mUnknownApps.removeAt(i);
                changed = true;
            }
        }
        if (changed) {
            mService.mWindowPlacerLocked.performSurfacePlacement();
        }
    }

    void dump(PrintWriter pw, String prefix) {
        if (mUnknownApps.isEmpty()) {
            return;
        }
        pw.println(prefix + "Unknown visibilities:");
        for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
            pw.println(prefix + "  app=" + mUnknownApps.keyAt(i)
                    + " state=" + mUnknownApps.valueAt(i));
        }
    }
}
