summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
authorGeorge Mount <mount@google.com>2015-04-09 08:23:05 -0700
committerGeorge Mount <mount@google.com>2015-05-07 08:36:28 -0700
commit41725dedc33906aaafee36b2d6523596e2a8a52e (patch)
tree6ee37b110a44efee78e5822ace351cdccdb0e0df /core/java/android
parent9260cb7ffe0845d229a8cfe948b4ba30fe32127b (diff)
downloadframeworks_base-41725dedc33906aaafee36b2d6523596e2a8a52e.zip
frameworks_base-41725dedc33906aaafee36b2d6523596e2a8a52e.tar.gz
frameworks_base-41725dedc33906aaafee36b2d6523596e2a8a52e.tar.bz2
Disable input during Activity Transition.
Bug 19437530 While the actual Activity Transitions are running, input is stopped, except for the "back" button. Change-Id: I112e6252b9de05ece10a6267681fee5487e5ef6b
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java32
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java39
-rw-r--r--core/java/android/app/EnterTransitionCoordinator.java21
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java25
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java7
-rw-r--r--core/java/android/view/ViewRootImpl.java32
-rw-r--r--core/java/android/view/WindowManagerGlobal.java3
7 files changed, 101 insertions, 58 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7260d10..c1d0e9b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3841,10 +3841,7 @@ public class Activity extends ContextThemeWrapper
mStartedActivity = true;
}
- final View decor = mWindow != null ? mWindow.peekDecorView() : null;
- if (decor != null) {
- decor.cancelPendingInputEvents();
- }
+ cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
@@ -3855,6 +3852,18 @@ public class Activity extends ContextThemeWrapper
mParent.startActivityFromChild(this, intent, requestCode);
}
}
+ }
+
+ /**
+ * Cancels pending inputs and if an Activity Transition is to be run, starts the transition.
+ *
+ * @param options The ActivityOptions bundle used to start an Activity.
+ */
+ private void cancelInputsAndStartExitTransition(Bundle options) {
+ final View decor = mWindow != null ? mWindow.peekDecorView() : null;
+ if (decor != null) {
+ decor.cancelPendingInputEvents();
+ }
if (options != null && !isTopOfTask()) {
mActivityTransitionState.startExitOutTransition(this, options);
}
@@ -3872,9 +3881,6 @@ public class Activity extends ContextThemeWrapper
*/
public void startActivityForResultAsUser(Intent intent, int requestCode,
@Nullable Bundle options, UserHandle user) {
- if (options != null) {
- mActivityTransitionState.startExitOutTransition(this, options);
- }
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
@@ -3896,10 +3902,7 @@ public class Activity extends ContextThemeWrapper
mStartedActivity = true;
}
- final View decor = mWindow != null ? mWindow.peekDecorView() : null;
- if (decor != null) {
- decor.cancelPendingInputEvents();
- }
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -3925,6 +3928,7 @@ public class Activity extends ContextThemeWrapper
mToken, mEmbeddedID, -1, ar.getResultCode(),
ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -3948,6 +3952,7 @@ public class Activity extends ContextThemeWrapper
mToken, mEmbeddedID, -1, ar.getResultCode(),
ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -4380,6 +4385,7 @@ public class Activity extends ContextThemeWrapper
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -4431,9 +4437,6 @@ public class Activity extends ContextThemeWrapper
@Override
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
- if (options != null) {
- mActivityTransitionState.startExitOutTransition(this, options);
- }
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
@@ -4443,6 +4446,7 @@ public class Activity extends ContextThemeWrapper
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 2939322..2965827 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -31,6 +31,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroupOverlay;
import android.view.ViewParent;
+import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.ImageView;
@@ -187,11 +188,6 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
*/
public static final int MSG_SHARED_ELEMENT_DESTINATION = 107;
- /**
- * Send the shared element positions.
- */
- public static final int MSG_SEND_SHARED_ELEMENT_DESTINATION = 108;
-
private Window mWindow;
final protected ArrayList<String> mAllSharedElementNames;
final protected ArrayList<View> mSharedElements = new ArrayList<View>();
@@ -207,6 +203,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
new ArrayList<GhostViewListeners>();
private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>();
private ArrayList<Matrix> mSharedElementParentMatrices;
+ private boolean mSharedElementTransitionComplete;
+ private boolean mViewsTransitionComplete;
public ActivityTransitionCoordinator(Window window,
ArrayList<String> allSharedElementNames,
@@ -219,6 +217,11 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
}
protected void viewsReady(ArrayMap<String, View> sharedElements) {
+ final View decor = getDecor();
+ final ViewRootImpl viewRoot = decor == null ? null : decor.getViewRootImpl();
+ if (viewRoot != null) {
+ viewRoot.setPausedForTransition(true);
+ }
sharedElements.retainAll(mAllSharedElementNames);
if (mListener != null) {
mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
@@ -878,6 +881,32 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
}
}
+ protected boolean isViewsTransitionComplete() {
+ return mViewsTransitionComplete;
+ }
+
+ protected void viewsTransitionComplete() {
+ mViewsTransitionComplete = true;
+ startInputWhenTransitionsComplete();
+ }
+
+ protected void sharedElementTransitionComplete() {
+ mSharedElementTransitionComplete = true;
+ startInputWhenTransitionsComplete();
+ }
+ private void startInputWhenTransitionsComplete() {
+ if (mViewsTransitionComplete && mSharedElementTransitionComplete) {
+ final View decor = getDecor();
+ if (decor != null) {
+ final ViewRootImpl viewRoot = decor.getViewRootImpl();
+ viewRoot.setPausedForTransition(false);
+ }
+ onTransitionsComplete();
+ }
+ }
+
+ protected void onTransitionsComplete() {}
+
protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
@Override
public void onTransitionStart(Transition transition) {
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index e84a8da..4db4be0 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -55,8 +55,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
private boolean mWasOpaque;
private boolean mAreViewsReady;
private boolean mIsViewsTransitionStarted;
- private boolean mIsViewsTransitionComplete;
- private boolean mIsSharedElementTransitionComplete;
private Transition mEnterViewsTransition;
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
@@ -456,7 +454,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
}
}
if (viewsTransition == null) {
- viewTransitionComplete();
+ viewsTransitionComplete();
} else {
viewsTransition.forceVisibility(View.INVISIBLE, true);
final ArrayList<View> transitioningViews = mTransitioningViews;
@@ -474,7 +472,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
public void onTransitionEnd(Transition transition) {
mEnterViewsTransition = null;
transition.removeListener(this);
- viewTransitionComplete();
+ viewsTransitionComplete();
super.onTransitionEnd(transition);
}
});
@@ -497,18 +495,9 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
return transition;
}
- private void viewTransitionComplete() {
- mIsViewsTransitionComplete = true;
- if (mIsSharedElementTransitionComplete) {
- moveSharedElementsFromOverlay();
- }
- }
-
- private void sharedElementTransitionComplete() {
- mIsSharedElementTransitionComplete = true;
- if (mIsViewsTransitionComplete) {
- moveSharedElementsFromOverlay();
- }
+ @Override
+ protected void onTransitionsComplete() {
+ moveSharedElementsFromOverlay();
}
private void sharedElementTransitionStarted() {
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 0f286fb..9ddebb0 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -46,8 +46,6 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
private static final String TAG = "ExitTransitionCoordinator";
private static final long MAX_WAIT_MS = 1000;
- private boolean mExitComplete;
-
private Bundle mSharedElementBundle;
private boolean mExitNotified;
@@ -165,7 +163,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
- if (mExitComplete) {
+ if (isViewsTransitionComplete()) {
delayCancel();
}
}
@@ -310,14 +308,14 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
viewsTransition = configureTransition(getViewsTransition(), true);
}
if (viewsTransition == null) {
- exitTransitionComplete();
+ viewsTransitionComplete();
} else {
final ArrayList<View> transitioningViews = mTransitioningViews;
viewsTransition.addListener(new ContinueTransitionListener() {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
- exitTransitionComplete();
+ viewsTransitionComplete();
if (mIsHidden && transitioningViews != null) {
showViews(transitioningViews, true);
}
@@ -373,19 +371,15 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
}
}
- private void exitTransitionComplete() {
- mExitComplete = true;
- notifyComplete();
- }
-
protected boolean isReadyToNotify() {
return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady;
}
- private void sharedElementTransitionComplete() {
+ @Override
+ protected void sharedElementTransitionComplete() {
mSharedElementBundle = mExitSharedElementBundle == null
? captureSharedElementState() : captureExitSharedElementsState();
- notifyComplete();
+ super.sharedElementTransitionComplete();
}
private Bundle captureExitSharedElementsState() {
@@ -405,6 +399,11 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
return bundle;
}
+ @Override
+ protected void onTransitionsComplete() {
+ notifyComplete();
+ }
+
protected void notifyComplete() {
if (isReadyToNotify()) {
if (!mSharedElementNotified) {
@@ -433,7 +432,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
}
private void notifyExitComplete() {
- if (!mExitNotified && mExitComplete) {
+ if (!mExitNotified && isViewsTransitionComplete()) {
mExitNotified = true;
mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
mResultReceiver = null; // done talking
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 68ad782..3781d40 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -586,7 +586,7 @@ final class AccessibilityInteractionController {
}
}
- private void perfromAccessibilityActionUiThread(Message message) {
+ private void performAccessibilityActionUiThread(Message message) {
final int flags = message.arg1;
final int accessibilityViewId = message.arg2;
@@ -602,7 +602,8 @@ final class AccessibilityInteractionController {
boolean succeeded = false;
try {
- if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
+ if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null ||
+ mViewRootImpl.mStopped || mViewRootImpl.mPausedForTransition) {
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
@@ -1146,7 +1147,7 @@ final class AccessibilityInteractionController {
findAccessibilityNodeInfoByAccessibilityIdUiThread(message);
} break;
case MSG_PERFORM_ACCESSIBILITY_ACTION: {
- perfromAccessibilityActionUiThread(message);
+ performAccessibilityActionUiThread(message);
} break;
case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: {
findAccessibilityNodeInfosByViewIdUiThread(message);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fda6e63..8421e6962 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -173,6 +173,9 @@ public final class ViewRootImpl implements ViewParent,
// so the window should no longer be active.
boolean mStopped = false;
+ // Set to true to stop input during an Activity Transition.
+ boolean mPausedForTransition = false;
+
boolean mLastInCompatMode = false;
SurfaceHolder.Callback2 mSurfaceHolderCallback;
@@ -977,15 +980,25 @@ public final class ViewRootImpl implements ViewParent,
return null;
}
- void setStopped(boolean stopped) {
+ void setWindowStopped(boolean stopped) {
if (mStopped != stopped) {
mStopped = stopped;
- if (!stopped) {
+ if (!mStopped) {
scheduleTraversals();
}
}
}
+ /**
+ * Block the input events during an Activity Transition. The KEYCODE_BACK event is allowed
+ * through to allow quick reversal of the Activity Transition.
+ *
+ * @param paused true to pause, false to resume.
+ */
+ public void setPausedForTransition(boolean paused) {
+ mPausedForTransition = paused;
+ }
+
@Override
public ViewParent getParent() {
return null;
@@ -3632,8 +3645,9 @@ public final class ViewRootImpl implements ViewParent,
if (mView == null || !mAdded) {
Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
return true;
- } else if ((!mAttachInfo.mHasWindowFocus || mStopped)
- && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+ } else if ((!mAttachInfo.mHasWindowFocus
+ && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) || mStopped
+ || (mPausedForTransition && !isBack(q.mEvent))) {
// This is a focus event and the window doesn't currently have input focus or
// has stopped. This could be an event that came back from the previous stage
// but the window has lost focus or stopped in the meantime.
@@ -3656,6 +3670,14 @@ public final class ViewRootImpl implements ViewParent,
mNext.dump(prefix, writer);
}
}
+
+ private boolean isBack(InputEvent event) {
+ if (event instanceof KeyEvent) {
+ return ((KeyEvent) event).getKeyCode() == KeyEvent.KEYCODE_BACK;
+ } else {
+ return false;
+ }
+ }
}
/**
@@ -6223,7 +6245,7 @@ public final class ViewRootImpl implements ViewParent,
@Override
public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
- if (mView == null) {
+ if (mView == null || mStopped || mPausedForTransition) {
return false;
}
// Intercept accessibility focus events fired by virtual nodes to keep
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 57558ff..e7a7ba8 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -21,7 +21,6 @@ import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.res.Configuration;
-import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -552,7 +551,7 @@ public final class WindowManagerGlobal {
for (int i = 0; i < count; i++) {
if (token == null || mParams.get(i).token == token) {
ViewRootImpl root = mRoots.get(i);
- root.setStopped(stopped);
+ root.setWindowStopped(stopped);
}
}
}