/*
 * Copyright (C) 2021 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.wm.shell.startingsurface.phone;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;

import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_SPLASH_SCREEN;
import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_TASK_SNAPSHOT;

import android.util.Slog;
import android.window.StartingWindowInfo;
import android.window.TaskSnapshot;

import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;

/**
 * Algorithm for determining the type of a new starting window on handheld devices.
 * At the moment also used on Android Auto.
 */
public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgorithm {
    private static final String TAG = PhoneStartingWindowTypeAlgorithm.class.getSimpleName();

    @Override
    public int getSuggestedWindowType(StartingWindowInfo windowInfo) {
        final int parameter = windowInfo.startingWindowTypeParameter;
        final boolean newTask = (parameter & TYPE_PARAMETER_NEW_TASK) != 0;
        final boolean taskSwitch = (parameter & TYPE_PARAMETER_TASK_SWITCH) != 0;
        final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0;
        final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0;
        final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0;
        final boolean useEmptySplashScreen =
                (parameter & TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN) != 0;
        final boolean legacySplashScreen =
                ((parameter & TYPE_PARAMETER_LEGACY_SPLASH_SCREEN) != 0);
        final boolean topIsHome = windowInfo.taskInfo.topActivityType == ACTIVITY_TYPE_HOME;

        if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
            Slog.d(TAG, "preferredStartingWindowType newTask:" + newTask
                    + " taskSwitch:" + taskSwitch
                    + " processRunning:" + processRunning
                    + " allowTaskSnapshot:" + allowTaskSnapshot
                    + " activityCreated:" + activityCreated
                    + " useEmptySplashScreen:" + useEmptySplashScreen
                    + " legacySplashScreen:" + legacySplashScreen
                    + " topIsHome:" + topIsHome);
        }

        final int visibleSplashScreenType = legacySplashScreen
                ? STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
                : STARTING_WINDOW_TYPE_SPLASH_SCREEN;

        if (!topIsHome) {
            if (!processRunning) {
                return useEmptySplashScreen
                        ? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                        : visibleSplashScreenType;
            }
            if (newTask) {
                return useEmptySplashScreen
                        ? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
                        : visibleSplashScreenType;
            }
            if (taskSwitch && !activityCreated) {
                return visibleSplashScreenType;
            }
        }
        if (taskSwitch && allowTaskSnapshot) {
            if (isSnapshotCompatible(windowInfo)) {
                return STARTING_WINDOW_TYPE_SNAPSHOT;
            }
            if (!topIsHome) {
                return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
            }
        }
        return STARTING_WINDOW_TYPE_NONE;
    }


    /**
     * Returns {@code true} if the task snapshot is compatible with this activity (at least the
     * rotation must be the same).
     */
    private boolean isSnapshotCompatible(StartingWindowInfo windowInfo) {
        final TaskSnapshot snapshot = windowInfo.mTaskSnapshot;
        if (snapshot == null) {
            if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
                Slog.d(TAG, "isSnapshotCompatible no snapshot " + windowInfo.taskInfo.taskId);
            }
            return false;
        }
        if (!snapshot.getTopActivityComponent().equals(windowInfo.taskInfo.topActivity)) {
            if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
                Slog.d(TAG, "isSnapshotCompatible obsoleted snapshot "
                        + windowInfo.taskInfo.topActivity);
            }
            return false;
        }

        final int taskRotation = windowInfo.taskInfo.configuration
                .windowConfiguration.getRotation();
        final int snapshotRotation = snapshot.getRotation();
        if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
            Slog.d(TAG, "isSnapshotCompatible rotation " + taskRotation
                    + " snapshot " + snapshotRotation);
        }
        return taskRotation == snapshotRotation;
    }
}
