blob: 848eff4b56f36f8a1ca5fe3fe445b40509a6fdce [file] [log] [blame]
/*
* 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;
}
}