Use START/STOP messages to update visibility
Activity visibility messages simply move the activity to STOPPED or STARTED state. We can use the lifecycle messages to do the same and simplify the logic/remove duplicated code. This CL also removes the option to send STOP message without making the client invisible and actually calling onStop(). This option caused a mismatch of the state between server (STOPPED) and client (PAUSED). Also, in cases when the device was going to sleep, STOP message was always followed by SLEEP message, which called onStop() anyway. Bug: 137329632 Bug: 129750406 Test: AM/WM CTS and unit tests Change-Id: I487575520ce301bb2f65519f0c0a30b6b9edac0c
This commit is contained in:
@@ -3349,8 +3349,8 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleStartActivity(ActivityClientRecord r,
|
public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) {
|
||||||
PendingTransactionActions pendingActions) {
|
final ActivityClientRecord r = mActivities.get(token);
|
||||||
final Activity activity = r.activity;
|
final Activity activity = r.activity;
|
||||||
if (r.activity == null) {
|
if (r.activity == null) {
|
||||||
// TODO(lifecycler): What do we do in this case?
|
// TODO(lifecycler): What do we do in this case?
|
||||||
@@ -3364,6 +3364,8 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unscheduleGcIdler();
|
||||||
|
|
||||||
// Start
|
// Start
|
||||||
activity.performStart("handleStartActivity");
|
activity.performStart("handleStartActivity");
|
||||||
r.setState(ON_START);
|
r.setState(ON_START);
|
||||||
@@ -3400,6 +3402,9 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
+ " did not call through to super.onPostCreate()");
|
+ " did not call through to super.onPostCreate()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateVisibility(r, true /* show */);
|
||||||
|
mSomeActivitiesChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4660,8 +4665,8 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
final void performStopActivity(IBinder token, boolean saveState, String reason) {
|
final void performStopActivity(IBinder token, boolean saveState, String reason) {
|
||||||
ActivityClientRecord r = mActivities.get(token);
|
ActivityClientRecord r = mActivities.get(token);
|
||||||
performStopActivityInner(r, null /* stopInfo */, false /* keepShown */, saveState,
|
performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */,
|
||||||
false /* finalStateRequest */, reason);
|
reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ProviderRefCount {
|
private static final class ProviderRefCount {
|
||||||
@@ -4687,25 +4692,19 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core implementation of stopping an activity. Note this is a little
|
* Core implementation of stopping an activity.
|
||||||
* tricky because the server's meaning of stop is slightly different
|
|
||||||
* than our client -- for the server, stop means to save state and give
|
|
||||||
* it the result when it is done, but the window may still be visible.
|
|
||||||
* For the client, we want to call onStop()/onStart() to indicate when
|
|
||||||
* the activity's UI visibility changes.
|
|
||||||
* @param r Target activity client record.
|
* @param r Target activity client record.
|
||||||
* @param info Action that will report activity stop to server.
|
* @param info Action that will report activity stop to server.
|
||||||
* @param keepShown Flag indicating whether the activity is still shown.
|
|
||||||
* @param saveState Flag indicating whether the activity state should be saved.
|
* @param saveState Flag indicating whether the activity state should be saved.
|
||||||
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
|
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
|
||||||
* request for a transaction.
|
* request for a transaction.
|
||||||
* @param reason Reason for performing this operation.
|
* @param reason Reason for performing this operation.
|
||||||
*/
|
*/
|
||||||
private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
|
private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
|
||||||
boolean saveState, boolean finalStateRequest, String reason) {
|
boolean saveState, boolean finalStateRequest, String reason) {
|
||||||
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
|
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
if (!keepShown && r.stopped) {
|
if (r.stopped) {
|
||||||
if (r.activity.mFinished) {
|
if (r.activity.mFinished) {
|
||||||
// If we are finishing, we won't call onResume() in certain
|
// If we are finishing, we won't call onResume() in certain
|
||||||
// cases. So here we likewise don't want to call onStop()
|
// cases. So here we likewise don't want to call onStop()
|
||||||
@@ -4740,9 +4739,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keepShown) {
|
callActivityOnStop(r, saveState, reason);
|
||||||
callActivityOnStop(r, saveState, reason);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4810,20 +4807,19 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleStopActivity(IBinder token, boolean show, int configChanges,
|
public void handleStopActivity(IBinder token, int configChanges,
|
||||||
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
|
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
|
||||||
final ActivityClientRecord r = mActivities.get(token);
|
final ActivityClientRecord r = mActivities.get(token);
|
||||||
r.activity.mConfigChangeFlags |= configChanges;
|
r.activity.mConfigChangeFlags |= configChanges;
|
||||||
|
|
||||||
final StopInfo stopInfo = new StopInfo();
|
final StopInfo stopInfo = new StopInfo();
|
||||||
performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
|
performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest,
|
||||||
reason);
|
reason);
|
||||||
|
|
||||||
if (localLOGV) Slog.v(
|
if (localLOGV) Slog.v(
|
||||||
TAG, "Finishing stop of " + r + ": show=" + show
|
TAG, "Finishing stop of " + r + ": win=" + r.window);
|
||||||
+ " win=" + r.window);
|
|
||||||
|
|
||||||
updateVisibility(r, show);
|
updateVisibility(r, false);
|
||||||
|
|
||||||
// Make sure any pending writes are now committed.
|
// Make sure any pending writes are now committed.
|
||||||
if (!r.isPreHoneycomb()) {
|
if (!r.isPreHoneycomb()) {
|
||||||
@@ -4859,34 +4855,6 @@ public final class ActivityThread extends ClientTransactionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleWindowVisibility(IBinder token, boolean show) {
|
|
||||||
ActivityClientRecord r = mActivities.get(token);
|
|
||||||
|
|
||||||
if (r == null) {
|
|
||||||
Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!show && !r.stopped) {
|
|
||||||
performStopActivityInner(r, null /* stopInfo */, show, false /* saveState */,
|
|
||||||
false /* finalStateRequest */, "handleWindowVisibility");
|
|
||||||
} else if (show && r.getLifecycleState() == ON_STOP) {
|
|
||||||
// If we are getting ready to gc after going to the background, well
|
|
||||||
// we are back active so skip it.
|
|
||||||
unscheduleGcIdler();
|
|
||||||
|
|
||||||
r.activity.performRestart(true /* start */, "handleWindowVisibility");
|
|
||||||
r.setState(ON_START);
|
|
||||||
}
|
|
||||||
if (r.activity.mDecor != null) {
|
|
||||||
if (false) Slog.v(
|
|
||||||
TAG, "Handle window " + r + " visibility: " + show);
|
|
||||||
updateVisibility(r, show);
|
|
||||||
}
|
|
||||||
mSomeActivitiesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: This method should be changed to use {@link #performStopActivityInner} to perform to
|
// TODO: This method should be changed to use {@link #performStopActivityInner} to perform to
|
||||||
// stop operation on the activity to reduce code duplication and the chance of fixing a bug in
|
// stop operation on the activity to reduce code duplication and the chance of fixing a bug in
|
||||||
// one place and missing the other.
|
// one place and missing the other.
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ public abstract class ClientTransactionHandler {
|
|||||||
/**
|
/**
|
||||||
* Stop the activity.
|
* Stop the activity.
|
||||||
* @param token Target activity token.
|
* @param token Target activity token.
|
||||||
* @param show Flag indicating whether activity is still shown.
|
|
||||||
* @param configChanges Activity configuration changes.
|
* @param configChanges Activity configuration changes.
|
||||||
* @param pendingActions Pending actions to be used on this or later stages of activity
|
* @param pendingActions Pending actions to be used on this or later stages of activity
|
||||||
* transaction.
|
* transaction.
|
||||||
@@ -127,7 +126,7 @@ public abstract class ClientTransactionHandler {
|
|||||||
* request for a transaction.
|
* request for a transaction.
|
||||||
* @param reason Reason for performing this operation.
|
* @param reason Reason for performing this operation.
|
||||||
*/
|
*/
|
||||||
public abstract void handleStopActivity(IBinder token, boolean show, int configChanges,
|
public abstract void handleStopActivity(IBinder token, int configChanges,
|
||||||
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
|
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
|
||||||
|
|
||||||
/** Report that activity was stopped to server. */
|
/** Report that activity was stopped to server. */
|
||||||
@@ -161,15 +160,12 @@ public abstract class ClientTransactionHandler {
|
|||||||
/** Request that an activity enter picture-in-picture. */
|
/** Request that an activity enter picture-in-picture. */
|
||||||
public abstract void handlePictureInPictureRequested(IBinder token);
|
public abstract void handlePictureInPictureRequested(IBinder token);
|
||||||
|
|
||||||
/** Update window visibility. */
|
|
||||||
public abstract void handleWindowVisibility(IBinder token, boolean show);
|
|
||||||
|
|
||||||
/** Perform activity launch. */
|
/** Perform activity launch. */
|
||||||
public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
|
public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
|
||||||
PendingTransactionActions pendingActions, Intent customIntent);
|
PendingTransactionActions pendingActions, Intent customIntent);
|
||||||
|
|
||||||
/** Perform activity start. */
|
/** Perform activity start. */
|
||||||
public abstract void handleStartActivity(ActivityThread.ActivityClientRecord r,
|
public abstract void handleStartActivity(IBinder token,
|
||||||
PendingTransactionActions pendingActions);
|
PendingTransactionActions pendingActions);
|
||||||
|
|
||||||
/** Get package info. */
|
/** Get package info. */
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public class LocalActivityManager {
|
|||||||
pendingActions = null;
|
pendingActions = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
mActivityThread.handleStartActivity(clientRecord, pendingActions);
|
mActivityThread.handleStartActivity(r, pendingActions);
|
||||||
r.curState = STARTED;
|
r.curState = STARTED;
|
||||||
|
|
||||||
if (desiredState == RESUMED) {
|
if (desiredState == RESUMED) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 The Android Open Source Project
|
* Copyright 2019 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -24,41 +24,44 @@ import android.os.Parcel;
|
|||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Window visibility change message.
|
* Request to move an activity to started and visible state.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class WindowVisibilityItem extends ClientTransactionItem {
|
public class StartActivityItem extends ActivityLifecycleItem {
|
||||||
|
|
||||||
private boolean mShowWindow;
|
private static final String TAG = "StartActivityItem";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ClientTransactionHandler client, IBinder token,
|
public void execute(ClientTransactionHandler client, IBinder token,
|
||||||
PendingTransactionActions pendingActions) {
|
PendingTransactionActions pendingActions) {
|
||||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
|
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "startActivityItem");
|
||||||
mShowWindow ? "activityShowWindow" : "activityHideWindow");
|
client.handleStartActivity(token, pendingActions);
|
||||||
client.handleWindowVisibility(token, mShowWindow);
|
|
||||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTargetState() {
|
||||||
|
return ON_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ObjectPoolItem implementation
|
// ObjectPoolItem implementation
|
||||||
|
|
||||||
private WindowVisibilityItem() {}
|
private StartActivityItem() {}
|
||||||
|
|
||||||
/** Obtain an instance initialized with provided params. */
|
/** Obtain an instance initialized with provided params. */
|
||||||
public static WindowVisibilityItem obtain(boolean showWindow) {
|
public static StartActivityItem obtain() {
|
||||||
WindowVisibilityItem instance = ObjectPool.obtain(WindowVisibilityItem.class);
|
StartActivityItem instance = ObjectPool.obtain(StartActivityItem.class);
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new WindowVisibilityItem();
|
instance = new StartActivityItem();
|
||||||
}
|
}
|
||||||
instance.mShowWindow = showWindow;
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recycle() {
|
public void recycle() {
|
||||||
mShowWindow = false;
|
super.recycle();
|
||||||
ObjectPool.recycle(this);
|
ObjectPool.recycle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,24 +71,24 @@ public class WindowVisibilityItem extends ClientTransactionItem {
|
|||||||
/** Write to Parcel. */
|
/** Write to Parcel. */
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeBoolean(mShowWindow);
|
// Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read from Parcel. */
|
/** Read from Parcel. */
|
||||||
private WindowVisibilityItem(Parcel in) {
|
private StartActivityItem(Parcel in) {
|
||||||
mShowWindow = in.readBoolean();
|
// Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final @android.annotation.NonNull Creator<WindowVisibilityItem> CREATOR =
|
public static final @android.annotation.NonNull Creator<StartActivityItem> CREATOR =
|
||||||
new Creator<WindowVisibilityItem>() {
|
new Creator<StartActivityItem>() {
|
||||||
public WindowVisibilityItem createFromParcel(Parcel in) {
|
public StartActivityItem createFromParcel(Parcel in) {
|
||||||
return new WindowVisibilityItem(in);
|
return new StartActivityItem(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowVisibilityItem[] newArray(int size) {
|
public StartActivityItem[] newArray(int size) {
|
||||||
return new WindowVisibilityItem[size];
|
return new StartActivityItem[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
@@ -95,17 +98,17 @@ public class WindowVisibilityItem extends ClientTransactionItem {
|
|||||||
if (o == null || getClass() != o.getClass()) {
|
if (o == null || getClass() != o.getClass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final WindowVisibilityItem other = (WindowVisibilityItem) o;
|
return true;
|
||||||
return mShowWindow == other.mShowWindow;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return 17 + 31 * (mShowWindow ? 1 : 0);
|
return 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "WindowVisibilityItem{showWindow=" + mShowWindow + "}";
|
return "StartActivityItem{}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,14 +31,13 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
|||||||
|
|
||||||
private static final String TAG = "StopActivityItem";
|
private static final String TAG = "StopActivityItem";
|
||||||
|
|
||||||
private boolean mShowWindow;
|
|
||||||
private int mConfigChanges;
|
private int mConfigChanges;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ClientTransactionHandler client, IBinder token,
|
public void execute(ClientTransactionHandler client, IBinder token,
|
||||||
PendingTransactionActions pendingActions) {
|
PendingTransactionActions pendingActions) {
|
||||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
|
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
|
||||||
client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
|
client.handleStopActivity(token, mConfigChanges, pendingActions,
|
||||||
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
|
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
|
||||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||||
}
|
}
|
||||||
@@ -59,13 +58,15 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
|||||||
|
|
||||||
private StopActivityItem() {}
|
private StopActivityItem() {}
|
||||||
|
|
||||||
/** Obtain an instance initialized with provided params. */
|
/**
|
||||||
public static StopActivityItem obtain(boolean showWindow, int configChanges) {
|
* Obtain an instance initialized with provided params.
|
||||||
|
* @param configChanges Configuration pieces that changed.
|
||||||
|
*/
|
||||||
|
public static StopActivityItem obtain(int configChanges) {
|
||||||
StopActivityItem instance = ObjectPool.obtain(StopActivityItem.class);
|
StopActivityItem instance = ObjectPool.obtain(StopActivityItem.class);
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new StopActivityItem();
|
instance = new StopActivityItem();
|
||||||
}
|
}
|
||||||
instance.mShowWindow = showWindow;
|
|
||||||
instance.mConfigChanges = configChanges;
|
instance.mConfigChanges = configChanges;
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
@@ -74,7 +75,6 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
|||||||
@Override
|
@Override
|
||||||
public void recycle() {
|
public void recycle() {
|
||||||
super.recycle();
|
super.recycle();
|
||||||
mShowWindow = false;
|
|
||||||
mConfigChanges = 0;
|
mConfigChanges = 0;
|
||||||
ObjectPool.recycle(this);
|
ObjectPool.recycle(this);
|
||||||
}
|
}
|
||||||
@@ -85,13 +85,11 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
|||||||
/** Write to Parcel. */
|
/** Write to Parcel. */
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeBoolean(mShowWindow);
|
|
||||||
dest.writeInt(mConfigChanges);
|
dest.writeInt(mConfigChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read from Parcel. */
|
/** Read from Parcel. */
|
||||||
private StopActivityItem(Parcel in) {
|
private StopActivityItem(Parcel in) {
|
||||||
mShowWindow = in.readBoolean();
|
|
||||||
mConfigChanges = in.readInt();
|
mConfigChanges = in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,20 +113,18 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final StopActivityItem other = (StopActivityItem) o;
|
final StopActivityItem other = (StopActivityItem) o;
|
||||||
return mShowWindow == other.mShowWindow && mConfigChanges == other.mConfigChanges;
|
return mConfigChanges == other.mConfigChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = 17;
|
int result = 17;
|
||||||
result = 31 * result + (mShowWindow ? 1 : 0);
|
|
||||||
result = 31 * result + mConfigChanges;
|
result = 31 * result + mConfigChanges;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "StopActivityItem{showWindow=" + mShowWindow + ",configChanges=" + mConfigChanges
|
return "StopActivityItem{configChanges=" + mConfigChanges + "}";
|
||||||
+ "}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ public class TransactionExecutor {
|
|||||||
null /* customIntent */);
|
null /* customIntent */);
|
||||||
break;
|
break;
|
||||||
case ON_START:
|
case ON_START:
|
||||||
mTransactionHandler.handleStartActivity(r, mPendingActions);
|
mTransactionHandler.handleStartActivity(r.token, mPendingActions);
|
||||||
break;
|
break;
|
||||||
case ON_RESUME:
|
case ON_RESUME:
|
||||||
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
|
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
|
||||||
@@ -230,8 +230,8 @@ public class TransactionExecutor {
|
|||||||
"LIFECYCLER_PAUSE_ACTIVITY");
|
"LIFECYCLER_PAUSE_ACTIVITY");
|
||||||
break;
|
break;
|
||||||
case ON_STOP:
|
case ON_STOP:
|
||||||
mTransactionHandler.handleStopActivity(r.token, false /* show */,
|
mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
|
||||||
0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
|
mPendingActions, false /* finalStateRequest */,
|
||||||
"LIFECYCLER_STOP_ACTIVITY");
|
"LIFECYCLER_STOP_ACTIVITY");
|
||||||
break;
|
break;
|
||||||
case ON_DESTROY:
|
case ON_DESTROY:
|
||||||
|
|||||||
@@ -183,8 +183,7 @@ public class TransactionExecutorHelper {
|
|||||||
lifecycleItem = PauseActivityItem.obtain();
|
lifecycleItem = PauseActivityItem.obtain();
|
||||||
break;
|
break;
|
||||||
case ON_STOP:
|
case ON_STOP:
|
||||||
lifecycleItem = StopActivityItem.obtain(r.isVisibleFromServer(),
|
lifecycleItem = StopActivityItem.obtain(0 /* configChanges */);
|
||||||
0 /* configChanges */);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lifecycleItem = ResumeActivityItem.obtain(false /* isForward */);
|
lifecycleItem = ResumeActivityItem.obtain(false /* isForward */);
|
||||||
|
|||||||
@@ -438,8 +438,7 @@ public class ActivityThreadTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ClientTransaction newStopTransaction(Activity activity) {
|
private static ClientTransaction newStopTransaction(Activity activity) {
|
||||||
final StopActivityItem stopStateRequest =
|
final StopActivityItem stopStateRequest = StopActivityItem.obtain(0 /* configChanges */);
|
||||||
StopActivityItem.obtain(false /* showWindow */, 0 /* configChanges */);
|
|
||||||
|
|
||||||
final ClientTransaction transaction = newTransaction(activity);
|
final ClientTransaction transaction = newTransaction(activity);
|
||||||
transaction.setLifecycleStateRequest(stopStateRequest);
|
transaction.setLifecycleStateRequest(stopStateRequest);
|
||||||
|
|||||||
@@ -274,30 +274,15 @@ public class ObjectPoolTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRecycleStopItem() {
|
public void testRecycleStopItem() {
|
||||||
StopActivityItem emptyItem = StopActivityItem.obtain(false, 0);
|
StopActivityItem emptyItem = StopActivityItem.obtain(0);
|
||||||
StopActivityItem item = StopActivityItem.obtain(true, 4);
|
StopActivityItem item = StopActivityItem.obtain(4);
|
||||||
assertNotSame(item, emptyItem);
|
assertNotSame(item, emptyItem);
|
||||||
assertFalse(item.equals(emptyItem));
|
assertFalse(item.equals(emptyItem));
|
||||||
|
|
||||||
item.recycle();
|
item.recycle();
|
||||||
assertEquals(item, emptyItem);
|
assertEquals(item, emptyItem);
|
||||||
|
|
||||||
StopActivityItem item2 = StopActivityItem.obtain(true, 3);
|
StopActivityItem item2 = StopActivityItem.obtain(3);
|
||||||
assertSame(item, item2);
|
|
||||||
assertFalse(item2.equals(emptyItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRecycleWindowVisibleItem() {
|
|
||||||
WindowVisibilityItem emptyItem = WindowVisibilityItem.obtain(false);
|
|
||||||
WindowVisibilityItem item = WindowVisibilityItem.obtain(true);
|
|
||||||
assertNotSame(item, emptyItem);
|
|
||||||
assertFalse(item.equals(emptyItem));
|
|
||||||
|
|
||||||
item.recycle();
|
|
||||||
assertEquals(item, emptyItem);
|
|
||||||
|
|
||||||
WindowVisibilityItem item2 = WindowVisibilityItem.obtain(true);
|
|
||||||
assertSame(item, item2);
|
assertSame(item, item2);
|
||||||
assertFalse(item2.equals(emptyItem));
|
assertFalse(item2.equals(emptyItem));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -179,31 +180,6 @@ public class TransactionParcelTests {
|
|||||||
assertTrue(item.equals(result));
|
assertTrue(item.equals(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWindowVisibilityChange() {
|
|
||||||
// Write to parcel
|
|
||||||
WindowVisibilityItem item = WindowVisibilityItem.obtain(true /* showWindow */);
|
|
||||||
writeAndPrepareForReading(item);
|
|
||||||
|
|
||||||
// Read from parcel and assert
|
|
||||||
WindowVisibilityItem result = WindowVisibilityItem.CREATOR.createFromParcel(mParcel);
|
|
||||||
|
|
||||||
assertEquals(item.hashCode(), result.hashCode());
|
|
||||||
assertTrue(item.equals(result));
|
|
||||||
|
|
||||||
// Check different value
|
|
||||||
item = WindowVisibilityItem.obtain(false);
|
|
||||||
|
|
||||||
mParcel = Parcel.obtain();
|
|
||||||
writeAndPrepareForReading(item);
|
|
||||||
|
|
||||||
// Read from parcel and assert
|
|
||||||
result = WindowVisibilityItem.CREATOR.createFromParcel(mParcel);
|
|
||||||
|
|
||||||
assertEquals(item.hashCode(), result.hashCode());
|
|
||||||
assertTrue(item.equals(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDestroy() {
|
public void testDestroy() {
|
||||||
DestroyActivityItem item = DestroyActivityItem.obtain(true /* finished */,
|
DestroyActivityItem item = DestroyActivityItem.obtain(true /* finished */,
|
||||||
@@ -299,8 +275,7 @@ public class TransactionParcelTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testStop() {
|
public void testStop() {
|
||||||
// Write to parcel
|
// Write to parcel
|
||||||
StopActivityItem item = StopActivityItem.obtain(true /* showWindow */,
|
StopActivityItem item = StopActivityItem.obtain(14 /* configChanges */);
|
||||||
14 /* configChanges */);
|
|
||||||
writeAndPrepareForReading(item);
|
writeAndPrepareForReading(item);
|
||||||
|
|
||||||
// Read from parcel and assert
|
// Read from parcel and assert
|
||||||
@@ -310,15 +285,27 @@ public class TransactionParcelTests {
|
|||||||
assertTrue(item.equals(result));
|
assertTrue(item.equals(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStart() {
|
||||||
|
// Write to parcel
|
||||||
|
StartActivityItem item = StartActivityItem.obtain();
|
||||||
|
writeAndPrepareForReading(item);
|
||||||
|
|
||||||
|
// Read from parcel and assert
|
||||||
|
StartActivityItem result = StartActivityItem.CREATOR.createFromParcel(mParcel);
|
||||||
|
|
||||||
|
assertEquals(item.hashCode(), result.hashCode());
|
||||||
|
assertEquals(item, result);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClientTransaction() {
|
public void testClientTransaction() {
|
||||||
// Write to parcel
|
// Write to parcel
|
||||||
WindowVisibilityItem callback1 = WindowVisibilityItem.obtain(true);
|
NewIntentItem callback1 = NewIntentItem.obtain(new ArrayList<>(), true);
|
||||||
ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
|
ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
|
||||||
config());
|
config());
|
||||||
|
|
||||||
StopActivityItem lifecycleRequest = StopActivityItem.obtain(true /* showWindow */,
|
StopActivityItem lifecycleRequest = StopActivityItem.obtain(78 /* configChanges */);
|
||||||
78 /* configChanges */);
|
|
||||||
|
|
||||||
IApplicationThread appThread = new StubAppThread();
|
IApplicationThread appThread = new StubAppThread();
|
||||||
Binder activityToken = new Binder();
|
Binder activityToken = new Binder();
|
||||||
@@ -340,7 +327,7 @@ public class TransactionParcelTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testClientTransactionCallbacksOnly() {
|
public void testClientTransactionCallbacksOnly() {
|
||||||
// Write to parcel
|
// Write to parcel
|
||||||
WindowVisibilityItem callback1 = WindowVisibilityItem.obtain(true);
|
NewIntentItem callback1 = NewIntentItem.obtain(new ArrayList<>(), true);
|
||||||
ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
|
ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
|
||||||
config());
|
config());
|
||||||
|
|
||||||
@@ -363,8 +350,7 @@ public class TransactionParcelTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testClientTransactionLifecycleOnly() {
|
public void testClientTransactionLifecycleOnly() {
|
||||||
// Write to parcel
|
// Write to parcel
|
||||||
StopActivityItem lifecycleRequest = StopActivityItem.obtain(true /* showWindow */,
|
StopActivityItem lifecycleRequest = StopActivityItem.obtain(78 /* configChanges */);
|
||||||
78 /* configChanges */);
|
|
||||||
|
|
||||||
IApplicationThread appThread = new StubAppThread();
|
IApplicationThread appThread = new StubAppThread();
|
||||||
Binder activityToken = new Binder();
|
Binder activityToken = new Binder();
|
||||||
|
|||||||
@@ -77,138 +77,6 @@ import org.mockito.quality.Strictness;
|
|||||||
@Presubmit
|
@Presubmit
|
||||||
public class ActivityThreadClientTest {
|
public class ActivityThreadClientTest {
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnCreate() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
clientSession.launchActivity(r);
|
|
||||||
assertEquals(ON_CREATE, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_CREATE, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_CREATE, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnCreate_Finished() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
Activity activity = clientSession.launchActivity(r);
|
|
||||||
activity.finish();
|
|
||||||
assertEquals(ON_CREATE, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_CREATE, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_CREATE, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnStart() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
clientSession.launchActivity(r);
|
|
||||||
clientSession.startActivity(r);
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_STOP, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnStart_Finished() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
Activity activity = clientSession.launchActivity(r);
|
|
||||||
clientSession.startActivity(r);
|
|
||||||
activity.finish();
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_STOP, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnResume() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
clientSession.launchActivity(r);
|
|
||||||
clientSession.startActivity(r);
|
|
||||||
clientSession.resumeActivity(r);
|
|
||||||
assertEquals(ON_RESUME, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_STOP, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnPause() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
clientSession.launchActivity(r);
|
|
||||||
clientSession.startActivity(r);
|
|
||||||
clientSession.resumeActivity(r);
|
|
||||||
clientSession.pauseActivity(r);
|
|
||||||
assertEquals(ON_PAUSE, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_STOP, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@UiThreadTest
|
|
||||||
public void testWindowVisibilityChange_OnStop() throws Exception {
|
|
||||||
try (ClientMockSession clientSession = new ClientMockSession()) {
|
|
||||||
ActivityClientRecord r = clientSession.stubActivityRecord();
|
|
||||||
|
|
||||||
clientSession.launchActivity(r);
|
|
||||||
clientSession.startActivity(r);
|
|
||||||
clientSession.resumeActivity(r);
|
|
||||||
clientSession.pauseActivity(r);
|
|
||||||
clientSession.stopActivity(r);
|
|
||||||
assertEquals(ON_STOP, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, true);
|
|
||||||
assertEquals(ON_START, r.getLifecycleState());
|
|
||||||
|
|
||||||
clientSession.changeVisibility(r, false);
|
|
||||||
assertEquals(ON_STOP, r.getLifecycleState());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
public void testLifecycleAfterFinished_OnCreate() throws Exception {
|
public void testLifecycleAfterFinished_OnCreate() throws Exception {
|
||||||
@@ -308,7 +176,7 @@ public class ActivityThreadClientTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startActivity(ActivityClientRecord r) {
|
private void startActivity(ActivityClientRecord r) {
|
||||||
mThread.handleStartActivity(r, null /* pendingActions */);
|
mThread.handleStartActivity(r.token, null /* pendingActions */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resumeActivity(ActivityClientRecord r) {
|
private void resumeActivity(ActivityClientRecord r) {
|
||||||
@@ -323,7 +191,7 @@ public class ActivityThreadClientTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void stopActivity(ActivityClientRecord r) {
|
private void stopActivity(ActivityClientRecord r) {
|
||||||
mThread.handleStopActivity(r.token, false /* show */, 0 /* configChanges */,
|
mThread.handleStopActivity(r.token, 0 /* configChanges */,
|
||||||
new PendingTransactionActions(), false /* finalStateRequest */, "test");
|
new PendingTransactionActions(), false /* finalStateRequest */, "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,10 +200,6 @@ public class ActivityThreadClientTest {
|
|||||||
false /* getNonConfigInstance */, "test");
|
false /* getNonConfigInstance */, "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeVisibility(ActivityClientRecord r, boolean show) {
|
|
||||||
mThread.handleWindowVisibility(r.token, show);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ActivityClientRecord stubActivityRecord() {
|
private ActivityClientRecord stubActivityRecord() {
|
||||||
ComponentName component = new ComponentName(
|
ComponentName component = new ComponentName(
|
||||||
InstrumentationRegistry.getInstrumentation().getContext(), TestActivity.class);
|
InstrumentationRegistry.getInstrumentation().getContext(), TestActivity.class);
|
||||||
|
|||||||
@@ -243,9 +243,9 @@ import android.app.servertransaction.NewIntentItem;
|
|||||||
import android.app.servertransaction.PauseActivityItem;
|
import android.app.servertransaction.PauseActivityItem;
|
||||||
import android.app.servertransaction.PipModeChangeItem;
|
import android.app.servertransaction.PipModeChangeItem;
|
||||||
import android.app.servertransaction.ResumeActivityItem;
|
import android.app.servertransaction.ResumeActivityItem;
|
||||||
|
import android.app.servertransaction.StartActivityItem;
|
||||||
import android.app.servertransaction.StopActivityItem;
|
import android.app.servertransaction.StopActivityItem;
|
||||||
import android.app.servertransaction.TopResumedActivityChangeItem;
|
import android.app.servertransaction.TopResumedActivityChangeItem;
|
||||||
import android.app.servertransaction.WindowVisibilityItem;
|
|
||||||
import android.app.usage.UsageEvents.Event;
|
import android.app.usage.UsageEvents.Event;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -4507,7 +4507,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
sleeping = false;
|
sleeping = false;
|
||||||
app.postPendingUiCleanMsg(true);
|
app.postPendingUiCleanMsg(true);
|
||||||
if (reportToClient) {
|
if (reportToClient) {
|
||||||
makeClientVisible();
|
mClientVisibilityDeferred = false;
|
||||||
|
makeActiveIfNeeded(starting);
|
||||||
} else {
|
} else {
|
||||||
mClientVisibilityDeferred = true;
|
mClientVisibilityDeferred = true;
|
||||||
}
|
}
|
||||||
@@ -4521,23 +4522,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
handleAlreadyVisible();
|
handleAlreadyVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send visibility change message to the client and pause if needed. */
|
|
||||||
void makeClientVisible() {
|
|
||||||
mClientVisibilityDeferred = false;
|
|
||||||
try {
|
|
||||||
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
|
||||||
WindowVisibilityItem.obtain(true /* showWindow */));
|
|
||||||
makeActiveIfNeeded(null /* activeActivity*/);
|
|
||||||
if (isState(STOPPING, STOPPED)) {
|
|
||||||
// Set state to STARTED in order to have consistent state with client while
|
|
||||||
// making an non-active activity visible from stopped.
|
|
||||||
setState(STARTED, "makeClientVisible");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeInvisible() {
|
void makeInvisible() {
|
||||||
if (!mVisibleRequested) {
|
if (!mVisibleRequested) {
|
||||||
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + this);
|
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + this);
|
||||||
@@ -4566,14 +4550,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
switch (getState()) {
|
switch (getState()) {
|
||||||
case STOPPING:
|
case STOPPING:
|
||||||
case STOPPED:
|
case STOPPED:
|
||||||
if (attachedToProcess()) {
|
|
||||||
if (DEBUG_VISIBILITY) {
|
|
||||||
Slog.v(TAG_VISIBILITY, "Scheduling invisibility: " + this);
|
|
||||||
}
|
|
||||||
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(),
|
|
||||||
appToken, WindowVisibilityItem.obtain(false /* showWindow */));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the flag indicating that an app can enter picture-in-picture once the
|
// Reset the flag indicating that an app can enter picture-in-picture once the
|
||||||
// activity is hidden
|
// activity is hidden
|
||||||
supportsEnterPipOnTaskSwitch = false;
|
supportsEnterPipOnTaskSwitch = false;
|
||||||
@@ -4605,17 +4581,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
|
boolean makeActiveIfNeeded(ActivityRecord activeActivity) {
|
||||||
if (shouldResumeActivity(activeActivity)) {
|
if (shouldResumeActivity(activeActivity)) {
|
||||||
if (DEBUG_VISIBILITY) {
|
if (DEBUG_VISIBILITY) {
|
||||||
Slog.v("TAG_VISIBILITY", "Resume visible activity, " + this);
|
Slog.v(TAG_VISIBILITY, "Resume visible activity, " + this);
|
||||||
}
|
}
|
||||||
return getActivityStack().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
|
return getActivityStack().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
|
||||||
null /* options */);
|
null /* options */);
|
||||||
} else if (shouldPauseActivity(activeActivity)) {
|
} else if (shouldPauseActivity(activeActivity)) {
|
||||||
if (DEBUG_VISIBILITY) {
|
if (DEBUG_VISIBILITY) {
|
||||||
Slog.v("TAG_VISIBILITY", "Pause visible activity, " + this);
|
Slog.v(TAG_VISIBILITY, "Pause visible activity, " + this);
|
||||||
}
|
}
|
||||||
// An activity must be in the {@link PAUSING} state for the system to validate
|
// An activity must be in the {@link PAUSING} state for the system to validate
|
||||||
// the move to {@link PAUSED}.
|
// the move to {@link PAUSED}.
|
||||||
setState(PAUSING, "makeVisibleIfNeeded");
|
setState(PAUSING, "makeActiveIfNeeded");
|
||||||
try {
|
try {
|
||||||
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
||||||
PauseActivityItem.obtain(finishing, false /* userLeaving */,
|
PauseActivityItem.obtain(finishing, false /* userLeaving */,
|
||||||
@@ -4623,6 +4599,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
|
Slog.w(TAG, "Exception thrown sending pause: " + intent.getComponent(), e);
|
||||||
}
|
}
|
||||||
|
} else if (shouldStartActivity()) {
|
||||||
|
if (DEBUG_VISIBILITY) {
|
||||||
|
Slog.v(TAG_VISIBILITY, "Start visible activity, " + this);
|
||||||
|
}
|
||||||
|
setState(STARTED, "makeActiveIfNeeded");
|
||||||
|
try {
|
||||||
|
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
||||||
|
StartActivityItem.obtain());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Slog.w(TAG, "Exception thrown sending start: " + intent.getComponent(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4665,6 +4652,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
&& canResumeByCompat();
|
&& canResumeByCompat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if activity should be moved to STARTED state.
|
||||||
|
* NOTE: This will not check if activity should be made paused or resumed first, so it must only
|
||||||
|
* be called after checking with {@link #shouldResumeActivity(ActivityRecord)}
|
||||||
|
* and {@link #shouldPauseActivity(ActivityRecord)}.
|
||||||
|
*/
|
||||||
|
private boolean shouldStartActivity() {
|
||||||
|
return mVisibleRequested && isState(STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if activity is eligible to be made active (resumed of paused). The activity:
|
* Check if activity is eligible to be made active (resumed of paused). The activity:
|
||||||
* - should be paused, stopped or stopping
|
* - should be paused, stopped or stopping
|
||||||
@@ -4901,16 +4898,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
}
|
}
|
||||||
setState(STOPPING, "stopIfPossible");
|
setState(STOPPING, "stopIfPossible");
|
||||||
if (DEBUG_VISIBILITY) {
|
if (DEBUG_VISIBILITY) {
|
||||||
Slog.v(TAG_VISIBILITY, "Stopping visibleRequested="
|
Slog.v(TAG_VISIBILITY, "Stopping:" + this);
|
||||||
+ mVisibleRequested + " for " + this);
|
|
||||||
}
|
|
||||||
if (!mVisibleRequested) {
|
|
||||||
setVisibility(false);
|
|
||||||
}
|
}
|
||||||
EventLogTags.writeWmStopActivity(
|
EventLogTags.writeWmStopActivity(
|
||||||
mUserId, System.identityHashCode(this), shortComponentName);
|
mUserId, System.identityHashCode(this), shortComponentName);
|
||||||
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
||||||
StopActivityItem.obtain(mVisibleRequested, configChangeFlags));
|
StopActivityItem.obtain(configChangeFlags));
|
||||||
|
|
||||||
if (stack.shouldSleepOrShutDownActivities()) {
|
if (stack.shouldSleepOrShutDownActivities()) {
|
||||||
setSleeping(true);
|
setSleeping(true);
|
||||||
}
|
}
|
||||||
@@ -7211,7 +7205,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
|||||||
// {@link ActivityTaskManagerService.activityStopped}).
|
// {@link ActivityTaskManagerService.activityStopped}).
|
||||||
try {
|
try {
|
||||||
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
|
||||||
StopActivityItem.obtain(false /* showWindow */, 0 /* configChanges */));
|
StopActivityItem.obtain(0 /* configChanges */));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "Exception thrown during restart " + this, e);
|
Slog.w(TAG, "Exception thrown during restart " + this, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,12 +79,13 @@ class EnsureActivitiesVisibleHelper {
|
|||||||
|
|
||||||
final PooledConsumer f = PooledLambda.obtainConsumer(
|
final PooledConsumer f = PooledLambda.obtainConsumer(
|
||||||
EnsureActivitiesVisibleHelper::setActivityVisibilityState, this,
|
EnsureActivitiesVisibleHelper::setActivityVisibilityState, this,
|
||||||
PooledLambda.__(ActivityRecord.class), resumeTopActivity);
|
PooledLambda.__(ActivityRecord.class), starting, resumeTopActivity);
|
||||||
mContiner.forAllActivities(f);
|
mContiner.forAllActivities(f);
|
||||||
f.recycle();
|
f.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setActivityVisibilityState(ActivityRecord r, final boolean resumeTopActivity) {
|
private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
|
||||||
|
final boolean resumeTopActivity) {
|
||||||
final boolean isTop = r == mTop;
|
final boolean isTop = r == mTop;
|
||||||
if (mAboveTop && !isTop) {
|
if (mAboveTop && !isTop) {
|
||||||
return;
|
return;
|
||||||
@@ -129,7 +130,8 @@ class EnsureActivitiesVisibleHelper {
|
|||||||
"Skipping: already visible at " + r);
|
"Skipping: already visible at " + r);
|
||||||
|
|
||||||
if (r.mClientVisibilityDeferred && mNotifyClients) {
|
if (r.mClientVisibilityDeferred && mNotifyClients) {
|
||||||
r.makeClientVisible();
|
r.makeActiveIfNeeded(r.mClientVisibilityDeferred ? null : starting);
|
||||||
|
r.mClientVisibilityDeferred = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
r.handleAlreadyVisible();
|
r.handleAlreadyVisible();
|
||||||
|
|||||||
@@ -521,11 +521,12 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShouldPauseWhenMakeClientVisible() {
|
public void testShouldStartWhenMakeClientActive() {
|
||||||
ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
|
ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
|
||||||
topActivity.setOccludesParent(false);
|
topActivity.setOccludesParent(false);
|
||||||
mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
|
mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
|
||||||
mActivity.makeClientVisible();
|
mActivity.setVisibility(true);
|
||||||
|
mActivity.makeActiveIfNeeded(null /* activeActivity */);
|
||||||
assertEquals(STARTED, mActivity.getState());
|
assertEquals(STARTED, mActivity.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user