final Handler mHandler = new Handler();
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
- // Most recent call to requestVisibleBehind().
- @Deprecated
- boolean mVisibleBehind;
-
private static final class ManagedCursor {
ManagedCursor(Cursor cursor) {
mCursor = cursor;
@Deprecated
@SystemApi
public boolean isBackgroundVisibleBehind() {
- try {
- return ActivityManager.getService().isBackgroundVisibleBehind(mToken);
- } catch (RemoteException e) {
- }
return false;
}
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.Canvas;
-import android.graphics.GraphicBuffer;
-import android.graphics.Matrix;
-import android.graphics.Point;
-import android.os.BatteryStats;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-
-import com.android.internal.app.procstats.ProcessStats;
-import com.android.internal.os.RoSystemProperties;
-import com.android.internal.os.TransferPipe;
-import com.android.internal.util.FastPrintWriter;
-import com.android.server.LocalServices;
-
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.UriPermission;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.GraphicBuffer;
+import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.os.BatteryStats;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.util.Singleton;
import android.util.Size;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.os.RoSystemProperties;
+import com.android.internal.os.TransferPipe;
+import com.android.internal.util.FastPrintWriter;
+import com.android.server.LocalServices;
+
import org.xmlpull.v1.XmlSerializer;
import java.io.FileDescriptor;
}
/**
- * Returns true if activities contained in this stack can request visible behind by
- * calling {@link Activity#requestVisibleBehind}.
- *
- * @deprecated This method's functionality is no longer supported as of
- * {@link android.os.Build.VERSION_CODES#O} and will be removed in a future release.
- */
- @Deprecated
- public static boolean activitiesCanRequestVisibleBehind(int stackId) {
- return stackId == FULLSCREEN_WORKSPACE_STACK_ID ||
- stackId == ASSISTANT_STACK_ID;
- }
-
- /**
* Returns true if this stack may be scaled without resizing, and windows within may need
* to be configured as such.
*/
sb.append(", startedActivity=").append(activity.mStartedActivity);
sb.append(", temporaryPause=").append(activity.mTemporaryPause);
sb.append(", changingConfigurations=").append(activity.mChangingConfigurations);
- sb.append(", visibleBehind=").append(activity.mVisibleBehind);
sb.append("}");
}
sb.append("}");
}
@Override
- public void scheduleCancelVisibleBehind(IBinder token) {
- sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
- }
-
- @Override
- public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
- sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
- }
-
- @Override
public void scheduleEnterAnimationComplete(IBinder token) {
sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
}
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
public static final int INSTALL_PROVIDER = 145;
public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
- public static final int CANCEL_VISIBLE_BEHIND = 147;
- public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
public static final int ENTER_ANIMATION_COMPLETE = 149;
public static final int START_BINDER_TRACKING = 150;
public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
- case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
- case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
onNewActivityOptions(pair.first, pair.second);
break;
- case CANCEL_VISIBLE_BEHIND:
- handleCancelVisibleBehind((IBinder) msg.obj);
- break;
- case BACKGROUND_VISIBLE_BEHIND_CHANGED:
- handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
- break;
case ENTER_ANIMATION_COMPLETE:
handleEnterAnimationComplete((IBinder) msg.obj);
break;
}
}
- public void handleCancelVisibleBehind(IBinder token) {
- ActivityClientRecord r = mActivities.get(token);
- if (r != null) {
- mSomeActivitiesChanged = true;
- final Activity activity = r.activity;
- if (activity.mVisibleBehind) {
- activity.mCalled = false;
- activity.onVisibleBehindCanceled();
- // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
- if (!activity.mCalled) {
- throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
- " did not call through to super.onVisibleBehindCanceled()");
- }
- activity.mVisibleBehind = false;
- }
- }
- try {
- ActivityManager.getService().backgroundResourcesReleased(token);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
- ActivityClientRecord r = mActivities.get(token);
- if (r != null) {
- r.activity.onBackgroundVisibleBehindChanged(visible);
- }
- }
-
public void handleInstallProvider(ProviderInfo info) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
void stopSystemLockTaskMode();
void finishVoiceTask(in IVoiceInteractionSession session);
boolean isTopOfTask(in IBinder token);
- boolean requestVisibleBehind(in IBinder token, boolean visible);
- boolean isBackgroundVisibleBehind(in IBinder token);
- void backgroundResourcesReleased(in IBinder token);
void notifyLaunchTaskBehindComplete(in IBinder token);
int startActivityFromRecents(int taskId, in Bundle options);
void notifyEnterAnimationComplete(in IBinder token);
void setProcessState(int state);
void scheduleInstallProvider(in ProviderInfo provider);
void updateTimePrefs(int timeFormatPreference);
- void scheduleCancelVisibleBehind(IBinder token);
- void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled);
void scheduleEnterAnimationComplete(IBinder token);
void notifyCleartextNetwork(in byte[] firstPacket);
void startBinderTracking();
static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
- static final boolean DEBUG_VISIBLE_BEHIND = DEBUG_ALL_ACTIVITIES || false;
static final boolean DEBUG_USAGE_STATS = DEBUG_ALL || false;
static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false;
static final boolean DEBUG_WHITELISTS = DEBUG_ALL || false;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
}
@Override
- public final void backgroundResourcesReleased(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- stack.backgroundResourcesReleased();
- }
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
public final void notifyLaunchTaskBehindComplete(IBinder token) {
mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
}
}
final boolean translucentChanged = r.changeWindowTranslucency(true);
if (translucentChanged) {
- r.getStack().releaseBackgroundResources(r);
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
mWindowManager.setAppFullscreen(token, true);
}
@Override
- public boolean requestVisibleBehind(IBinder token, boolean visible) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r != null) {
- return mStackSupervisor.requestVisibleBehindLocked(r, visible);
- }
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public boolean isBackgroundVisibleBehind(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityStack stack = ActivityRecord.getStackLocked(token);
- final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
- "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
- return visible;
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
public Bundle getActivityOptions(IBinder token) {
final long origId = Binder.clearCallingIdentity();
try {
}
void makeFinishingLocked() {
- if (!finishing) {
- final ActivityStack stack = getStack();
- if (stack != null && this == stack.getVisibleBehindActivity()) {
- // A finishing activity should not remain as visible in the background
- mStackSupervisor.requestVisibleBehindLocked(this, false);
- }
- finishing = true;
- if (stopped) {
- clearOptionsLocked();
- }
+ if (finishing) {
+ return;
+ }
+ finishing = true;
+ if (stopped) {
+ clearOptionsLocked();
+ }
- if (service != null) {
- service.mTaskChangeNotificationController.notifyTaskStackChanged();
- }
+ if (service != null) {
+ service.mTaskChangeNotificationController.notifyTaskStackChanged();
}
}
*
* @see {@link ActivityStack#checkKeyguardVisibility}
*/
- boolean shouldBeVisibleIgnoringKeyguard(boolean behindTranslucentActivity,
- boolean stackVisibleBehind, ActivityRecord visibleBehind,
- boolean behindFullscreenActivity) {
+ boolean shouldBeVisibleIgnoringKeyguard(boolean behindFullscreenActivity) {
if (!okToShowLocked()) {
return false;
}
- // mLaunchingBehind: Activities launching behind are at the back of the task stack
- // but must be drawn initially for the animation as though they were visible.
- final boolean activityVisibleBehind =
- (behindTranslucentActivity || stackVisibleBehind) && visibleBehind == this;
-
- boolean isVisible =
- !behindFullscreenActivity || mLaunchTaskBehind || activityVisibleBehind;
+ boolean isVisible = !behindFullscreenActivity || mLaunchTaskBehind;
if (service.mSupportsLeanbackOnly && isVisible && isRecentsActivity()) {
// On devices that support leanback only (Android TV), Recents activity can only be
}
returningOptions = null;
-
- if (stack.getVisibleBehindActivity() == this) {
- // When resuming an activity, require it to call requestVisibleBehind() again.
- stack.setVisibleBehindActivity(null /* ActivityRecord */);
- }
mStackSupervisor.checkReadyForSleepLocked();
}
mWindowContainerController.notifyAppStopped();
- if (stack.getVisibleBehindActivity() == this) {
- mStackSupervisor.requestVisibleBehindLocked(this, false /* visible */);
- }
if (finishing) {
clearOptionsLocked();
} else {
static final int STACK_INVISIBLE = 0;
// Stack is considered visible
static final int STACK_VISIBLE = 1;
- // Stack is considered visible, but only becuase it has activity that is visible behind other
- // activities and there is a specific combination of stacks.
- static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2;
@VisibleForTesting
/* The various modes for the method {@link #removeTask}. */
static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
- static final int RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG =
- ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
private static class ScheduleDestroyArgs {
final ProcessRecord mOwner;
notifyActivityDrawnLocked(null);
}
} break;
- case RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG: {
- synchronized (mService) {
- final ActivityRecord r = getVisibleBehindActivity();
- Slog.e(TAG, "Timeout waiting for cancelVisibleBehind player=" + r);
- if (r != null) {
- mService.killAppAtUsersRequest(r.app, null);
- }
- }
- } break;
}
}
}
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep still waiting to pause " + mPausingActivity);
return true;
}
-
- if (hasVisibleBehindActivity()) {
- // Stop visible behind activity before going to sleep.
- final ActivityRecord r = getVisibleBehindActivity();
- mStackSupervisor.mStoppingActivities.add(r);
- if (DEBUG_STATES) Slog.v(TAG_STATES, "Sleep still waiting to stop visible behind " + r);
- return true;
- }
-
return false;
}
// We can't clobber it, because the stop confirmation will not be handled.
// We don't need to schedule another stop, we only need to let it happen.
prev.state = STOPPING;
- } else if ((!prev.visible && !hasVisibleBehindActivity())
- || mService.isSleepingOrShuttingDownLocked()) {
+ } else if (!prev.visible || mService.isSleepingOrShuttingDownLocked()) {
// Clear out any deferred client hide we might currently have.
prev.setDeferHidingClient(false);
// If we were visible then resumeTopActivities will release resources before
}
/**
- * Returns what the stack visibility should be: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE}
- * or {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
+ * Returns what the stack visibility should be: {@link #STACK_INVISIBLE} or
+ * {@link #STACK_VISIBLE}.
*
* @param starting The currently starting activity or null if there is none.
*/
final ActivityStack topStack = getTopStackOnDisplay();
final int topStackId = topStack.mStackId;
- if (StackId.isBackdropToTranslucentActivity(mStackId)
- && hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(topStackId)
- && (topStack.topActivity() == null || !topStack.topActivity().fullscreen)) {
- // The fullscreen or assistant stack should be visible if it has a visible behind
- // activity behind the home or recents stack that is translucent.
- return STACK_VISIBLE_ACTIVITY_BEHIND;
- }
-
if (mStackId == DOCKED_STACK_ID) {
// If the assistant stack is focused and translucent, then the docked stack is always
// visible
boolean aboveTop = top != null;
final int stackVisibility = shouldBeVisible(starting);
final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
- final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
boolean behindFullscreenActivity = stackInvisible;
boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
&& (isInStackLocked(starting) == null);
boolean behindTranslucentActivity = false;
- final ActivityRecord visibleBehind = getVisibleBehindActivity();
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
// Check whether activity should be visible without Keyguard influence
final boolean visibleIgnoringKeyguard = r.shouldBeVisibleIgnoringKeyguard(
- behindTranslucentActivity, stackVisibleBehind, visibleBehind,
behindFullscreenActivity);
r.visibleIgnoringKeyguard = visibleIgnoringKeyguard;
+ stackInvisible + " behindFullscreenActivity="
+ behindFullscreenActivity + " mLaunchTaskBehind="
+ r.mLaunchTaskBehind);
- makeInvisible(r, visibleBehind);
+ makeInvisible(r);
}
}
if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
return false;
}
- private void makeInvisible(ActivityRecord r, ActivityRecord visibleBehind) {
+ // TODO: Should probably be moved into ActivityRecord.
+ private void makeInvisible(ActivityRecord r) {
if (!r.visible) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r);
return;
case RESUMED:
case PAUSING:
case PAUSED:
- // This case created for transitioning activities from
- // translucent to opaque {@link Activity#convertToOpaque}.
- if (visibleBehind == r) {
- releaseBackgroundResources(r);
- } else {
- addToStopping(r, true /* scheduleIdle */,
- canEnterPictureInPicture /* idleDelayed */);
- }
+ addToStopping(r, true /* scheduleIdle */,
+ canEnterPictureInPicture /* idleDelayed */);
break;
default:
// Get rid of any pending idle timeouts.
removeTimeoutsForActivityLocked(r);
- if (getVisibleBehindActivity() == r) {
- mStackSupervisor.requestVisibleBehindLocked(r, false);
- }
-
// Clean-up activities are no longer relaunching (e.g. app process died). Notify window
// manager so it can update its bookkeeping.
mWindowManager.notifyAppRelaunchesCleared(r.appToken);
}
}
- void releaseBackgroundResources(ActivityRecord r) {
- if (hasVisibleBehindActivity() &&
- !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
- if (r == topRunningActivityLocked()
- && shouldBeVisible(null) == STACK_VISIBLE) {
- // Don't release the top activity if it has requested to run behind the next
- // activity and the stack is currently visible.
- return;
- }
- if (DEBUG_STATES) Slog.d(TAG_STATES, "releaseBackgroundResources activtyDisplay=" +
- mActivityContainer.mActivityDisplay + " visibleBehind=" + r + " app=" + r.app +
- " thread=" + r.app.thread);
- if (r != null && r.app != null && r.app.thread != null) {
- try {
- r.app.thread.scheduleCancelVisibleBehind(r.appToken);
- } catch (RemoteException e) {
- }
- mHandler.sendEmptyMessageDelayed(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG, 500);
- } else {
- Slog.e(TAG, "releaseBackgroundResources: activity " + r + " no longer running");
- backgroundResourcesReleased();
- }
- }
- }
-
- final void backgroundResourcesReleased() {
- mHandler.removeMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG);
- final ActivityRecord r = getVisibleBehindActivity();
- if (r != null) {
- mStackSupervisor.mStoppingActivities.add(r);
- setVisibleBehindActivity(null);
- mStackSupervisor.scheduleIdleTimeoutLocked(null);
- }
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
- }
-
- boolean hasVisibleBehindActivity() {
- return isAttached() && mActivityContainer.mActivityDisplay.hasVisibleBehindActivity();
- }
-
- void setVisibleBehindActivity(ActivityRecord r) {
- if (isAttached()) {
- mActivityContainer.mActivityDisplay.setVisibleBehindActivity(r);
- }
- }
-
- ActivityRecord getVisibleBehindActivity() {
- return isAttached() ? mActivityContainer.mActivityDisplay.mVisibleBehindActivity : null;
- }
-
private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
ProcessRecord app, String listName) {
int i = list.size();
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
- if (mStackId == HOME_STACK_ID && topTask().isHomeTask()) {
- // For the case where we are moving the home task back and there is an activity visible
- // behind it on the fullscreen or assistant stack, we want to move the focus to the
- // visible behind activity to maintain order with what the user is seeing.
- ActivityRecord visibleBehind = null;
- final ActivityStack fullscreenStack =
- mStackSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID);
- final ActivityStack assistantStack =
- mStackSupervisor.getStack(ASSISTANT_STACK_ID);
- if (fullscreenStack != null && fullscreenStack.hasVisibleBehindActivity()) {
- visibleBehind = fullscreenStack.getVisibleBehindActivity();
- } else if (assistantStack != null && assistantStack.hasVisibleBehindActivity()) {
- visibleBehind = assistantStack.getVisibleBehindActivity();
- }
- if (visibleBehind != null) {
- mStackSupervisor.moveFocusableActivityStackToFrontLocked(visibleBehind,
- "moveTaskToBack");
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
- return true;
- }
- }
-
boolean prevIsHome = false;
// If true, we should resume the home activity next if the task we are moving to the
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
try {
final TaskRecord task = r.getTask();
-
- if (r == task.getStack().getVisibleBehindActivity()) {
- // An activity can't be pinned and visible behind at the same time. Go ahead and
- // release it from been visible behind before pinning.
- requestVisibleBehindLocked(r, false);
- }
-
// Resize the pinned stack to match the current size of the task the activity we are
// going to be moving is currently contained in. We do this to have the right starting
// animation bounds for the pinned stack to the desired bounds the caller wants.
}
}
- boolean requestVisibleBehindLocked(ActivityRecord r, boolean visible) {
- final ActivityStack stack = r.getStack();
- if (stack == null) {
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
- "requestVisibleBehind: r=" + r + " visible=" + visible + " stack is null");
- return false;
- }
-
- if (visible && !StackId.activitiesCanRequestVisibleBehind(stack.mStackId)) {
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: r=" + r
- + " visible=" + visible + " stackId=" + stack.mStackId
- + " can't contain visible behind activities");
- return false;
- }
-
- final boolean isVisible = stack.hasVisibleBehindActivity();
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
- "requestVisibleBehind r=" + r + " visible=" + visible + " isVisible=" + isVisible);
-
- final ActivityRecord top = topRunningActivityLocked();
- if (top == null || top == r || (visible == isVisible)) {
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, "requestVisibleBehind: quick return");
- stack.setVisibleBehindActivity(visible ? r : null);
- return true;
- }
-
- // A non-top activity is reporting a visibility change.
- if (visible && top.fullscreen) {
- // Let the caller know that it can't be seen.
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
- "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen
- + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread="
- + top.app.thread);
- return false;
- } else if (!visible && stack.getVisibleBehindActivity() != r) {
- // Only the activity set as currently visible behind should actively reset its
- // visible behind state.
- if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
- "requestVisibleBehind: returning visible=" + visible
- + " stack.getVisibleBehindActivity()=" + stack.getVisibleBehindActivity()
- + " r=" + r);
- return false;
- }
-
- stack.setVisibleBehindActivity(visible ? r : null);
- if (!visible) {
- // If there is a translucent home activity, we need to force it stop being translucent,
- // because we can't depend on the application to necessarily perform that operation.
- // Check out b/14469711 for details.
- final ActivityRecord next = stack.findNextTranslucentActivity(r);
- if (next != null && next.isHomeActivity()) {
- mService.convertFromTranslucent(next.appToken);
- }
- }
- if (top.app != null && top.app.thread != null) {
- // Notify the top app of the change.
- try {
- top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
- } catch (RemoteException e) {
- }
- }
- return true;
- }
-
// Called when WindowManager has finished animating the launchingBehind activity to the back.
private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
final TaskRecord task = r.getTask();
* stacks, bottommost behind. Accessed directly by ActivityManager package classes */
final ArrayList<ActivityStack> mStacks = new ArrayList<>();
- ActivityRecord mVisibleBehindActivity;
-
/** Array of all UIDs that are present on the display. */
private IntArray mDisplayAccessUIDs = new IntArray();
mStacks.remove(stack);
}
- void setVisibleBehindActivity(ActivityRecord r) {
- mVisibleBehindActivity = r;
- }
-
- boolean hasVisibleBehindActivity() {
- return mVisibleBehindActivity != null;
- }
-
@Override
public String toString() {
return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}";
testStack.stopActivityLocked(activityRecord);
}
-
- /**
- * This test verifies that {@link ActivityStack#STACK_VISIBLE_ACTIVITY_BEHIND} is returned from
- * {@link ActivityStack#shouldBeVisible(ActivityRecord)} from a fullscreen workspace stack with
- * a visible behind activity when top focused stack is the home stack.
- */
- @Test
- public void testShouldBeVisibleWithVisibleBehindActivity() throws Exception {
- final ActivityManagerService service = createActivityManagerService();
- final TaskRecord task = createTask(service, testActivityComponent,
- ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID);
- final ActivityStack fullscreenWorkspaceStackId = task.getStack();
- final ActivityStack homeStack = service.mStackSupervisor.getStack(
- ActivityManager.StackId.HOME_STACK_ID, true /*createStaticStackIfNeeded*/,
- true /*onTop*/);
- final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
- service.mStackSupervisor.setFocusStackUnchecked("testEmptyStackShouldBeVisible", homeStack);
- service.mStackSupervisor.requestVisibleBehindLocked(activityRecord, true);
- assertEquals(ActivityStack.STACK_VISIBLE_ACTIVITY_BEHIND,
- fullscreenWorkspaceStackId.shouldBeVisible(null /*starting*/));
- }
}