Merge "Revert "Revert "Introduce ActivityTransactionItem and reduce null checks"""
This commit is contained in:
@@ -614,7 +614,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
throw new IllegalStateException(
|
||||
"Received config update for non-existing activity");
|
||||
}
|
||||
activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
|
||||
activity.mMainThread.handleActivityConfigurationChanged(this, overrideConfig,
|
||||
newDisplayId);
|
||||
};
|
||||
}
|
||||
@@ -3475,13 +3475,9 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) {
|
||||
final ActivityClientRecord r = mActivities.get(token);
|
||||
public void handleStartActivity(ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
final Activity activity = r.activity;
|
||||
if (r.activity == null) {
|
||||
// TODO(lifecycler): What do we do in this case?
|
||||
return;
|
||||
}
|
||||
if (!r.stopped) {
|
||||
throw new IllegalStateException("Can't start activity that is not stopped.");
|
||||
}
|
||||
@@ -3687,12 +3683,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
|
||||
final ActivityClientRecord r = mActivities.get(token);
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void handleNewIntent(ActivityClientRecord r, List<ReferrerIntent> intents) {
|
||||
checkAndBlockForNetworkAccess();
|
||||
deliverNewIntents(r, intents);
|
||||
}
|
||||
@@ -3881,13 +3872,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePictureInPictureRequested(IBinder token) {
|
||||
final ActivityClientRecord r = mActivities.get(token);
|
||||
if (r == null) {
|
||||
Log.w(TAG, "Activity to request PIP to no longer exists");
|
||||
return;
|
||||
}
|
||||
|
||||
public void handlePictureInPictureRequested(ActivityClientRecord r) {
|
||||
final boolean receivedByApp = r.activity.onPictureInPictureRequested();
|
||||
if (!receivedByApp) {
|
||||
// Previous recommendation was for apps to enter picture-in-picture in
|
||||
@@ -4417,22 +4402,21 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
|
||||
/**
|
||||
* Resume the activity.
|
||||
* @param token Target activity token.
|
||||
* @param r Target activity record.
|
||||
* @param finalStateRequest Flag indicating if this is part of final state resolution for a
|
||||
* transaction.
|
||||
* @param reason Reason for performing the action.
|
||||
*
|
||||
* @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
|
||||
* @return {@code true} that was resumed, {@code false} otherwise.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
|
||||
public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
|
||||
String reason) {
|
||||
final ActivityClientRecord r = mActivities.get(token);
|
||||
if (localLOGV) {
|
||||
Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
|
||||
}
|
||||
if (r == null || r.activity.mFinished) {
|
||||
return null;
|
||||
if (r.activity.mFinished) {
|
||||
return false;
|
||||
}
|
||||
if (r.getLifecycleState() == ON_RESUME) {
|
||||
if (!finalStateRequest) {
|
||||
@@ -4446,7 +4430,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
// handle two resume requests for the final state. For cases other than this
|
||||
// one, we don't expect it to happen.
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
if (finalStateRequest) {
|
||||
r.hideForNow = false;
|
||||
@@ -4477,7 +4461,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
return true;
|
||||
}
|
||||
|
||||
static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
|
||||
@@ -4498,20 +4482,19 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
|
||||
String reason) {
|
||||
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
|
||||
boolean isForward, String reason) {
|
||||
// If we are getting ready to gc after going to the background, well
|
||||
// we are back active so skip it.
|
||||
unscheduleGcIdler();
|
||||
mSomeActivitiesChanged = true;
|
||||
|
||||
// TODO Push resumeArgs into the activity for consideration
|
||||
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
|
||||
if (r == null) {
|
||||
// We didn't actually resume the activity, so skipping any follow-up actions.
|
||||
// skip below steps for double-resume and r.mFinish = true case.
|
||||
if (!performResumeActivity(r, finalStateRequest, reason)) {
|
||||
return;
|
||||
}
|
||||
if (mActivitiesToBeDestroyed.containsKey(token)) {
|
||||
if (mActivitiesToBeDestroyed.containsKey(r.token)) {
|
||||
// Although the activity is resumed, it is going to be destroyed. So the following
|
||||
// UI operations are unnecessary and also prevents exception because its token may
|
||||
// be gone that window manager cannot recognize it. All necessary cleanup actions
|
||||
@@ -4629,13 +4612,8 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) {
|
||||
ActivityClientRecord r = mActivities.get(token);
|
||||
if (r == null || r.activity == null) {
|
||||
Slog.w(TAG, "Not found target activity to report position change for token: " + token);
|
||||
return;
|
||||
}
|
||||
|
||||
public void handleTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
|
||||
String reason) {
|
||||
if (DEBUG_ORDER) {
|
||||
Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
|
||||
}
|
||||
@@ -4668,23 +4646,20 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
|
||||
public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
|
||||
int configChanges, PendingTransactionActions pendingActions, String reason) {
|
||||
ActivityClientRecord r = mActivities.get(token);
|
||||
if (r != null) {
|
||||
if (userLeaving) {
|
||||
performUserLeavingActivity(r);
|
||||
}
|
||||
|
||||
r.activity.mConfigChangeFlags |= configChanges;
|
||||
performPauseActivity(r, finished, reason, pendingActions);
|
||||
|
||||
// Make sure any pending writes are now committed.
|
||||
if (r.isPreHoneycomb()) {
|
||||
QueuedWork.waitToFinish();
|
||||
}
|
||||
mSomeActivitiesChanged = true;
|
||||
if (userLeaving) {
|
||||
performUserLeavingActivity(r);
|
||||
}
|
||||
|
||||
r.activity.mConfigChangeFlags |= configChanges;
|
||||
performPauseActivity(r, finished, reason, pendingActions);
|
||||
|
||||
// Make sure any pending writes are now committed.
|
||||
if (r.isPreHoneycomb()) {
|
||||
QueuedWork.waitToFinish();
|
||||
}
|
||||
mSomeActivitiesChanged = true;
|
||||
}
|
||||
|
||||
final void performUserLeavingActivity(ActivityClientRecord r) {
|
||||
@@ -4781,8 +4756,11 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
r.setState(ON_PAUSE);
|
||||
}
|
||||
|
||||
// TODO(b/127877792): Make LocalActivityManager call performStopActivityInner. We cannot remove
|
||||
// this since it's a high usage hidden API.
|
||||
/** Called from {@link LocalActivityManager}. */
|
||||
@UnsupportedAppUsage
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 127877792,
|
||||
publicAlternatives = "{@code N/A}")
|
||||
final void performStopActivity(IBinder token, boolean saveState, String reason) {
|
||||
ActivityClientRecord r = mActivities.get(token);
|
||||
performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */,
|
||||
@@ -4823,44 +4801,42 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
|
||||
boolean saveState, boolean finalStateRequest, String reason) {
|
||||
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
|
||||
if (r != null) {
|
||||
if (r.stopped) {
|
||||
if (r.activity.mFinished) {
|
||||
// If we are finishing, we won't call onResume() in certain
|
||||
// cases. So here we likewise don't want to call onStop()
|
||||
// if the activity isn't resumed.
|
||||
return;
|
||||
}
|
||||
if (!finalStateRequest) {
|
||||
final RuntimeException e = new RuntimeException(
|
||||
"Performing stop of activity that is already stopped: "
|
||||
+ r.intent.getComponent().toShortString());
|
||||
Slog.e(TAG, e.getMessage(), e);
|
||||
Slog.e(TAG, r.getStateString());
|
||||
}
|
||||
if (r.stopped) {
|
||||
if (r.activity.mFinished) {
|
||||
// If we are finishing, we won't call onResume() in certain
|
||||
// cases. So here we likewise don't want to call onStop()
|
||||
// if the activity isn't resumed.
|
||||
return;
|
||||
}
|
||||
|
||||
// One must first be paused before stopped...
|
||||
performPauseActivityIfNeeded(r, reason);
|
||||
|
||||
if (info != null) {
|
||||
try {
|
||||
// First create a thumbnail for the activity...
|
||||
// For now, don't create the thumbnail here; we are
|
||||
// doing that by doing a screen snapshot.
|
||||
info.setDescription(r.activity.onCreateDescription());
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException(
|
||||
"Unable to save state of activity "
|
||||
+ r.intent.getComponent().toShortString()
|
||||
+ ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
if (!finalStateRequest) {
|
||||
final RuntimeException e = new RuntimeException(
|
||||
"Performing stop of activity that is already stopped: "
|
||||
+ r.intent.getComponent().toShortString());
|
||||
Slog.e(TAG, e.getMessage(), e);
|
||||
Slog.e(TAG, r.getStateString());
|
||||
}
|
||||
|
||||
callActivityOnStop(r, saveState, reason);
|
||||
}
|
||||
|
||||
// One must first be paused before stopped...
|
||||
performPauseActivityIfNeeded(r, reason);
|
||||
|
||||
if (info != null) {
|
||||
try {
|
||||
// First create a thumbnail for the activity...
|
||||
// For now, don't create the thumbnail here; we are
|
||||
// doing that by doing a screen snapshot.
|
||||
info.setDescription(r.activity.onCreateDescription());
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException(
|
||||
"Unable to save state of activity "
|
||||
+ r.intent.getComponent().toShortString()
|
||||
+ ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callActivityOnStop(r, saveState, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4927,9 +4903,8 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStopActivity(IBinder token, int configChanges,
|
||||
public void handleStopActivity(ActivityClientRecord r, int configChanges,
|
||||
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
|
||||
final ActivityClientRecord r = mActivities.get(token);
|
||||
r.activity.mConfigChangeFlags |= configChanges;
|
||||
|
||||
final StopInfo stopInfo = new StopInfo();
|
||||
@@ -4965,8 +4940,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRestartActivity(IBinder token, boolean start) {
|
||||
ActivityClientRecord r = mActivities.get(token);
|
||||
public void performRestartActivity(ActivityClientRecord r, boolean start) {
|
||||
if (r.stopped) {
|
||||
r.activity.performRestart(start, "performRestartActivity");
|
||||
if (start) {
|
||||
@@ -5053,110 +5027,98 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
|
||||
ActivityClientRecord r = mActivities.get(token);
|
||||
public void handleSendResult(ActivityClientRecord r, List<ResultInfo> results, String reason) {
|
||||
if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
|
||||
if (r != null) {
|
||||
final boolean resumed = !r.paused;
|
||||
if (!r.activity.mFinished && r.activity.mDecor != null
|
||||
&& r.hideForNow && resumed) {
|
||||
// We had hidden the activity because it started another
|
||||
// one... we have gotten a result back and we are not
|
||||
// paused, so make sure our window is visible.
|
||||
updateVisibility(r, true);
|
||||
}
|
||||
if (resumed) {
|
||||
try {
|
||||
// Now we are idle.
|
||||
r.activity.mCalled = false;
|
||||
mInstrumentation.callActivityOnPause(r.activity);
|
||||
if (!r.activity.mCalled) {
|
||||
throw new SuperNotCalledException(
|
||||
"Activity " + r.intent.getComponent().toShortString()
|
||||
+ " did not call through to super.onPause()");
|
||||
}
|
||||
} catch (SuperNotCalledException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException(
|
||||
"Unable to pause activity "
|
||||
+ r.intent.getComponent().toShortString()
|
||||
+ ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkAndBlockForNetworkAccess();
|
||||
deliverResults(r, results, reason);
|
||||
if (resumed) {
|
||||
r.activity.performResume(false, reason);
|
||||
}
|
||||
final boolean resumed = !r.paused;
|
||||
if (!r.activity.mFinished && r.activity.mDecor != null
|
||||
&& r.hideForNow && resumed) {
|
||||
// We had hidden the activity because it started another
|
||||
// one... we have gotten a result back and we are not
|
||||
// paused, so make sure our window is visible.
|
||||
updateVisibility(r, true);
|
||||
}
|
||||
}
|
||||
|
||||
/** Core implementation of activity destroy call. */
|
||||
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
|
||||
int configChanges, boolean getNonConfigInstance, String reason) {
|
||||
ActivityClientRecord r = mActivities.get(token);
|
||||
Class<? extends Activity> activityClass = null;
|
||||
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
|
||||
if (r != null) {
|
||||
activityClass = r.activity.getClass();
|
||||
r.activity.mConfigChangeFlags |= configChanges;
|
||||
if (finishing) {
|
||||
r.activity.mFinished = true;
|
||||
}
|
||||
|
||||
performPauseActivityIfNeeded(r, "destroy");
|
||||
|
||||
if (!r.stopped) {
|
||||
callActivityOnStop(r, false /* saveState */, "destroy");
|
||||
}
|
||||
if (getNonConfigInstance) {
|
||||
try {
|
||||
r.lastNonConfigurationInstances
|
||||
= r.activity.retainNonConfigurationInstances();
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException(
|
||||
"Unable to retain activity "
|
||||
+ r.intent.getComponent().toShortString()
|
||||
+ ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resumed) {
|
||||
try {
|
||||
// Now we are idle.
|
||||
r.activity.mCalled = false;
|
||||
mInstrumentation.callActivityOnDestroy(r.activity);
|
||||
mInstrumentation.callActivityOnPause(r.activity);
|
||||
if (!r.activity.mCalled) {
|
||||
throw new SuperNotCalledException(
|
||||
"Activity " + safeToComponentShortString(r.intent) +
|
||||
" did not call through to super.onDestroy()");
|
||||
}
|
||||
if (r.window != null) {
|
||||
r.window.closeAllPanels();
|
||||
"Activity " + r.intent.getComponent().toShortString()
|
||||
+ " did not call through to super.onPause()");
|
||||
}
|
||||
} catch (SuperNotCalledException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException(
|
||||
"Unable to destroy activity " + safeToComponentShortString(r.intent)
|
||||
"Unable to pause activity "
|
||||
+ r.intent.getComponent().toShortString()
|
||||
+ ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
r.setState(ON_DESTROY);
|
||||
mLastReportedWindowingMode.remove(r.activity.getActivityToken());
|
||||
}
|
||||
checkAndBlockForNetworkAccess();
|
||||
deliverResults(r, results, reason);
|
||||
if (resumed) {
|
||||
r.activity.performResume(false, reason);
|
||||
}
|
||||
}
|
||||
|
||||
/** Core implementation of activity destroy call. */
|
||||
void performDestroyActivity(ActivityClientRecord r, boolean finishing,
|
||||
int configChanges, boolean getNonConfigInstance, String reason) {
|
||||
Class<? extends Activity> activityClass = null;
|
||||
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
|
||||
activityClass = r.activity.getClass();
|
||||
r.activity.mConfigChangeFlags |= configChanges;
|
||||
if (finishing) {
|
||||
r.activity.mFinished = true;
|
||||
}
|
||||
|
||||
performPauseActivityIfNeeded(r, "destroy");
|
||||
|
||||
if (!r.stopped) {
|
||||
callActivityOnStop(r, false /* saveState */, "destroy");
|
||||
}
|
||||
if (getNonConfigInstance) {
|
||||
try {
|
||||
r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException("Unable to retain activity "
|
||||
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
r.activity.mCalled = false;
|
||||
mInstrumentation.callActivityOnDestroy(r.activity);
|
||||
if (!r.activity.mCalled) {
|
||||
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
|
||||
+ " did not call through to super.onDestroy()");
|
||||
}
|
||||
if (r.window != null) {
|
||||
r.window.closeAllPanels();
|
||||
}
|
||||
} catch (SuperNotCalledException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
if (!mInstrumentation.onException(r.activity, e)) {
|
||||
throw new RuntimeException("Unable to destroy activity "
|
||||
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
r.setState(ON_DESTROY);
|
||||
mLastReportedWindowingMode.remove(r.activity.getActivityToken());
|
||||
schedulePurgeIdler();
|
||||
// updatePendingActivityConfiguration() reads from mActivities to update
|
||||
// ActivityClientRecord which runs in a different thread. Protect modifications to
|
||||
// mActivities to avoid race.
|
||||
synchronized (mResourcesManager) {
|
||||
mActivities.remove(token);
|
||||
mActivities.remove(r.token);
|
||||
}
|
||||
StrictMode.decrementExpectedActivityCount(activityClass);
|
||||
return r;
|
||||
}
|
||||
|
||||
private static String safeToComponentShortString(Intent intent) {
|
||||
@@ -5170,70 +5132,65 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
|
||||
public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
|
||||
boolean getNonConfigInstance, String reason) {
|
||||
ActivityClientRecord r = performDestroyActivity(token, finishing,
|
||||
configChanges, getNonConfigInstance, reason);
|
||||
if (r != null) {
|
||||
cleanUpPendingRemoveWindows(r, finishing);
|
||||
WindowManager wm = r.activity.getWindowManager();
|
||||
View v = r.activity.mDecor;
|
||||
if (v != null) {
|
||||
if (r.activity.mVisibleFromServer) {
|
||||
mNumVisibleActivities--;
|
||||
}
|
||||
IBinder wtoken = v.getWindowToken();
|
||||
if (r.activity.mWindowAdded) {
|
||||
if (r.mPreserveWindow) {
|
||||
// Hold off on removing this until the new activity's
|
||||
// window is being added.
|
||||
r.mPendingRemoveWindow = r.window;
|
||||
r.mPendingRemoveWindowManager = wm;
|
||||
// We can only keep the part of the view hierarchy that we control,
|
||||
// everything else must be removed, because it might not be able to
|
||||
// behave properly when activity is relaunching.
|
||||
r.window.clearContentView();
|
||||
} else {
|
||||
wm.removeViewImmediate(v);
|
||||
}
|
||||
}
|
||||
if (wtoken != null && r.mPendingRemoveWindow == null) {
|
||||
WindowManagerGlobal.getInstance().closeAll(wtoken,
|
||||
r.activity.getClass().getName(), "Activity");
|
||||
} else if (r.mPendingRemoveWindow != null) {
|
||||
// We're preserving only one window, others should be closed so app views
|
||||
// will be detached before the final tear down. It should be done now because
|
||||
// some components (e.g. WebView) rely on detach callbacks to perform receiver
|
||||
// unregister and other cleanup.
|
||||
WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
|
||||
r.activity.getClass().getName(), "Activity");
|
||||
}
|
||||
r.activity.mDecor = null;
|
||||
performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
|
||||
cleanUpPendingRemoveWindows(r, finishing);
|
||||
WindowManager wm = r.activity.getWindowManager();
|
||||
View v = r.activity.mDecor;
|
||||
if (v != null) {
|
||||
if (r.activity.mVisibleFromServer) {
|
||||
mNumVisibleActivities--;
|
||||
}
|
||||
if (r.mPendingRemoveWindow == null) {
|
||||
// If we are delaying the removal of the activity window, then
|
||||
// we can't clean up all windows here. Note that we can't do
|
||||
// so later either, which means any windows that aren't closed
|
||||
// by the app will leak. Well we try to warning them a lot
|
||||
// about leaking windows, because that is a bug, so if they are
|
||||
// using this recreate facility then they get to live with leaks.
|
||||
WindowManagerGlobal.getInstance().closeAll(token,
|
||||
IBinder wtoken = v.getWindowToken();
|
||||
if (r.activity.mWindowAdded) {
|
||||
if (r.mPreserveWindow) {
|
||||
// Hold off on removing this until the new activity's window is being added.
|
||||
r.mPendingRemoveWindow = r.window;
|
||||
r.mPendingRemoveWindowManager = wm;
|
||||
// We can only keep the part of the view hierarchy that we control,
|
||||
// everything else must be removed, because it might not be able to
|
||||
// behave properly when activity is relaunching.
|
||||
r.window.clearContentView();
|
||||
} else {
|
||||
wm.removeViewImmediate(v);
|
||||
}
|
||||
}
|
||||
if (wtoken != null && r.mPendingRemoveWindow == null) {
|
||||
WindowManagerGlobal.getInstance().closeAll(wtoken,
|
||||
r.activity.getClass().getName(), "Activity");
|
||||
} else if (r.mPendingRemoveWindow != null) {
|
||||
// We're preserving only one window, others should be closed so app views
|
||||
// will be detached before the final tear down. It should be done now because
|
||||
// some components (e.g. WebView) rely on detach callbacks to perform receiver
|
||||
// unregister and other cleanup.
|
||||
WindowManagerGlobal.getInstance().closeAllExceptView(r.token, v,
|
||||
r.activity.getClass().getName(), "Activity");
|
||||
}
|
||||
r.activity.mDecor = null;
|
||||
}
|
||||
if (r.mPendingRemoveWindow == null) {
|
||||
// If we are delaying the removal of the activity window, then
|
||||
// we can't clean up all windows here. Note that we can't do
|
||||
// so later either, which means any windows that aren't closed
|
||||
// by the app will leak. Well we try to warning them a lot
|
||||
// about leaking windows, because that is a bug, so if they are
|
||||
// using this recreate facility then they get to live with leaks.
|
||||
WindowManagerGlobal.getInstance().closeAll(r.token,
|
||||
r.activity.getClass().getName(), "Activity");
|
||||
}
|
||||
|
||||
// Mocked out contexts won't be participating in the normal
|
||||
// process lifecycle, but if we're running with a proper
|
||||
// ApplicationContext we need to have it tear down things
|
||||
// cleanly.
|
||||
Context c = r.activity.getBaseContext();
|
||||
if (c instanceof ContextImpl) {
|
||||
((ContextImpl) c).scheduleFinalCleanup(
|
||||
r.activity.getClass().getName(), "Activity");
|
||||
}
|
||||
// Mocked out contexts won't be participating in the normal
|
||||
// process lifecycle, but if we're running with a proper
|
||||
// ApplicationContext we need to have it tear down things
|
||||
// cleanly.
|
||||
Context c = r.activity.getBaseContext();
|
||||
if (c instanceof ContextImpl) {
|
||||
((ContextImpl) c).scheduleFinalCleanup(r.activity.getClass().getName(), "Activity");
|
||||
}
|
||||
if (finishing) {
|
||||
try {
|
||||
ActivityTaskManager.getService().activityDestroyed(token);
|
||||
ActivityTaskManager.getService().activityDestroyed(r.token);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -5455,7 +5412,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
callActivityOnStop(r, true /* saveState */, reason);
|
||||
}
|
||||
|
||||
handleDestroyActivity(r.token, false, configChanges, true, reason);
|
||||
handleDestroyActivity(r, false, configChanges, true, reason);
|
||||
|
||||
r.activity = null;
|
||||
r.window = null;
|
||||
@@ -5483,12 +5440,10 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) {
|
||||
public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) {
|
||||
try {
|
||||
ActivityTaskManager.getService().activityRelaunched(token);
|
||||
final ActivityClientRecord r = mActivities.get(token);
|
||||
if (pendingActions.shouldReportRelaunchToWindowManager() && r != null
|
||||
&& r.window != null) {
|
||||
ActivityTaskManager.getService().activityRelaunched(r.token);
|
||||
if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
|
||||
r.window.reportActivityRelaunched();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -5647,13 +5602,7 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
*/
|
||||
private Configuration performActivityConfigurationChanged(Activity activity,
|
||||
Configuration newConfig, Configuration amOverrideConfig, int displayId) {
|
||||
if (activity == null) {
|
||||
throw new IllegalArgumentException("No activity provided.");
|
||||
}
|
||||
final IBinder activityToken = activity.getActivityToken();
|
||||
if (activityToken == null) {
|
||||
throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
|
||||
}
|
||||
|
||||
// WindowConfiguration differences aren't considered as public, check it separately.
|
||||
// multi-window / pip mode changes, if any, should be sent before the configuration
|
||||
@@ -5952,20 +5901,8 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
* processing any configurations older than {@code overrideConfig}.
|
||||
*/
|
||||
@Override
|
||||
public void updatePendingActivityConfiguration(IBinder activityToken,
|
||||
public void updatePendingActivityConfiguration(ActivityClientRecord r,
|
||||
Configuration overrideConfig) {
|
||||
final ActivityClientRecord r;
|
||||
synchronized (mResourcesManager) {
|
||||
r = mActivities.get(activityToken);
|
||||
}
|
||||
|
||||
if (r == null) {
|
||||
if (DEBUG_CONFIGURATION) {
|
||||
Slog.w(TAG, "Not found target activity to update its pending config.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (r) {
|
||||
if (r.mPendingOverrideConfig != null
|
||||
&& !r.mPendingOverrideConfig.isOtherSeqNewer(overrideConfig)) {
|
||||
@@ -5985,21 +5922,14 @@ public final class ActivityThread extends ClientTransactionHandler {
|
||||
* if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with
|
||||
* a newer config than {@code overrideConfig}.
|
||||
*
|
||||
* @param activityToken Target activity token.
|
||||
* @param r Target activity record.
|
||||
* @param overrideConfig Activity override config.
|
||||
* @param displayId Id of the display where activity was moved to, -1 if there was no move and
|
||||
* value didn't change.
|
||||
*/
|
||||
@Override
|
||||
public void handleActivityConfigurationChanged(IBinder activityToken,
|
||||
public void handleActivityConfigurationChanged(ActivityClientRecord r,
|
||||
@NonNull Configuration overrideConfig, int displayId) {
|
||||
ActivityClientRecord r = mActivities.get(activityToken);
|
||||
// Check input params.
|
||||
if (r == null || r.activity == null) {
|
||||
if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (r) {
|
||||
if (overrideConfig.isOtherSeqNewer(r.mPendingOverrideConfig)) {
|
||||
if (DEBUG_CONFIGURATION) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package android.app;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.servertransaction.ClientTransaction;
|
||||
import android.app.servertransaction.ClientTransactionItem;
|
||||
import android.app.servertransaction.PendingTransactionActions;
|
||||
@@ -89,37 +91,38 @@ public abstract class ClientTransactionHandler {
|
||||
public abstract Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed();
|
||||
|
||||
/** Destroy the activity. */
|
||||
public abstract void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
|
||||
boolean getNonConfigInstance, String reason);
|
||||
public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
|
||||
int configChanges, boolean getNonConfigInstance, String reason);
|
||||
|
||||
/** Pause the activity. */
|
||||
public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
|
||||
int configChanges, PendingTransactionActions pendingActions, String reason);
|
||||
public abstract void handlePauseActivity(@NonNull ActivityClientRecord r, boolean finished,
|
||||
boolean userLeaving, int configChanges, PendingTransactionActions pendingActions,
|
||||
String reason);
|
||||
|
||||
/**
|
||||
* Resume the activity.
|
||||
* @param token Target activity token.
|
||||
* @param r Target activity record.
|
||||
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
|
||||
* request for a transaction.
|
||||
* @param isForward Flag indicating if next transition is forward.
|
||||
* @param reason Reason for performing this operation.
|
||||
*/
|
||||
public abstract void handleResumeActivity(IBinder token, boolean finalStateRequest,
|
||||
boolean isForward, String reason);
|
||||
public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
|
||||
boolean finalStateRequest, boolean isForward, String reason);
|
||||
|
||||
/**
|
||||
* Notify the activity about top resumed state change.
|
||||
* @param token Target activity token.
|
||||
* @param r Target activity record.
|
||||
* @param isTopResumedActivity Current state of the activity, {@code true} if it's the
|
||||
* topmost resumed activity in the system, {@code false} otherwise.
|
||||
* @param reason Reason for performing this operation.
|
||||
*/
|
||||
public abstract void handleTopResumedActivityChanged(IBinder token,
|
||||
public abstract void handleTopResumedActivityChanged(@NonNull ActivityClientRecord r,
|
||||
boolean isTopResumedActivity, String reason);
|
||||
|
||||
/**
|
||||
* Stop the activity.
|
||||
* @param token Target activity token.
|
||||
* @param r Target activity record.
|
||||
* @param configChanges Activity configuration changes.
|
||||
* @param pendingActions Pending actions to be used on this or later stages of activity
|
||||
* transaction.
|
||||
@@ -127,38 +130,40 @@ public abstract class ClientTransactionHandler {
|
||||
* request for a transaction.
|
||||
* @param reason Reason for performing this operation.
|
||||
*/
|
||||
public abstract void handleStopActivity(IBinder token, int configChanges,
|
||||
public abstract void handleStopActivity(@NonNull ActivityClientRecord r, int configChanges,
|
||||
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
|
||||
|
||||
/** Report that activity was stopped to server. */
|
||||
public abstract void reportStop(PendingTransactionActions pendingActions);
|
||||
|
||||
/** Restart the activity after it was stopped. */
|
||||
public abstract void performRestartActivity(IBinder token, boolean start);
|
||||
public abstract void performRestartActivity(@NonNull ActivityClientRecord r, boolean start);
|
||||
|
||||
/** Set pending activity configuration in case it will be updated by other transaction item. */
|
||||
public abstract void updatePendingActivityConfiguration(IBinder activityToken,
|
||||
public abstract void updatePendingActivityConfiguration(@NonNull ActivityClientRecord r,
|
||||
Configuration overrideConfig);
|
||||
|
||||
/** Deliver activity (override) configuration change. */
|
||||
public abstract void handleActivityConfigurationChanged(IBinder activityToken,
|
||||
public abstract void handleActivityConfigurationChanged(@NonNull ActivityClientRecord r,
|
||||
Configuration overrideConfig, int displayId);
|
||||
|
||||
/** Deliver result from another activity. */
|
||||
public abstract void handleSendResult(IBinder token, List<ResultInfo> results, String reason);
|
||||
public abstract void handleSendResult(
|
||||
@NonNull ActivityClientRecord r, List<ResultInfo> results, String reason);
|
||||
|
||||
/** Deliver new intent. */
|
||||
public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents);
|
||||
public abstract void handleNewIntent(
|
||||
@NonNull ActivityClientRecord r, List<ReferrerIntent> intents);
|
||||
|
||||
/** Request that an activity enter picture-in-picture. */
|
||||
public abstract void handlePictureInPictureRequested(IBinder token);
|
||||
public abstract void handlePictureInPictureRequested(@NonNull ActivityClientRecord r);
|
||||
|
||||
/** Perform activity launch. */
|
||||
public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
|
||||
public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions, Intent customIntent);
|
||||
|
||||
/** Perform activity start. */
|
||||
public abstract void handleStartActivity(IBinder token,
|
||||
public abstract void handleStartActivity(@NonNull ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions);
|
||||
|
||||
/** Get package info. */
|
||||
@@ -176,7 +181,7 @@ public abstract class ClientTransactionHandler {
|
||||
* Get {@link android.app.ActivityThread.ActivityClientRecord} instance that corresponds to the
|
||||
* provided token.
|
||||
*/
|
||||
public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token);
|
||||
public abstract ActivityClientRecord getActivityClient(IBinder token);
|
||||
|
||||
/**
|
||||
* Prepare activity relaunch to update internal bookkeeping. This is used to track multiple
|
||||
@@ -191,7 +196,7 @@ public abstract class ClientTransactionHandler {
|
||||
* @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during
|
||||
* relaunch, or {@code null} if relaunch cancelled.
|
||||
*/
|
||||
public abstract ActivityThread.ActivityClientRecord prepareRelaunchActivity(IBinder token,
|
||||
public abstract ActivityClientRecord prepareRelaunchActivity(IBinder token,
|
||||
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
|
||||
int configChanges, MergedConfiguration config, boolean preserveWindow);
|
||||
|
||||
@@ -200,14 +205,15 @@ public abstract class ClientTransactionHandler {
|
||||
* @param r Activity client record prepared for relaunch.
|
||||
* @param pendingActions Pending actions to be used on later stages of activity transaction.
|
||||
* */
|
||||
public abstract void handleRelaunchActivity(ActivityThread.ActivityClientRecord r,
|
||||
public abstract void handleRelaunchActivity(@NonNull ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions);
|
||||
|
||||
/**
|
||||
* Report that relaunch request was handled.
|
||||
* @param token Target activity token.
|
||||
* @param r Target activity record.
|
||||
* @param pendingActions Pending actions initialized on earlier stages of activity transaction.
|
||||
* Used to check if we should report relaunch to WM.
|
||||
* */
|
||||
public abstract void reportRelaunch(IBinder token, PendingTransactionActions pendingActions);
|
||||
public abstract void reportRelaunch(@NonNull ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public class LocalActivityManager {
|
||||
private static final String TAG = "LocalActivityManager";
|
||||
private static final boolean localLOGV = false;
|
||||
|
||||
// TODO(b/127877792): try to remove this and use {@code ActivityClientRecord} instead.
|
||||
// Internal token for an Activity being managed by LocalActivityManager.
|
||||
private static class LocalActivityRecord extends Binder {
|
||||
LocalActivityRecord(String _id, Intent _intent) {
|
||||
@@ -136,7 +137,7 @@ public class LocalActivityManager {
|
||||
// startActivity() has not yet been called, so nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (r.curState == INITIALIZING) {
|
||||
// Get the lastNonConfigurationInstance for the activity
|
||||
HashMap<String, Object> lastNonConfigurationInstances =
|
||||
@@ -177,12 +178,13 @@ public class LocalActivityManager {
|
||||
pendingActions = null;
|
||||
}
|
||||
|
||||
mActivityThread.handleStartActivity(r, pendingActions);
|
||||
mActivityThread.handleStartActivity(clientRecord, pendingActions);
|
||||
r.curState = STARTED;
|
||||
|
||||
if (desiredState == RESUMED) {
|
||||
if (localLOGV) Log.v(TAG, r.id + ": resuming");
|
||||
mActivityThread.performResumeActivity(r, true, "moveToState-INITIALIZING");
|
||||
mActivityThread.performResumeActivity(clientRecord, true,
|
||||
"moveToState-INITIALIZING");
|
||||
r.curState = RESUMED;
|
||||
}
|
||||
|
||||
@@ -194,18 +196,25 @@ public class LocalActivityManager {
|
||||
// group's state catches up.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
|
||||
if (clientRecord == null) {
|
||||
Log.w(TAG, "Can't get activity record for " + r.id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (r.curState) {
|
||||
case CREATED:
|
||||
if (desiredState == STARTED) {
|
||||
if (localLOGV) Log.v(TAG, r.id + ": restarting");
|
||||
mActivityThread.performRestartActivity(r, true /* start */);
|
||||
mActivityThread.performRestartActivity(clientRecord, true /* start */);
|
||||
r.curState = STARTED;
|
||||
}
|
||||
if (desiredState == RESUMED) {
|
||||
if (localLOGV) Log.v(TAG, r.id + ": restarting and resuming");
|
||||
mActivityThread.performRestartActivity(r, true /* start */);
|
||||
mActivityThread.performResumeActivity(r, true, "moveToState-CREATED");
|
||||
mActivityThread.performRestartActivity(clientRecord, true /* start */);
|
||||
mActivityThread.performResumeActivity(clientRecord, true,
|
||||
"moveToState-CREATED");
|
||||
r.curState = RESUMED;
|
||||
}
|
||||
return;
|
||||
@@ -214,7 +223,8 @@ public class LocalActivityManager {
|
||||
if (desiredState == RESUMED) {
|
||||
// Need to resume it...
|
||||
if (localLOGV) Log.v(TAG, r.id + ": resuming");
|
||||
mActivityThread.performResumeActivity(r, true, "moveToState-STARTED");
|
||||
mActivityThread.performResumeActivity(clientRecord, true,
|
||||
"moveToState-STARTED");
|
||||
r.instanceState = null;
|
||||
r.curState = RESUMED;
|
||||
}
|
||||
@@ -352,7 +362,8 @@ public class LocalActivityManager {
|
||||
ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
|
||||
intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
|
||||
if (localLOGV) Log.v(TAG, r.id + ": new intent");
|
||||
mActivityThread.handleNewIntent(r, intents);
|
||||
final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
|
||||
mActivityThread.handleNewIntent(clientRecord, intents);
|
||||
r.intent = intent;
|
||||
moveToState(r, mCurState);
|
||||
if (mSingleMode) {
|
||||
@@ -399,8 +410,11 @@ public class LocalActivityManager {
|
||||
performPause(r, finish);
|
||||
}
|
||||
if (localLOGV) Log.v(TAG, r.id + ": destroying");
|
||||
mActivityThread.performDestroyActivity(r, finish, 0 /* configChanges */,
|
||||
false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
|
||||
final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
|
||||
if (clientRecord != null) {
|
||||
mActivityThread.performDestroyActivity(clientRecord, finish, 0 /* configChanges */,
|
||||
false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
|
||||
}
|
||||
r.activity = null;
|
||||
r.window = null;
|
||||
if (finish) {
|
||||
@@ -664,7 +678,12 @@ public class LocalActivityManager {
|
||||
for (int i=0; i<N; i++) {
|
||||
LocalActivityRecord r = mActivityArray.get(i);
|
||||
if (localLOGV) Log.v(TAG, r.id + ": destroying");
|
||||
mActivityThread.performDestroyActivity(r, finishing, 0 /* configChanges */,
|
||||
final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
|
||||
if (clientRecord == null) {
|
||||
if (localLOGV) Log.v(TAG, r.id + ": no corresponding record");
|
||||
continue;
|
||||
}
|
||||
mActivityThread.performDestroyActivity(clientRecord, finishing, 0 /* configChanges */,
|
||||
false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
|
||||
}
|
||||
mActivities.clear();
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.IBinder;
|
||||
@@ -32,23 +33,24 @@ import java.util.Objects;
|
||||
* Activity configuration changed callback.
|
||||
* @hide
|
||||
*/
|
||||
public class ActivityConfigurationChangeItem extends ClientTransactionItem {
|
||||
public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
|
||||
|
||||
private Configuration mConfiguration;
|
||||
|
||||
@Override
|
||||
public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
|
||||
final ActivityClientRecord r = getActivityClientRecord(client, token);
|
||||
// Notify the client of an upcoming change in the token configuration. This ensures that
|
||||
// batches of config change items only process the newest configuration.
|
||||
client.updatePendingActivityConfiguration(token, mConfiguration);
|
||||
client.updatePendingActivityConfiguration(r, mConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
// TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
|
||||
client.handleActivityConfigurationChanged(token, mConfiguration, INVALID_DISPLAY);
|
||||
client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -93,7 +95,7 @@ public class ActivityConfigurationChangeItem extends ClientTransactionItem {
|
||||
mConfiguration = in.readTypedObject(Configuration.CREATOR);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
|
||||
public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
|
||||
new Creator<ActivityConfigurationChangeItem>() {
|
||||
public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
|
||||
return new ActivityConfigurationChangeItem(in);
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* Request for lifecycle state that an activity should reach.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class ActivityLifecycleItem extends ClientTransactionItem {
|
||||
public abstract class ActivityLifecycleItem extends ActivityTransactionItem {
|
||||
|
||||
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
|
||||
UNDEFINED,
|
||||
|
||||
@@ -18,7 +18,8 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.app.ActivityThread.DEBUG_ORDER;
|
||||
|
||||
import android.app.ActivityThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.app.ResultInfo;
|
||||
import android.os.IBinder;
|
||||
@@ -36,7 +37,7 @@ import java.util.Objects;
|
||||
* Activity relaunch callback.
|
||||
* @hide
|
||||
*/
|
||||
public class ActivityRelaunchItem extends ClientTransactionItem {
|
||||
public class ActivityRelaunchItem extends ActivityTransactionItem {
|
||||
|
||||
private static final String TAG = "ActivityRelaunchItem";
|
||||
|
||||
@@ -50,7 +51,7 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
|
||||
* A record that was properly configured for relaunch. Execution will be cancelled if not
|
||||
* initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}.
|
||||
*/
|
||||
private ActivityThread.ActivityClientRecord mActivityClientRecord;
|
||||
private ActivityClientRecord mActivityClientRecord;
|
||||
|
||||
@Override
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
@@ -59,7 +60,7 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
if (mActivityClientRecord == null) {
|
||||
if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
|
||||
@@ -73,7 +74,8 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
|
||||
@Override
|
||||
public void postExecute(ClientTransactionHandler client, IBinder token,
|
||||
PendingTransactionActions pendingActions) {
|
||||
client.reportRelaunch(token, pendingActions);
|
||||
final ActivityClientRecord r = getActivityClientRecord(client, token);
|
||||
client.reportRelaunch(r, pendingActions);
|
||||
}
|
||||
|
||||
// ObjectPoolItem implementation
|
||||
@@ -130,16 +132,16 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
|
||||
mPreserveWindow = in.readBoolean();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<ActivityRelaunchItem> CREATOR =
|
||||
public static final @NonNull Creator<ActivityRelaunchItem> CREATOR =
|
||||
new Creator<ActivityRelaunchItem>() {
|
||||
public ActivityRelaunchItem createFromParcel(Parcel in) {
|
||||
return new ActivityRelaunchItem(in);
|
||||
}
|
||||
public ActivityRelaunchItem createFromParcel(Parcel in) {
|
||||
return new ActivityRelaunchItem(in);
|
||||
}
|
||||
|
||||
public ActivityRelaunchItem[] newArray(int size) {
|
||||
return new ActivityRelaunchItem[size];
|
||||
}
|
||||
};
|
||||
public ActivityRelaunchItem[] newArray(int size) {
|
||||
return new ActivityRelaunchItem[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
@@ -18,10 +18,11 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.app.ResultInfo;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Trace;
|
||||
@@ -33,7 +34,7 @@ import java.util.Objects;
|
||||
* Activity result delivery callback.
|
||||
* @hide
|
||||
*/
|
||||
public class ActivityResultItem extends ClientTransactionItem {
|
||||
public class ActivityResultItem extends ActivityTransactionItem {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private List<ResultInfo> mResultInfoList;
|
||||
@@ -45,10 +46,10 @@ public class ActivityResultItem extends ClientTransactionItem {
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
|
||||
client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT");
|
||||
client.handleSendResult(r, mResultInfoList, "ACTIVITY_RESULT");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ public class ActivityResultItem extends ClientTransactionItem {
|
||||
mResultInfoList = in.createTypedArrayList(ResultInfo.CREATOR);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
|
||||
public static final @NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
|
||||
new Parcelable.Creator<ActivityResultItem>() {
|
||||
public ActivityResultItem createFromParcel(Parcel in) {
|
||||
return new ActivityResultItem(in);
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 android.app.servertransaction;
|
||||
|
||||
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* An activity-targeting callback message to a client that can be scheduled and executed.
|
||||
* It also provides nullity-free version of
|
||||
* {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)} for child class
|
||||
* to inherit.
|
||||
*
|
||||
* @see ClientTransaction
|
||||
* @see ClientTransactionItem
|
||||
* @see com.android.server.wm.ClientLifecycleManager
|
||||
* @hide
|
||||
*/
|
||||
public abstract class ActivityTransactionItem extends ClientTransactionItem {
|
||||
@Override
|
||||
public final void execute(ClientTransactionHandler client, IBinder token,
|
||||
PendingTransactionActions pendingActions) {
|
||||
final ActivityClientRecord r = getActivityClientRecord(client, token);
|
||||
|
||||
execute(client, r, pendingActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)},
|
||||
* but take non-null {@link ActivityClientRecord} as a parameter.
|
||||
*/
|
||||
@VisibleForTesting(visibility = PACKAGE)
|
||||
public abstract void execute(@NonNull ClientTransactionHandler client,
|
||||
@NonNull ActivityClientRecord r, PendingTransactionActions pendingActions);
|
||||
|
||||
@NonNull ActivityClientRecord getActivityClientRecord(
|
||||
@NonNull ClientTransactionHandler client, IBinder token) {
|
||||
final ActivityClientRecord r = client.getActivityClient(token);
|
||||
if (r == null) {
|
||||
throw new IllegalArgumentException("Activity client record must not be null to execute "
|
||||
+ "transaction item");
|
||||
}
|
||||
if (client.getActivity(token) == null) {
|
||||
throw new IllegalArgumentException("Activity must not be null to execute "
|
||||
+ "transaction item");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -38,10 +40,10 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
|
||||
client.handleDestroyActivity(token, mFinished, mConfigChanges,
|
||||
client.handleDestroyActivity(r, mFinished, mConfigChanges,
|
||||
false /* getNonConfigInstance */, "DestroyActivityItem");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
@@ -92,7 +94,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
|
||||
mConfigChanges = in.readInt();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<DestroyActivityItem> CREATOR =
|
||||
public static final @NonNull Creator<DestroyActivityItem> CREATOR =
|
||||
new Creator<DestroyActivityItem>() {
|
||||
public DestroyActivityItem createFromParcel(Parcel in) {
|
||||
return new DestroyActivityItem(in);
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
|
||||
package android.app.servertransaction;
|
||||
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
|
||||
/**
|
||||
* Request an activity to enter picture-in-picture mode.
|
||||
* @hide
|
||||
*/
|
||||
public final class EnterPipRequestedItem extends ClientTransactionItem {
|
||||
public final class EnterPipRequestedItem extends ActivityTransactionItem {
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
client.handlePictureInPictureRequested(token);
|
||||
client.handlePictureInPictureRequested(r);
|
||||
}
|
||||
|
||||
// ObjectPoolItem implementation
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.app.ProfilerInfo;
|
||||
@@ -163,7 +164,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
|
||||
in.readTypedObject(FixedRotationAdjustments.CREATOR));
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<LaunchActivityItem> CREATOR =
|
||||
public static final @NonNull Creator<LaunchActivityItem> CREATOR =
|
||||
new Creator<LaunchActivityItem>() {
|
||||
public LaunchActivityItem createFromParcel(Parcel in) {
|
||||
return new LaunchActivityItem(in);
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.app.servertransaction;
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.IBinder;
|
||||
@@ -31,23 +32,24 @@ import java.util.Objects;
|
||||
* Activity move to a different display message.
|
||||
* @hide
|
||||
*/
|
||||
public class MoveToDisplayItem extends ClientTransactionItem {
|
||||
public class MoveToDisplayItem extends ActivityTransactionItem {
|
||||
|
||||
private int mTargetDisplayId;
|
||||
private Configuration mConfiguration;
|
||||
|
||||
@Override
|
||||
public void preExecute(ClientTransactionHandler client, IBinder token) {
|
||||
final ActivityClientRecord r = getActivityClientRecord(client, token);
|
||||
// Notify the client of an upcoming change in the token configuration. This ensures that
|
||||
// batches of config change items only process the newest configuration.
|
||||
client.updatePendingActivityConfiguration(token, mConfiguration);
|
||||
client.updatePendingActivityConfiguration(r, mConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
|
||||
client.handleActivityConfigurationChanged(token, mConfiguration, mTargetDisplayId);
|
||||
client.handleActivityConfigurationChanged(r, mConfiguration, mTargetDisplayId);
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -96,7 +98,8 @@ public class MoveToDisplayItem extends ClientTransactionItem {
|
||||
mConfiguration = in.readTypedObject(Configuration.CREATOR);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<MoveToDisplayItem> CREATOR = new Creator<MoveToDisplayItem>() {
|
||||
public static final @NonNull Creator<MoveToDisplayItem> CREATOR =
|
||||
new Creator<MoveToDisplayItem>() {
|
||||
public MoveToDisplayItem createFromParcel(Parcel in) {
|
||||
return new MoveToDisplayItem(in);
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ package android.app.servertransaction;
|
||||
import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
|
||||
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Trace;
|
||||
@@ -35,7 +36,7 @@ import java.util.Objects;
|
||||
* New intent message.
|
||||
* @hide
|
||||
*/
|
||||
public class NewIntentItem extends ClientTransactionItem {
|
||||
public class NewIntentItem extends ActivityTransactionItem {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private List<ReferrerIntent> mIntents;
|
||||
@@ -47,10 +48,10 @@ public class NewIntentItem extends ClientTransactionItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
|
||||
client.handleNewIntent(token, mIntents);
|
||||
client.handleNewIntent(r, mIntents);
|
||||
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -94,7 +95,7 @@ public class NewIntentItem extends ClientTransactionItem {
|
||||
mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<NewIntentItem> CREATOR =
|
||||
public static final @NonNull Parcelable.Creator<NewIntentItem> CREATOR =
|
||||
new Parcelable.Creator<NewIntentItem>() {
|
||||
public NewIntentItem createFromParcel(Parcel in) {
|
||||
return new NewIntentItem(in);
|
||||
|
||||
@@ -18,8 +18,9 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -40,10 +41,10 @@ public class PauseActivityItem extends ActivityLifecycleItem {
|
||||
private boolean mDontReport;
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
|
||||
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
|
||||
client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
|
||||
"PAUSE_ACTIVITY_ITEM");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
@@ -130,7 +131,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
|
||||
mDontReport = in.readBoolean();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<PauseActivityItem> CREATOR =
|
||||
public static final @NonNull Creator<PauseActivityItem> CREATOR =
|
||||
new Creator<PauseActivityItem>() {
|
||||
public PauseActivityItem createFromParcel(Parcel in) {
|
||||
return new PauseActivityItem(in);
|
||||
|
||||
@@ -18,8 +18,10 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -46,10 +48,10 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
|
||||
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
|
||||
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
|
||||
"RESUME_ACTIVITY");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
@@ -128,7 +130,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
|
||||
mIsForward = in.readBoolean();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<ResumeActivityItem> CREATOR =
|
||||
public static final @NonNull Creator<ResumeActivityItem> CREATOR =
|
||||
new Creator<ResumeActivityItem>() {
|
||||
public ResumeActivityItem createFromParcel(Parcel in) {
|
||||
return new ResumeActivityItem(in);
|
||||
|
||||
@@ -18,8 +18,9 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Trace;
|
||||
|
||||
@@ -32,10 +33,10 @@ public class StartActivityItem extends ActivityLifecycleItem {
|
||||
private static final String TAG = "StartActivityItem";
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "startActivityItem");
|
||||
client.handleStartActivity(token, pendingActions);
|
||||
client.handleStartActivity(r, pendingActions);
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ public class StartActivityItem extends ActivityLifecycleItem {
|
||||
// Empty
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<StartActivityItem> CREATOR =
|
||||
public static final @NonNull Creator<StartActivityItem> CREATOR =
|
||||
new Creator<StartActivityItem>() {
|
||||
public StartActivityItem createFromParcel(Parcel in) {
|
||||
return new StartActivityItem(in);
|
||||
|
||||
@@ -18,6 +18,8 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -34,10 +36,10 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
||||
private int mConfigChanges;
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
|
||||
client.handleStopActivity(token, mConfigChanges, pendingActions,
|
||||
client.handleStopActivity(r, mConfigChanges, pendingActions,
|
||||
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
@@ -93,7 +95,7 @@ public class StopActivityItem extends ActivityLifecycleItem {
|
||||
mConfigChanges = in.readInt();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<StopActivityItem> CREATOR =
|
||||
public static final @NonNull Creator<StopActivityItem> CREATOR =
|
||||
new Creator<StopActivityItem>() {
|
||||
public StopActivityItem createFromParcel(Parcel in) {
|
||||
return new StopActivityItem(in);
|
||||
|
||||
@@ -17,7 +17,9 @@ package android.app.servertransaction;
|
||||
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
@@ -28,15 +30,15 @@ import android.os.Trace;
|
||||
* Top resumed activity changed callback.
|
||||
* @hide
|
||||
*/
|
||||
public class TopResumedActivityChangeItem extends ClientTransactionItem {
|
||||
public class TopResumedActivityChangeItem extends ActivityTransactionItem {
|
||||
|
||||
private boolean mOnTop;
|
||||
|
||||
@Override
|
||||
public void execute(ClientTransactionHandler client, IBinder token,
|
||||
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
|
||||
PendingTransactionActions pendingActions) {
|
||||
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
|
||||
client.handleTopResumedActivityChanged(token, mOnTop, "topResumedActivityChangeItem");
|
||||
client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
}
|
||||
|
||||
@@ -97,16 +99,16 @@ public class TopResumedActivityChangeItem extends ClientTransactionItem {
|
||||
mOnTop = in.readBoolean();
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<TopResumedActivityChangeItem> CREATOR =
|
||||
public static final @NonNull Creator<TopResumedActivityChangeItem> CREATOR =
|
||||
new Creator<TopResumedActivityChangeItem>() {
|
||||
public TopResumedActivityChangeItem createFromParcel(Parcel in) {
|
||||
return new TopResumedActivityChangeItem(in);
|
||||
}
|
||||
public TopResumedActivityChangeItem createFromParcel(Parcel in) {
|
||||
return new TopResumedActivityChangeItem(in);
|
||||
}
|
||||
|
||||
public TopResumedActivityChangeItem[] newArray(int size) {
|
||||
return new TopResumedActivityChangeItem[size];
|
||||
}
|
||||
};
|
||||
public TopResumedActivityChangeItem[] newArray(int size) {
|
||||
return new TopResumedActivityChangeItem[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
@@ -218,29 +218,29 @@ public class TransactionExecutor {
|
||||
null /* customIntent */);
|
||||
break;
|
||||
case ON_START:
|
||||
mTransactionHandler.handleStartActivity(r.token, mPendingActions);
|
||||
mTransactionHandler.handleStartActivity(r, mPendingActions);
|
||||
break;
|
||||
case ON_RESUME:
|
||||
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
|
||||
mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
|
||||
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
|
||||
break;
|
||||
case ON_PAUSE:
|
||||
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
|
||||
mTransactionHandler.handlePauseActivity(r, false /* finished */,
|
||||
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
|
||||
"LIFECYCLER_PAUSE_ACTIVITY");
|
||||
break;
|
||||
case ON_STOP:
|
||||
mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
|
||||
mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
|
||||
mPendingActions, false /* finalStateRequest */,
|
||||
"LIFECYCLER_STOP_ACTIVITY");
|
||||
break;
|
||||
case ON_DESTROY:
|
||||
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
|
||||
mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
|
||||
0 /* configChanges */, false /* getNonConfigInstance */,
|
||||
"performLifecycleSequence. cycling to:" + path.get(size - 1));
|
||||
break;
|
||||
case ON_RESTART:
|
||||
mTransactionHandler.performRestartActivity(r.token, false /* start */);
|
||||
mTransactionHandler.performRestartActivity(r, false /* start */);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
|
||||
|
||||
@@ -25,14 +25,14 @@ import static android.view.Display.INVALID_DISPLAY;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityThread;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.IApplicationThread;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.app.ResourcesManager;
|
||||
@@ -114,11 +114,12 @@ public class ActivityThreadTest {
|
||||
final ActivityThread activityThread = activity.getActivityThread();
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||
activityThread.executeTransaction(newResumeTransaction(activity));
|
||||
assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
|
||||
true /* finalStateRequest */, "test"));
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
assertFalse(activityThread.performResumeActivity(r, true /* finalStateRequest */,
|
||||
"test"));
|
||||
|
||||
assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
|
||||
false /* finalStateRequest */, "test"));
|
||||
assertFalse(activityThread.performResumeActivity(r, false /* finalStateRequest */,
|
||||
"test"));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -244,20 +245,18 @@ public class ActivityThreadTest {
|
||||
newerConfig.orientation = orientation == ORIENTATION_LANDSCAPE
|
||||
? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
|
||||
newerConfig.seq = seq + 2;
|
||||
activityThread.updatePendingActivityConfiguration(activity.getActivityToken(),
|
||||
newerConfig);
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
activityThread.updatePendingActivityConfiguration(r, newerConfig);
|
||||
|
||||
final Configuration olderConfig = new Configuration();
|
||||
olderConfig.orientation = orientation;
|
||||
olderConfig.seq = seq + 1;
|
||||
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
|
||||
olderConfig, INVALID_DISPLAY);
|
||||
activityThread.handleActivityConfigurationChanged(r, olderConfig, INVALID_DISPLAY);
|
||||
assertEquals(numOfConfig, activity.mNumOfConfigChanges);
|
||||
assertEquals(olderConfig.orientation, activity.mConfig.orientation);
|
||||
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
|
||||
newerConfig, INVALID_DISPLAY);
|
||||
activityThread.handleActivityConfigurationChanged(r, newerConfig, INVALID_DISPLAY);
|
||||
assertEquals(numOfConfig + 1, activity.mNumOfConfigChanges);
|
||||
assertEquals(newerConfig.orientation, activity.mConfig.orientation);
|
||||
});
|
||||
@@ -274,7 +273,7 @@ public class ActivityThreadTest {
|
||||
config.seq = BASE_SEQ;
|
||||
config.orientation = ORIENTATION_PORTRAIT;
|
||||
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
|
||||
activityThread.handleActivityConfigurationChanged(getActivityClientRecord(activity),
|
||||
config, INVALID_DISPLAY);
|
||||
});
|
||||
|
||||
@@ -335,7 +334,7 @@ public class ActivityThreadTest {
|
||||
config.seq = BASE_SEQ;
|
||||
config.orientation = ORIENTATION_PORTRAIT;
|
||||
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
|
||||
activityThread.handleActivityConfigurationChanged(getActivityClientRecord(activity),
|
||||
config, INVALID_DISPLAY);
|
||||
});
|
||||
|
||||
@@ -472,10 +471,10 @@ public class ActivityThreadTest {
|
||||
newActivityConfig.orientation = newActivityConfig.orientation == ORIENTATION_PORTRAIT
|
||||
? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
|
||||
|
||||
activityThread.updatePendingActivityConfiguration(activity.getActivityToken(),
|
||||
newActivityConfig);
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
|
||||
newActivityConfig, INVALID_DISPLAY);
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
activityThread.updatePendingActivityConfiguration(r, newActivityConfig);
|
||||
activityThread.handleActivityConfigurationChanged(r, newActivityConfig,
|
||||
INVALID_DISPLAY);
|
||||
|
||||
assertEquals("Virtual display orientation must not change when activity"
|
||||
+ " configuration orientation changes.",
|
||||
@@ -560,9 +559,10 @@ public class ActivityThreadTest {
|
||||
startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_ENTER, true);
|
||||
final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
|
||||
final ActivityThread activityThread = activity.getActivityThread();
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||
activityThread.handlePictureInPictureRequested(activity.getActivityToken());
|
||||
activityThread.handlePictureInPictureRequested(r);
|
||||
});
|
||||
|
||||
assertTrue(activity.pipRequested());
|
||||
@@ -575,9 +575,10 @@ public class ActivityThreadTest {
|
||||
startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_SKIP, true);
|
||||
final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
|
||||
final ActivityThread activityThread = activity.getActivityThread();
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||
activityThread.handlePictureInPictureRequested(activity.getActivityToken());
|
||||
activityThread.handlePictureInPictureRequested(r);
|
||||
});
|
||||
|
||||
assertTrue(activity.pipRequested());
|
||||
@@ -588,9 +589,10 @@ public class ActivityThreadTest {
|
||||
public void testHandlePictureInPictureRequested_notOverridden() {
|
||||
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
|
||||
final ActivityThread activityThread = activity.getActivityThread();
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||
activityThread.handlePictureInPictureRequested(activity.getActivityToken());
|
||||
activityThread.handlePictureInPictureRequested(r);
|
||||
});
|
||||
|
||||
assertTrue(activity.pipRequested());
|
||||
@@ -599,8 +601,9 @@ public class ActivityThreadTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link ActivityThread#handleActivityConfigurationChanged(IBinder, Configuration, int)}
|
||||
* to try to push activity configuration to the activity for the given sequence number.
|
||||
* Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
|
||||
* Configuration, int)} to try to push activity configuration to the activity for the given
|
||||
* sequence number.
|
||||
* <p>
|
||||
* It uses orientation to push the configuration and it tries a different orientation if the
|
||||
* first attempt doesn't make through, to rule out the possibility that the previous
|
||||
@@ -613,13 +616,13 @@ public class ActivityThreadTest {
|
||||
*/
|
||||
private int applyConfigurationChange(TestActivity activity, int seq) {
|
||||
final ActivityThread activityThread = activity.getActivityThread();
|
||||
final ActivityClientRecord r = getActivityClientRecord(activity);
|
||||
|
||||
final int numOfConfig = activity.mNumOfConfigChanges;
|
||||
Configuration config = new Configuration();
|
||||
config.orientation = ORIENTATION_PORTRAIT;
|
||||
config.seq = seq;
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
|
||||
INVALID_DISPLAY);
|
||||
activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
|
||||
|
||||
if (activity.mNumOfConfigChanges > numOfConfig) {
|
||||
return config.seq;
|
||||
@@ -628,12 +631,17 @@ public class ActivityThreadTest {
|
||||
config = new Configuration();
|
||||
config.orientation = ORIENTATION_LANDSCAPE;
|
||||
config.seq = seq + 1;
|
||||
activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
|
||||
INVALID_DISPLAY);
|
||||
activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
|
||||
|
||||
return config.seq;
|
||||
}
|
||||
|
||||
private static ActivityClientRecord getActivityClientRecord(Activity activity) {
|
||||
final ActivityThread thread = activity.getActivityThread();
|
||||
final IBinder token = activity.getActivityToken();
|
||||
return thread.getActivityClient(token);
|
||||
}
|
||||
|
||||
private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
|
||||
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
|
||||
null, 0, new MergedConfiguration(), false /* preserveWindow */);
|
||||
|
||||
@@ -32,11 +32,12 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityThread.ActivityClientRecord;
|
||||
import android.app.ClientTransactionHandler;
|
||||
import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
|
||||
@@ -225,6 +226,7 @@ public class TransactionExecutorTests {
|
||||
when(callback2.getPostExecutionState()).thenReturn(UNDEFINED);
|
||||
ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
|
||||
IBinder token = mock(IBinder.class);
|
||||
when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
|
||||
|
||||
ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
|
||||
token /* activityToken */);
|
||||
@@ -236,9 +238,9 @@ public class TransactionExecutorTests {
|
||||
mExecutor.execute(transaction);
|
||||
|
||||
InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest);
|
||||
inOrder.verify(callback1, times(1)).execute(eq(mTransactionHandler), eq(token), any());
|
||||
inOrder.verify(callback2, times(1)).execute(eq(mTransactionHandler), eq(token), any());
|
||||
inOrder.verify(stateRequest, times(1)).execute(eq(mTransactionHandler), eq(token), any());
|
||||
inOrder.verify(callback1).execute(eq(mTransactionHandler), eq(token), any());
|
||||
inOrder.verify(callback2).execute(eq(mTransactionHandler), eq(token), any());
|
||||
inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -273,7 +275,7 @@ public class TransactionExecutorTests {
|
||||
|
||||
// The launch transaction should not be executed because its token is in the
|
||||
// to-be-destroyed container.
|
||||
verify(launchItem, times(0)).execute(any(), any(), any());
|
||||
verify(launchItem, never()).execute(any(), any(), any());
|
||||
|
||||
// After the destroy transaction has been executed, the token should be removed.
|
||||
mExecutor.execute(destroyTransaction);
|
||||
@@ -282,6 +284,8 @@ public class TransactionExecutorTests {
|
||||
|
||||
@Test
|
||||
public void testActivityResultRequiredStateResolution() {
|
||||
when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
|
||||
|
||||
PostExecItem postExecItem = new PostExecItem(ON_RESUME);
|
||||
|
||||
IBinder token = mock(IBinder.class);
|
||||
@@ -292,12 +296,12 @@ public class TransactionExecutorTests {
|
||||
// Verify resolution that should get to onPause
|
||||
mClientRecord.setState(ON_RESUME);
|
||||
mExecutor.executeCallbacks(transaction);
|
||||
verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
|
||||
verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
|
||||
|
||||
// Verify resolution that should get to onStart
|
||||
mClientRecord.setState(ON_STOP);
|
||||
mExecutor.executeCallbacks(transaction);
|
||||
verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
|
||||
verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -433,6 +437,36 @@ public class TransactionExecutorTests {
|
||||
mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testActivityItemNullRecordThrowsException() {
|
||||
final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
|
||||
when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
|
||||
final IBinder token = mock(IBinder.class);
|
||||
final ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token);
|
||||
transaction.addCallback(activityItem);
|
||||
when(mTransactionHandler.getActivityClient(token)).thenReturn(null);
|
||||
|
||||
mExecutor.executeCallbacks(transaction);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActivityItemExecute() {
|
||||
final IBinder token = mock(IBinder.class);
|
||||
final ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token);
|
||||
final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
|
||||
when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
|
||||
transaction.addCallback(activityItem);
|
||||
final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
|
||||
transaction.setLifecycleStateRequest(stateRequest);
|
||||
when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
|
||||
|
||||
mExecutor.execute(transaction);
|
||||
|
||||
final InOrder inOrder = inOrder(activityItem, stateRequest);
|
||||
inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any());
|
||||
inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
|
||||
}
|
||||
|
||||
private static int[] shuffledArray(int[] inputArray) {
|
||||
final List<Integer> list = Arrays.stream(inputArray).boxed().collect(Collectors.toList());
|
||||
Collections.shuffle(list);
|
||||
@@ -489,13 +523,13 @@ public class TransactionExecutorTests {
|
||||
|
||||
public static final Parcelable.Creator<StubItem> CREATOR =
|
||||
new Parcelable.Creator<StubItem>() {
|
||||
public StubItem createFromParcel(Parcel in) {
|
||||
return new StubItem(in);
|
||||
}
|
||||
public StubItem createFromParcel(Parcel in) {
|
||||
return new StubItem(in);
|
||||
}
|
||||
|
||||
public StubItem[] newArray(int size) {
|
||||
return new StubItem[size];
|
||||
}
|
||||
};
|
||||
public StubItem[] newArray(int size) {
|
||||
return new StubItem[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,27 +243,27 @@ public class ActivityThreadClientTest {
|
||||
}
|
||||
|
||||
private void startActivity(ActivityClientRecord r) {
|
||||
mThread.handleStartActivity(r.token, null /* pendingActions */);
|
||||
mThread.handleStartActivity(r, null /* pendingActions */);
|
||||
}
|
||||
|
||||
private void resumeActivity(ActivityClientRecord r) {
|
||||
mThread.handleResumeActivity(r.token, true /* finalStateRequest */,
|
||||
mThread.handleResumeActivity(r, true /* finalStateRequest */,
|
||||
true /* isForward */, "test");
|
||||
}
|
||||
|
||||
private void pauseActivity(ActivityClientRecord r) {
|
||||
mThread.handlePauseActivity(r.token, false /* finished */,
|
||||
mThread.handlePauseActivity(r, false /* finished */,
|
||||
false /* userLeaving */, 0 /* configChanges */, null /* pendingActions */,
|
||||
"test");
|
||||
}
|
||||
|
||||
private void stopActivity(ActivityClientRecord r) {
|
||||
mThread.handleStopActivity(r.token, 0 /* configChanges */,
|
||||
mThread.handleStopActivity(r, 0 /* configChanges */,
|
||||
new PendingTransactionActions(), false /* finalStateRequest */, "test");
|
||||
}
|
||||
|
||||
private void destroyActivity(ActivityClientRecord r) {
|
||||
mThread.handleDestroyActivity(r.token, true /* finishing */, 0 /* configChanges */,
|
||||
mThread.handleDestroyActivity(r, true /* finishing */, 0 /* configChanges */,
|
||||
false /* getNonConfigInstance */, "test");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user