summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Matt Casey <mrcasey@google.com> 2023-08-22 19:58:56 +0000
committer Matt Casey <mrcasey@google.com> 2023-08-25 20:52:21 +0000
commit2408b1e62c0facac74545ad97705ca4386323956 (patch)
tree02341196e24939c71042ec3549cdbc525ebdf2fd /java/src
parentea59592a728c2fb00070f15873e85939b806a3d9 (diff)
Defer finish() to onStop() when doing shared transition
We used to immediately finish() after starting the shared element transition. In high-latency situations, this transition took a while to start and resulted in some broken UI in window manager. Instead of finishing immediately, we finish onStop() such that we can wait for the transition to actually begin. Bug: 292158050 Test: Share an image that has high latency to load. Validate that the UI looks normal (albeit slow) when the edit transition happens (see bug). Change-Id: I66686398781aeea630c500c48198c5febc1e8fc2
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/ChooserActivity.java106
1 files changed, 14 insertions, 92 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java
index 8edbba08..b5899e5c 100644
--- a/java/src/com/android/intentresolver/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/ChooserActivity.java
@@ -27,7 +27,6 @@ import static android.stats.devicepolicy.nano.DevicePolicyEnums.RESOLVER_EMPTY_S
import static com.android.internal.util.LatencyTracker.ACTION_LOAD_SHARE_SHEET;
import android.annotation.IntDef;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
@@ -66,9 +65,6 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.LinearInterpolator;
import android.widget.TextView;
import androidx.annotation.MainThread;
@@ -238,6 +234,13 @@ public class ChooserActivity extends ResolverActivity implements
private final SparseArray<ProfileRecord> mProfileRecords = new SparseArray<>();
private boolean mExcludeSharedText = false;
+ /**
+ * When we intend to finish the activity with a shared element transition, we can't immediately
+ * finish() when the transition is invoked, as the receiving end may not be able to start the
+ * animation and the UI breaks if this takes too long. Instead we defer finishing until onStop
+ * in order to wait for the transition to begin.
+ */
+ private boolean mFinishWhenStopped = false;
@Inject
public ChooserActivity(ViewModelComponent.Builder builder) {
@@ -645,8 +648,7 @@ public class ChooserActivity extends ResolverActivity implements
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: " + getComponentName().flattenToShortString());
- maybeCancelFinishAnimation();
-
+ mFinishWhenStopped = false;
mRefinementManager.onActivityResume();
}
@@ -747,7 +749,8 @@ public class ChooserActivity extends ResolverActivity implements
super.onStop();
mRefinementManager.onActivityStop(isChangingConfigurations());
- if (maybeCancelFinishAnimation()) {
+ if (mFinishWhenStopped) {
+ mFinishWhenStopped = false;
finish();
}
}
@@ -1363,7 +1366,10 @@ public class ChooserActivity extends ResolverActivity implements
ChooserActivity.this, sharedElement, sharedElementName);
safelyStartActivityAsUser(
targetInfo, getPersonalProfileUserHandle(), options.toBundle());
- startFinishAnimation();
+ // Can't finish right away because the shared element transition may not
+ // be ready to start.
+ mFinishWhenStopped = true;
+
}
},
(status) -> {
@@ -1748,25 +1754,6 @@ public class ChooserActivity extends ResolverActivity implements
contentPreviewContainer.setVisibility(View.GONE);
}
- private void startFinishAnimation() {
- View rootView = findRootView();
- if (rootView != null) {
- rootView.startAnimation(new FinishAnimation(this, rootView));
- }
- }
-
- private boolean maybeCancelFinishAnimation() {
- View rootView = findRootView();
- Animation animation = (rootView == null) ? null : rootView.getAnimation();
- if (animation instanceof FinishAnimation) {
- boolean hasEnded = animation.hasEnded();
- animation.cancel();
- rootView.clearAnimation();
- return !hasEnded;
- }
- return false;
- }
-
private View findRootView() {
if (mContentView == null) {
mContentView = findViewById(android.R.id.content);
@@ -1847,71 +1834,6 @@ public class ChooserActivity extends ResolverActivity implements
}
}
- /**
- * Used in combination with the scene transition when launching the image editor
- */
- private static class FinishAnimation extends AlphaAnimation implements
- Animation.AnimationListener {
- @Nullable
- private Activity mActivity;
- @Nullable
- private View mRootView;
- private final float mFromAlpha;
-
- FinishAnimation(@NonNull Activity activity, @NonNull View rootView) {
- super(rootView.getAlpha(), 0.0f);
- mActivity = activity;
- mRootView = rootView;
- mFromAlpha = rootView.getAlpha();
- setInterpolator(new LinearInterpolator());
- long duration = activity.getWindow().getTransitionBackgroundFadeDuration();
- setDuration(duration);
- // The scene transition animation looks better when it's not overlapped with this
- // fade-out animation thus the delay.
- // It is most likely that the image editor will cause this activity to stop and this
- // animation will be cancelled in the background without running (i.e. we'll animate
- // only when this activity remains partially visible after the image editor launch).
- setStartOffset(duration);
- super.setAnimationListener(this);
- }
-
- @Override
- public void setAnimationListener(AnimationListener listener) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void cancel() {
- if (mRootView != null) {
- mRootView.setAlpha(mFromAlpha);
- }
- cleanup();
- super.cancel();
- }
-
- @Override
- public void onAnimationStart(Animation animation) {
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- Activity activity = mActivity;
- cleanup();
- if (activity != null) {
- activity.finish();
- }
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
-
- private void cleanup() {
- mActivity = null;
- mRootView = null;
- }
- }
-
@Override
protected void maybeLogProfileChange() {
getEventLog().logSharesheetProfileChanged();